| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdarg.h> | 5 #include <stdarg.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
| 10 | 10 |
| (...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 DCHECK((qreg >= 0) && (qreg < num_q_registers)); | 900 DCHECK((qreg >= 0) && (qreg < num_q_registers)); |
| 901 memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 2); | 901 memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 2); |
| 902 } | 902 } |
| 903 | 903 |
| 904 | 904 |
| 905 void Simulator::set_q_register(int qreg, const uint64_t* value) { | 905 void Simulator::set_q_register(int qreg, const uint64_t* value) { |
| 906 DCHECK((qreg >= 0) && (qreg < num_q_registers)); | 906 DCHECK((qreg >= 0) && (qreg < num_q_registers)); |
| 907 memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 2); | 907 memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 2); |
| 908 } | 908 } |
| 909 | 909 |
| 910 template <typename T> |
| 911 void Simulator::get_q_register(int qreg, T* value) { |
| 912 DCHECK((qreg >= 0) && (qreg < num_q_registers)); |
| 913 memcpy(value, vfp_registers_ + qreg * 4, kSimd128Size); |
| 914 } |
| 910 | 915 |
| 911 void Simulator::get_q_register(int qreg, uint32_t* value) { | 916 template <typename T> |
| 917 void Simulator::set_q_register(int qreg, const T* value) { |
| 912 DCHECK((qreg >= 0) && (qreg < num_q_registers)); | 918 DCHECK((qreg >= 0) && (qreg < num_q_registers)); |
| 913 memcpy(value, vfp_registers_ + qreg * 4, sizeof(*value) * 4); | 919 memcpy(vfp_registers_ + qreg * 4, value, kSimd128Size); |
| 914 } | 920 } |
| 915 | 921 |
| 916 | 922 |
| 917 void Simulator::set_q_register(int qreg, const uint32_t* value) { | |
| 918 DCHECK((qreg >= 0) && (qreg < num_q_registers)); | |
| 919 memcpy(vfp_registers_ + qreg * 4, value, sizeof(*value) * 4); | |
| 920 } | |
| 921 | |
| 922 | |
| 923 // Raw access to the PC register. | 923 // Raw access to the PC register. |
| 924 void Simulator::set_pc(int32_t value) { | 924 void Simulator::set_pc(int32_t value) { |
| 925 pc_modified_ = true; | 925 pc_modified_ = true; |
| 926 registers_[pc] = value; | 926 registers_[pc] = value; |
| 927 } | 927 } |
| 928 | 928 |
| 929 | 929 |
| 930 bool Simulator::has_bad_pc() const { | 930 bool Simulator::has_bad_pc() const { |
| 931 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc)); | 931 return ((registers_[pc] == bad_lr) || (registers_[pc] == end_sim_pc)); |
| 932 } | 932 } |
| (...skipping 2916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3849 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3849 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 3850 uint32_t data[4]; | 3850 uint32_t data[4]; |
| 3851 get_q_register(Vm, data); | 3851 get_q_register(Vm, data); |
| 3852 set_q_register(Vd, data); | 3852 set_q_register(Vd, data); |
| 3853 } else if (instr->Bits(11, 8) == 8) { | 3853 } else if (instr->Bits(11, 8) == 8) { |
| 3854 // vadd/vtst | 3854 // vadd/vtst |
| 3855 int size = static_cast<NeonSize>(instr->Bits(21, 20)); | 3855 int size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| 3856 int Vd = instr->VFPDRegValue(kSimd128Precision); | 3856 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 3857 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3857 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 3858 int Vn = instr->VFPNRegValue(kSimd128Precision); | 3858 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 3859 uint32_t src1[4], src2[4]; | |
| 3860 get_q_register(Vn, src1); | |
| 3861 get_q_register(Vm, src2); | |
| 3862 if (instr->Bit(4) == 0) { | 3859 if (instr->Bit(4) == 0) { |
| 3863 // vadd.i<size> Qd, Qm, Qn. | 3860 // vadd.i<size> Qd, Qm, Qn. |
| 3864 switch (size) { | 3861 switch (size) { |
| 3865 case Neon8: { | 3862 case Neon8: { |
| 3866 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); | 3863 uint8_t src1[16], src2[16]; |
| 3867 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); | 3864 get_q_register(Vn, src1); |
| 3865 get_q_register(Vm, src2); |
| 3868 for (int i = 0; i < 16; i++) { | 3866 for (int i = 0; i < 16; i++) { |
| 3869 s1[i] += s2[i]; | 3867 src1[i] += src2[i]; |
| 3870 } | 3868 } |
| 3869 set_q_register(Vd, src1); |
| 3871 break; | 3870 break; |
| 3872 } | 3871 } |
| 3873 case Neon16: { | 3872 case Neon16: { |
| 3874 uint16_t s1[8], s2[8]; | 3873 uint16_t src1[8], src2[8]; |
| 3875 memcpy(s1, src1, sizeof(s1)); | 3874 get_q_register(Vn, src1); |
| 3876 memcpy(s2, src2, sizeof(s2)); | 3875 get_q_register(Vm, src2); |
| 3877 for (int i = 0; i < 8; i++) { | 3876 for (int i = 0; i < 8; i++) { |
| 3878 s1[i] += s2[i]; | 3877 src1[i] += src2[i]; |
| 3879 } | 3878 } |
| 3880 memcpy(src1, s1, sizeof(src1)); | 3879 set_q_register(Vd, src1); |
| 3881 break; | 3880 break; |
| 3882 } | 3881 } |
| 3883 case Neon32: { | 3882 case Neon32: { |
| 3883 uint32_t src1[4], src2[4]; |
| 3884 get_q_register(Vn, src1); |
| 3885 get_q_register(Vm, src2); |
| 3884 for (int i = 0; i < 4; i++) { | 3886 for (int i = 0; i < 4; i++) { |
| 3885 src1[i] += src2[i]; | 3887 src1[i] += src2[i]; |
| 3886 } | 3888 } |
| 3889 set_q_register(Vd, src1); |
| 3887 break; | 3890 break; |
| 3888 } | 3891 } |
| 3889 default: | 3892 default: |
| 3890 UNREACHABLE(); | 3893 UNREACHABLE(); |
| 3891 break; | 3894 break; |
| 3892 } | 3895 } |
| 3893 } else { | 3896 } else { |
| 3894 // vtst.i<size> Qd, Qm, Qn. | 3897 // vtst.i<size> Qd, Qm, Qn. |
| 3895 switch (size) { | 3898 switch (size) { |
| 3896 case Neon8: { | 3899 case Neon8: { |
| 3897 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); | 3900 uint8_t src1[16], src2[16]; |
| 3898 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); | 3901 get_q_register(Vn, src1); |
| 3902 get_q_register(Vm, src2); |
| 3899 for (int i = 0; i < 16; i++) { | 3903 for (int i = 0; i < 16; i++) { |
| 3900 s1[i] = (s1[i] & s2[i]) != 0 ? 0xFFu : 0; | 3904 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFu : 0; |
| 3901 } | 3905 } |
| 3906 set_q_register(Vd, src1); |
| 3902 break; | 3907 break; |
| 3903 } | 3908 } |
| 3904 case Neon16: { | 3909 case Neon16: { |
| 3905 uint16_t s1[8], s2[8]; | 3910 uint16_t src1[8], src2[8]; |
| 3906 memcpy(s1, src1, sizeof(s1)); | 3911 get_q_register(Vn, src1); |
| 3907 memcpy(s2, src2, sizeof(s2)); | 3912 get_q_register(Vm, src2); |
| 3908 for (int i = 0; i < 8; i++) { | 3913 for (int i = 0; i < 8; i++) { |
| 3909 s1[i] = (s1[i] & s2[i]) != 0 ? 0xFFFFu : 0; | 3914 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFu : 0; |
| 3910 } | 3915 } |
| 3911 memcpy(src1, s1, sizeof(src1)); | 3916 set_q_register(Vd, src1); |
| 3912 break; | 3917 break; |
| 3913 } | 3918 } |
| 3914 case Neon32: { | 3919 case Neon32: { |
| 3920 uint32_t src1[4], src2[4]; |
| 3921 get_q_register(Vn, src1); |
| 3922 get_q_register(Vm, src2); |
| 3915 for (int i = 0; i < 4; i++) { | 3923 for (int i = 0; i < 4; i++) { |
| 3916 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFFFFFu : 0; | 3924 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFFFFFu : 0; |
| 3917 } | 3925 } |
| 3926 set_q_register(Vd, src1); |
| 3918 break; | 3927 break; |
| 3919 } | 3928 } |
| 3920 default: | 3929 default: |
| 3921 UNREACHABLE(); | 3930 UNREACHABLE(); |
| 3922 break; | 3931 break; |
| 3923 } | 3932 } |
| 3924 } | 3933 } |
| 3925 set_q_register(Vd, src1); | |
| 3926 } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xd && | 3934 } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xd && |
| 3927 instr->Bit(4) == 0) { | 3935 instr->Bit(4) == 0) { |
| 3928 int Vd = instr->VFPDRegValue(kSimd128Precision); | 3936 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 3929 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3937 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 3930 int Vn = instr->VFPNRegValue(kSimd128Precision); | 3938 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 3931 uint32_t src1[4], src2[4]; | 3939 float src1[4], src2[4]; |
| 3932 get_q_register(Vn, src1); | 3940 get_q_register(Vn, src1); |
| 3933 get_q_register(Vm, src2); | 3941 get_q_register(Vm, src2); |
| 3934 for (int i = 0; i < 4; i++) { | 3942 for (int i = 0; i < 4; i++) { |
| 3935 if (instr->Bit(21) == 0) { | 3943 if (instr->Bit(21) == 0) { |
| 3936 // vadd.f32 Qd, Qm, Qn. | 3944 // vadd.f32 Qd, Qm, Qn. |
| 3937 src1[i] = bit_cast<uint32_t>(bit_cast<float>(src1[i]) + | 3945 src1[i] = src1[i] + src2[i]; |
| 3938 bit_cast<float>(src2[i])); | |
| 3939 } else { | 3946 } else { |
| 3940 // vsub.f32 Qd, Qm, Qn. | 3947 // vsub.f32 Qd, Qm, Qn. |
| 3941 src1[i] = bit_cast<uint32_t>(bit_cast<float>(src1[i]) - | 3948 src1[i] = src1[i] - src2[i]; |
| 3942 bit_cast<float>(src2[i])); | |
| 3943 } | 3949 } |
| 3944 } | 3950 } |
| 3945 set_q_register(Vd, src1); | 3951 set_q_register(Vd, src1); |
| 3946 } else if (instr->Bits(11, 8) == 0x9 && instr->Bit(6) == 1 && | 3952 } else if (instr->Bits(11, 8) == 0x9 && instr->Bit(6) == 1 && |
| 3947 instr->Bit(4) == 1) { | 3953 instr->Bit(4) == 1) { |
| 3948 // vmul.i<size> Qd, Qm, Qn. | 3954 // vmul.i<size> Qd, Qm, Qn. |
| 3949 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); | 3955 NeonSize size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| 3950 int Vd = instr->VFPDRegValue(kSimd128Precision); | 3956 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 3951 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3957 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 3952 int Vn = instr->VFPNRegValue(kSimd128Precision); | 3958 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 3953 uint32_t src1[4], src2[4]; | |
| 3954 get_q_register(Vn, src1); | |
| 3955 get_q_register(Vm, src2); | |
| 3956 switch (size) { | 3959 switch (size) { |
| 3957 case Neon8: { | 3960 case Neon8: { |
| 3958 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); | 3961 uint8_t src1[16], src2[16]; |
| 3959 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); | 3962 get_q_register(Vn, src1); |
| 3963 get_q_register(Vm, src2); |
| 3960 for (int i = 0; i < 16; i++) { | 3964 for (int i = 0; i < 16; i++) { |
| 3961 s1[i] *= s2[i]; | 3965 src1[i] *= src2[i]; |
| 3962 } | 3966 } |
| 3967 set_q_register(Vd, src1); |
| 3963 break; | 3968 break; |
| 3964 } | 3969 } |
| 3965 case Neon16: { | 3970 case Neon16: { |
| 3966 uint16_t s1[8], s2[8]; | 3971 uint16_t src1[8], src2[8]; |
| 3967 memcpy(s1, src1, sizeof(s1)); | 3972 get_q_register(Vn, src1); |
| 3968 memcpy(s2, src2, sizeof(s2)); | 3973 get_q_register(Vm, src2); |
| 3969 for (int i = 0; i < 8; i++) { | 3974 for (int i = 0; i < 8; i++) { |
| 3970 s1[i] *= s2[i]; | 3975 src1[i] *= src2[i]; |
| 3971 } | 3976 } |
| 3972 memcpy(src1, s1, sizeof(src1)); | 3977 set_q_register(Vd, src1); |
| 3973 break; | 3978 break; |
| 3974 } | 3979 } |
| 3975 case Neon32: { | 3980 case Neon32: { |
| 3981 uint32_t src1[4], src2[4]; |
| 3982 get_q_register(Vn, src1); |
| 3983 get_q_register(Vm, src2); |
| 3976 for (int i = 0; i < 4; i++) { | 3984 for (int i = 0; i < 4; i++) { |
| 3977 src1[i] *= src2[i]; | 3985 src1[i] *= src2[i]; |
| 3978 } | 3986 } |
| 3987 set_q_register(Vd, src1); |
| 3979 break; | 3988 break; |
| 3980 } | 3989 } |
| 3981 default: | 3990 default: |
| 3982 UNIMPLEMENTED(); | 3991 UNIMPLEMENTED(); |
| 3983 break; | 3992 break; |
| 3984 } | 3993 } |
| 3985 set_q_register(Vd, src1); | |
| 3986 } else if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 0xe && | 3994 } else if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 0xe && |
| 3987 instr->Bit(4) == 0) { | 3995 instr->Bit(4) == 0) { |
| 3996 // vceq.f32. |
| 3988 int Vd = instr->VFPDRegValue(kSimd128Precision); | 3997 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 3989 int Vm = instr->VFPMRegValue(kSimd128Precision); | 3998 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 3990 int Vn = instr->VFPNRegValue(kSimd128Precision); | 3999 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 3991 uint32_t src1[4], src2[4]; | 4000 float src1[4], src2[4]; |
| 3992 get_q_register(Vn, src1); | 4001 get_q_register(Vn, src1); |
| 3993 get_q_register(Vm, src2); | 4002 get_q_register(Vm, src2); |
| 4003 uint32_t dst[4]; |
| 3994 for (int i = 0; i < 4; i++) { | 4004 for (int i = 0; i < 4; i++) { |
| 3995 src1[i] = bit_cast<float>(src1[i]) == bit_cast<float>(src2[i]) | 4005 dst[i] = (src1[i] == src2[i]) ? 0xFFFFFFFF : 0; |
| 3996 ? 0xFFFFFFFF | |
| 3997 : 0; | |
| 3998 } | 4006 } |
| 3999 set_q_register(Vd, src1); | 4007 set_q_register(Vd, dst); |
| 4000 | 4008 |
| 4001 } else { | 4009 } else { |
| 4002 UNIMPLEMENTED(); | 4010 UNIMPLEMENTED(); |
| 4003 } | 4011 } |
| 4004 break; | 4012 break; |
| 4005 case 5: | 4013 case 5: |
| 4006 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && | 4014 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && |
| 4007 (instr->Bit(4) == 1)) { | 4015 (instr->Bit(4) == 1)) { |
| 4008 // vmovl signed | 4016 // vmovl signed |
| 4009 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); | 4017 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4021 to[e] = from[e]; | 4029 to[e] = from[e]; |
| 4022 e++; | 4030 e++; |
| 4023 } | 4031 } |
| 4024 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); | 4032 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); |
| 4025 } else if (instr->Bits(21, 20) == 3 && instr->Bit(4) == 0) { | 4033 } else if (instr->Bits(21, 20) == 3 && instr->Bit(4) == 0) { |
| 4026 // vext. | 4034 // vext. |
| 4027 int imm4 = instr->Bits(11, 8); | 4035 int imm4 = instr->Bits(11, 8); |
| 4028 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4036 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4029 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4037 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4030 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4038 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4031 uint32_t src1[4], src2[4], dst[4]; | 4039 uint8_t src1[16], src2[16], dst[16]; |
| 4032 get_q_register(Vn, src1); | 4040 get_q_register(Vn, src1); |
| 4033 get_q_register(Vm, src2); | 4041 get_q_register(Vm, src2); |
| 4034 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); | 4042 int boundary = kSimd128Size - imm4; |
| 4035 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); | |
| 4036 uint8_t* d = reinterpret_cast<uint8_t*>(dst); | |
| 4037 int boundary = 16 - imm4; | |
| 4038 int i = 0; | 4043 int i = 0; |
| 4039 for (; i < boundary; i++) { | 4044 for (; i < boundary; i++) { |
| 4040 d[i] = s1[i + imm4]; | 4045 dst[i] = src1[i + imm4]; |
| 4041 } | 4046 } |
| 4042 for (; i < 16; i++) { | 4047 for (; i < 16; i++) { |
| 4043 d[i] = s2[i - boundary]; | 4048 dst[i] = src2[i - boundary]; |
| 4044 } | 4049 } |
| 4045 set_q_register(Vd, dst); | 4050 set_q_register(Vd, dst); |
| 4046 } else { | 4051 } else { |
| 4047 UNIMPLEMENTED(); | 4052 UNIMPLEMENTED(); |
| 4048 } | 4053 } |
| 4049 break; | 4054 break; |
| 4050 case 6: | 4055 case 6: |
| 4051 if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) { | 4056 if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) { |
| 4052 // vsub.size Qd, Qm, Qn. | 4057 // vsub.size Qd, Qm, Qn. |
| 4053 int size = static_cast<NeonSize>(instr->Bits(21, 20)); | 4058 int size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| 4054 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4059 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4055 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4060 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4056 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4061 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4057 uint32_t src1[4], src2[4]; | |
| 4058 get_q_register(Vn, src1); | |
| 4059 get_q_register(Vm, src2); | |
| 4060 switch (size) { | 4062 switch (size) { |
| 4061 case Neon8: { | 4063 case Neon8: { |
| 4062 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); | 4064 uint8_t src1[16], src2[16]; |
| 4063 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); | 4065 get_q_register(Vn, src1); |
| 4066 get_q_register(Vm, src2); |
| 4064 for (int i = 0; i < 16; i++) { | 4067 for (int i = 0; i < 16; i++) { |
| 4065 s1[i] -= s2[i]; | 4068 src1[i] -= src2[i]; |
| 4066 } | 4069 } |
| 4070 set_q_register(Vd, src1); |
| 4067 break; | 4071 break; |
| 4068 } | 4072 } |
| 4069 case Neon16: { | 4073 case Neon16: { |
| 4070 uint16_t s1[8], s2[8]; | 4074 uint16_t src1[8], src2[8]; |
| 4071 memcpy(s1, src1, sizeof(s1)); | 4075 get_q_register(Vn, src1); |
| 4072 memcpy(s2, src2, sizeof(s2)); | 4076 get_q_register(Vm, src2); |
| 4073 for (int i = 0; i < 8; i++) { | 4077 for (int i = 0; i < 8; i++) { |
| 4074 s1[i] -= s2[i]; | 4078 src1[i] -= src2[i]; |
| 4075 } | 4079 } |
| 4076 memcpy(src1, s1, sizeof(src1)); | 4080 set_q_register(Vd, src1); |
| 4077 break; | 4081 break; |
| 4078 } | 4082 } |
| 4079 case Neon32: { | 4083 case Neon32: { |
| 4084 uint32_t src1[4], src2[4]; |
| 4085 get_q_register(Vn, src1); |
| 4086 get_q_register(Vm, src2); |
| 4080 for (int i = 0; i < 4; i++) { | 4087 for (int i = 0; i < 4; i++) { |
| 4081 src1[i] -= src2[i]; | 4088 src1[i] -= src2[i]; |
| 4082 } | 4089 } |
| 4090 set_q_register(Vd, src1); |
| 4083 break; | 4091 break; |
| 4084 } | 4092 } |
| 4085 default: | 4093 default: |
| 4086 UNREACHABLE(); | 4094 UNREACHABLE(); |
| 4087 break; | 4095 break; |
| 4088 } | 4096 } |
| 4089 set_q_register(Vd, src1); | |
| 4090 } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) { | 4097 } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) { |
| 4091 // vceq.size Qd, Qm, Qn. | 4098 // vceq.size Qd, Qm, Qn. |
| 4092 int size = static_cast<NeonSize>(instr->Bits(21, 20)); | 4099 int size = static_cast<NeonSize>(instr->Bits(21, 20)); |
| 4093 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4100 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4094 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4101 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4095 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4102 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4096 uint32_t src1[4], src2[4]; | |
| 4097 get_q_register(Vn, src1); | |
| 4098 get_q_register(Vm, src2); | |
| 4099 switch (size) { | 4103 switch (size) { |
| 4100 case Neon8: { | 4104 case Neon8: { |
| 4101 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); | 4105 uint8_t src1[16], src2[16]; |
| 4102 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); | 4106 get_q_register(Vn, src1); |
| 4107 get_q_register(Vm, src2); |
| 4103 for (int i = 0; i < 16; i++) { | 4108 for (int i = 0; i < 16; i++) { |
| 4104 s1[i] = s1[i] == s2[i] ? 0xFF : 0; | 4109 src1[i] = (src1[i] == src2[i]) ? 0xFFu : 0; |
| 4105 } | 4110 } |
| 4111 set_q_register(Vd, src1); |
| 4106 break; | 4112 break; |
| 4107 } | 4113 } |
| 4108 case Neon16: { | 4114 case Neon16: { |
| 4109 uint16_t s1[8], s2[8]; | 4115 uint16_t src1[8], src2[8]; |
| 4110 memcpy(s1, src1, sizeof(s1)); | 4116 get_q_register(Vn, src1); |
| 4111 memcpy(s2, src2, sizeof(s2)); | 4117 get_q_register(Vm, src2); |
| 4112 for (int i = 0; i < 8; i++) { | 4118 for (int i = 0; i < 8; i++) { |
| 4113 s1[i] = s1[i] == s2[i] ? 0xffffu : 0; | 4119 src1[i] = (src1[i] == src2[i]) ? 0xFFFFu : 0; |
| 4114 } | 4120 } |
| 4115 memcpy(src1, s1, sizeof(src1)); | 4121 set_q_register(Vd, src1); |
| 4116 break; | 4122 break; |
| 4117 } | 4123 } |
| 4118 case Neon32: { | 4124 case Neon32: { |
| 4125 uint32_t src1[4], src2[4]; |
| 4126 get_q_register(Vn, src1); |
| 4127 get_q_register(Vm, src2); |
| 4119 for (int i = 0; i < 4; i++) { | 4128 for (int i = 0; i < 4; i++) { |
| 4120 src1[i] = src1[i] == src2[i] ? 0xFFFFFFFF : 0; | 4129 src1[i] = (src1[i] == src2[i]) ? 0xFFFFFFFFu : 0; |
| 4121 } | 4130 } |
| 4131 set_q_register(Vd, src1); |
| 4122 break; | 4132 break; |
| 4123 } | 4133 } |
| 4124 default: | 4134 default: |
| 4125 UNREACHABLE(); | 4135 UNREACHABLE(); |
| 4126 break; | 4136 break; |
| 4127 } | 4137 } |
| 4128 set_q_register(Vd, src1); | |
| 4129 } else if (instr->Bits(21, 20) == 1 && instr->Bits(11, 8) == 1 && | 4138 } else if (instr->Bits(21, 20) == 1 && instr->Bits(11, 8) == 1 && |
| 4130 instr->Bit(4) == 1) { | 4139 instr->Bit(4) == 1) { |
| 4131 // vbsl.size Qd, Qm, Qn. | 4140 // vbsl.size Qd, Qm, Qn. |
| 4132 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4141 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4133 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4142 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4134 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4143 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4135 uint32_t dst[4], src1[4], src2[4]; | 4144 uint32_t dst[4], src1[4], src2[4]; |
| 4136 get_q_register(Vd, dst); | 4145 get_q_register(Vd, dst); |
| 4137 get_q_register(Vn, src1); | 4146 get_q_register(Vn, src1); |
| 4138 get_q_register(Vm, src2); | 4147 get_q_register(Vm, src2); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4163 get_q_register(Vm, src2); | 4172 get_q_register(Vm, src2); |
| 4164 for (int i = 0; i < 4; i++) src1[i] ^= src2[i]; | 4173 for (int i = 0; i < 4; i++) src1[i] ^= src2[i]; |
| 4165 set_q_register(Vd, src1); | 4174 set_q_register(Vd, src1); |
| 4166 } | 4175 } |
| 4167 } else if (instr->Bit(21) == 0 && instr->Bits(11, 8) == 0xd && | 4176 } else if (instr->Bit(21) == 0 && instr->Bits(11, 8) == 0xd && |
| 4168 instr->Bit(6) == 1 && instr->Bit(4) == 1) { | 4177 instr->Bit(6) == 1 && instr->Bit(4) == 1) { |
| 4169 // vmul.f32 Qd, Qn, Qm | 4178 // vmul.f32 Qd, Qn, Qm |
| 4170 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4179 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4171 int Vn = instr->VFPNRegValue(kSimd128Precision); | 4180 int Vn = instr->VFPNRegValue(kSimd128Precision); |
| 4172 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4181 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4173 uint32_t src1[4], src2[4]; | 4182 float src1[4], src2[4]; |
| 4174 get_q_register(Vn, src1); | 4183 get_q_register(Vn, src1); |
| 4175 get_q_register(Vm, src2); | 4184 get_q_register(Vm, src2); |
| 4176 for (int i = 0; i < 4; i++) { | 4185 for (int i = 0; i < 4; i++) { |
| 4177 src1[i] = bit_cast<uint32_t>(bit_cast<float>(src1[i]) * | 4186 src1[i] = src1[i] * src2[i]; |
| 4178 bit_cast<float>(src2[i])); | |
| 4179 } | 4187 } |
| 4180 set_q_register(Vd, src1); | 4188 set_q_register(Vd, src1); |
| 4181 } else { | 4189 } else { |
| 4182 UNIMPLEMENTED(); | 4190 UNIMPLEMENTED(); |
| 4183 } | 4191 } |
| 4184 break; | 4192 break; |
| 4185 case 7: | 4193 case 7: |
| 4186 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && | 4194 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && |
| 4187 (instr->Bit(4) == 1)) { | 4195 (instr->Bit(4) == 1)) { |
| 4188 // vmovl unsigned | 4196 // vmovl unsigned |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4295 } else if (vtbx) { | 4303 } else if (vtbx) { |
| 4296 result |= destination & (0xFFull << shift); | 4304 result |= destination & (0xFFull << shift); |
| 4297 } | 4305 } |
| 4298 } | 4306 } |
| 4299 set_d_register(vd, &result); | 4307 set_d_register(vd, &result); |
| 4300 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 6) == 0x7) { | 4308 } else if (instr->Bits(17, 16) == 0x2 && instr->Bits(11, 6) == 0x7) { |
| 4301 // vzip.<size> Qd, Qm. | 4309 // vzip.<size> Qd, Qm. |
| 4302 int size = static_cast<NeonSize>(instr->Bits(19, 18)); | 4310 int size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| 4303 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4311 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4304 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4312 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4305 uint32_t src1[4], src2[4], dst1[4], dst2[4]; | |
| 4306 get_q_register(Vd, src1); | |
| 4307 get_q_register(Vm, src2); | |
| 4308 switch (size) { | 4313 switch (size) { |
| 4309 case Neon8: { | 4314 case Neon8: { |
| 4310 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1); | 4315 uint8_t src1[16], src2[16], dst1[16], dst2[16]; |
| 4311 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2); | 4316 get_q_register(Vd, src1); |
| 4312 uint8_t* d1 = reinterpret_cast<uint8_t*>(dst1); | 4317 get_q_register(Vm, src2); |
| 4313 uint8_t* d2 = reinterpret_cast<uint8_t*>(dst2); | |
| 4314 for (int i = 0; i < 8; i++) { | 4318 for (int i = 0; i < 8; i++) { |
| 4315 d1[i * 2] = s1[i]; | 4319 dst1[i * 2] = src1[i]; |
| 4316 d1[i * 2 + 1] = s2[i]; | 4320 dst1[i * 2 + 1] = src2[i]; |
| 4317 d2[i * 2] = s1[i + 8]; | 4321 dst2[i * 2] = src1[i + 8]; |
| 4318 d2[i * 2 + 1] = s2[i + 8]; | 4322 dst2[i * 2 + 1] = src2[i + 8]; |
| 4319 } | 4323 } |
| 4324 set_q_register(Vd, dst1); |
| 4325 set_q_register(Vm, dst2); |
| 4320 break; | 4326 break; |
| 4321 } | 4327 } |
| 4322 case Neon16: { | 4328 case Neon16: { |
| 4323 uint16_t s1[8], s2[8], d1[8], d2[8]; | 4329 uint16_t src1[8], src2[8], dst1[8], dst2[8]; |
| 4324 memcpy(s1, src1, sizeof(s1)); | 4330 get_q_register(Vd, src1); |
| 4325 memcpy(s2, src2, sizeof(s2)); | 4331 get_q_register(Vm, src2); |
| 4326 for (int i = 0; i < 8; i += 2) { | 4332 for (int i = 0; i < 8; i += 2) { |
| 4327 d1[i] = s1[i / 2]; | 4333 dst1[i] = src1[i / 2]; |
| 4328 d1[i + 1] = s2[i / 2]; | 4334 dst1[i + 1] = src2[i / 2]; |
| 4329 d2[i] = s1[i / 2 + 4]; | 4335 dst2[i] = src1[i / 2 + 4]; |
| 4330 d2[i + 1] = s2[i / 2 + 4]; | 4336 dst2[i + 1] = src2[i / 2 + 4]; |
| 4331 } | 4337 } |
| 4332 memcpy(dst1, d1, sizeof(dst1)); | 4338 set_q_register(Vd, dst1); |
| 4333 memcpy(dst2, d2, sizeof(dst2)); | 4339 set_q_register(Vm, dst2); |
| 4334 break; | 4340 break; |
| 4335 } | 4341 } |
| 4336 case Neon32: { | 4342 case Neon32: { |
| 4343 uint32_t src1[4], src2[4], dst1[4], dst2[4]; |
| 4344 get_q_register(Vd, src1); |
| 4345 get_q_register(Vm, src2); |
| 4337 for (int i = 0; i < 2; i++) { | 4346 for (int i = 0; i < 2; i++) { |
| 4338 dst1[i * 2] = src1[i]; | 4347 dst1[i * 2] = src1[i]; |
| 4339 dst1[i * 2 + 1] = src2[i]; | 4348 dst1[i * 2 + 1] = src2[i]; |
| 4340 dst2[i * 2] = src1[i + 2]; | 4349 dst2[i * 2] = src1[i + 2]; |
| 4341 dst2[i * 2 + 1] = src2[i + 2]; | 4350 dst2[i * 2 + 1] = src2[i + 2]; |
| 4342 } | 4351 } |
| 4352 set_q_register(Vd, dst1); |
| 4353 set_q_register(Vm, dst2); |
| 4343 break; | 4354 break; |
| 4344 } | 4355 } |
| 4345 default: | 4356 default: |
| 4346 UNREACHABLE(); | 4357 UNREACHABLE(); |
| 4347 break; | 4358 break; |
| 4348 } | 4359 } |
| 4349 set_q_register(Vd, dst1); | |
| 4350 set_q_register(Vm, dst2); | |
| 4351 } else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0) { | 4360 } else if (instr->Bits(17, 16) == 0 && instr->Bits(11, 9) == 0) { |
| 4352 // vrev<op>.size Qd, Qm | 4361 // vrev<op>.size Qd, Qm |
| 4353 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4362 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4354 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4363 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4355 int size = static_cast<NeonSize>(instr->Bits(19, 18)); | 4364 int size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| 4356 NeonSize op = static_cast<NeonSize>(static_cast<int>(Neon64) - | 4365 NeonSize op = static_cast<NeonSize>(static_cast<int>(Neon64) - |
| 4357 instr->Bits(8, 7)); | 4366 instr->Bits(8, 7)); |
| 4358 uint32_t src[4]; | |
| 4359 get_q_register(Vm, src); | |
| 4360 switch (op) { | 4367 switch (op) { |
| 4361 case Neon16: { | 4368 case Neon16: { |
| 4362 DCHECK_EQ(Neon8, size); | 4369 DCHECK_EQ(Neon8, size); |
| 4363 uint8_t* s = reinterpret_cast<uint8_t*>(src); | 4370 uint8_t src[16]; |
| 4371 get_q_register(Vm, src); |
| 4364 for (int i = 0; i < 16; i += 2) { | 4372 for (int i = 0; i < 16; i += 2) { |
| 4365 std::swap(s[i], s[i + 1]); | 4373 std::swap(src[i], src[i + 1]); |
| 4366 } | 4374 } |
| 4375 set_q_register(Vd, src); |
| 4367 break; | 4376 break; |
| 4368 } | 4377 } |
| 4369 case Neon32: { | 4378 case Neon32: { |
| 4370 switch (size) { | 4379 switch (size) { |
| 4371 case Neon16: | 4380 case Neon16: { |
| 4381 uint16_t src[8]; |
| 4382 get_q_register(Vm, src); |
| 4383 for (int i = 0; i < 8; i += 2) { |
| 4384 std::swap(src[i], src[i + 1]); |
| 4385 } |
| 4386 set_q_register(Vd, src); |
| 4387 break; |
| 4388 } |
| 4389 case Neon8: { |
| 4390 uint8_t src[16]; |
| 4391 get_q_register(Vm, src); |
| 4372 for (int i = 0; i < 4; i++) { | 4392 for (int i = 0; i < 4; i++) { |
| 4373 src[i] = (src[i] >> 16) | (src[i] << 16); | 4393 std::swap(src[i * 4], src[i * 4 + 3]); |
| 4394 std::swap(src[i * 4 + 1], src[i * 4 + 2]); |
| 4374 } | 4395 } |
| 4375 break; | 4396 set_q_register(Vd, src); |
| 4376 case Neon8: { | |
| 4377 uint8_t* s = reinterpret_cast<uint8_t*>(src); | |
| 4378 for (int i = 0; i < 4; i++) { | |
| 4379 std::swap(s[i * 4], s[i * 4 + 3]); | |
| 4380 std::swap(s[i * 4 + 1], s[i * 4 + 2]); | |
| 4381 } | |
| 4382 break; | 4397 break; |
| 4383 } | 4398 } |
| 4384 default: | 4399 default: |
| 4385 UNREACHABLE(); | 4400 UNREACHABLE(); |
| 4386 break; | 4401 break; |
| 4387 } | 4402 } |
| 4388 break; | 4403 break; |
| 4389 } | 4404 } |
| 4390 case Neon64: { | 4405 case Neon64: { |
| 4391 switch (size) { | 4406 switch (size) { |
| 4392 case Neon32: { | 4407 case Neon32: { |
| 4408 uint32_t src[4]; |
| 4409 get_q_register(Vm, src); |
| 4393 std::swap(src[0], src[1]); | 4410 std::swap(src[0], src[1]); |
| 4394 std::swap(src[2], src[3]); | 4411 std::swap(src[2], src[3]); |
| 4412 set_q_register(Vd, src); |
| 4395 break; | 4413 break; |
| 4396 } | 4414 } |
| 4397 case Neon16: { | 4415 case Neon16: { |
| 4398 for (int i = 0; i <= 2; i += 2) { | 4416 uint16_t src[8]; |
| 4399 uint32_t w1 = src[i]; | 4417 get_q_register(Vm, src); |
| 4400 uint32_t w2 = src[i + 1]; | 4418 for (int i = 0; i < 4; i++) { |
| 4401 src[i] = (w2 >> 16) | (w2 << 16); | 4419 std::swap(src[i * 4], src[i * 4 + 3]); |
| 4402 src[i + 1] = (w1 >> 16) | (w1 << 16); | 4420 std::swap(src[i * 4 + 1], src[i * 4 + 2]); |
| 4403 } | 4421 } |
| 4422 set_q_register(Vd, src); |
| 4404 break; | 4423 break; |
| 4405 } | 4424 } |
| 4406 case Neon8: { | 4425 case Neon8: { |
| 4407 uint8_t* s = reinterpret_cast<uint8_t*>(src); | 4426 uint8_t src[16]; |
| 4427 get_q_register(Vm, src); |
| 4408 for (int i = 0; i < 4; i++) { | 4428 for (int i = 0; i < 4; i++) { |
| 4409 std::swap(s[i], s[7 - i]); | 4429 std::swap(src[i], src[7 - i]); |
| 4410 std::swap(s[i + 8], s[15 - i]); | 4430 std::swap(src[i + 8], src[15 - i]); |
| 4411 } | 4431 } |
| 4432 set_q_register(Vd, src); |
| 4412 break; | 4433 break; |
| 4413 } | 4434 } |
| 4414 default: | 4435 default: |
| 4415 UNREACHABLE(); | 4436 UNREACHABLE(); |
| 4416 break; | 4437 break; |
| 4417 } | 4438 } |
| 4418 break; | 4439 break; |
| 4419 } | 4440 } |
| 4420 default: | 4441 default: |
| 4421 UNREACHABLE(); | 4442 UNREACHABLE(); |
| 4422 break; | 4443 break; |
| 4423 } | 4444 } |
| 4424 set_q_register(Vd, src); | |
| 4425 } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0) { | 4445 } else if (instr->Bits(17, 16) == 0x1 && instr->Bit(11) == 0) { |
| 4426 int Vd = instr->VFPDRegValue(kSimd128Precision); | 4446 int Vd = instr->VFPDRegValue(kSimd128Precision); |
| 4427 int Vm = instr->VFPMRegValue(kSimd128Precision); | 4447 int Vm = instr->VFPMRegValue(kSimd128Precision); |
| 4428 int size = static_cast<NeonSize>(instr->Bits(19, 18)); | 4448 int size = static_cast<NeonSize>(instr->Bits(19, 18)); |
| 4429 uint32_t src[4]; | |
| 4430 get_q_register(Vm, src); | |
| 4431 if (instr->Bits(9, 6) == 0xd) { | 4449 if (instr->Bits(9, 6) == 0xd) { |
| 4432 // vabs<type>.<size> Qd, Qm | 4450 // vabs<type>.<size> Qd, Qm |
| 4433 if (instr->Bit(10) != 0) { | 4451 if (instr->Bit(10) != 0) { |
| 4434 // floating point (clear sign bits) | 4452 // floating point (clear sign bits) |
| 4453 uint32_t src[4]; |
| 4454 get_q_register(Vm, src); |
| 4435 for (int i = 0; i < 4; i++) { | 4455 for (int i = 0; i < 4; i++) { |
| 4436 src[i] &= ~0x80000000; | 4456 src[i] &= ~0x80000000; |
| 4437 } | 4457 } |
| 4458 set_q_register(Vd, src); |
| 4438 } else { | 4459 } else { |
| 4439 // signed integer | 4460 // signed integer |
| 4440 switch (size) { | 4461 switch (size) { |
| 4441 case Neon8: { | 4462 case Neon8: { |
| 4442 int8_t* s = reinterpret_cast<int8_t*>(src); | 4463 int8_t src[16]; |
| 4464 get_q_register(Vm, src); |
| 4443 for (int i = 0; i < 16; i++) { | 4465 for (int i = 0; i < 16; i++) { |
| 4444 s[i] = std::abs(s[i]); | 4466 src[i] = std::abs(src[i]); |
| 4445 } | 4467 } |
| 4468 set_q_register(Vd, src); |
| 4446 break; | 4469 break; |
| 4447 } | 4470 } |
| 4448 case Neon16: { | 4471 case Neon16: { |
| 4449 int16_t s[8]; | 4472 int16_t src[8]; |
| 4450 memcpy(s, src, sizeof(s)); | 4473 get_q_register(Vm, src); |
| 4451 for (int i = 0; i < 8; i++) { | 4474 for (int i = 0; i < 8; i++) { |
| 4452 s[i] = std::abs(s[i]); | 4475 src[i] = std::abs(src[i]); |
| 4453 } | 4476 } |
| 4454 memcpy(src, s, sizeof(src)); | 4477 set_q_register(Vd, src); |
| 4455 break; | 4478 break; |
| 4456 } | 4479 } |
| 4457 case Neon32: { | 4480 case Neon32: { |
| 4458 int32_t* as_signed = reinterpret_cast<int32_t*>(src); | 4481 int32_t src[4]; |
| 4482 get_q_register(Vm, src); |
| 4459 for (int i = 0; i < 4; i++) { | 4483 for (int i = 0; i < 4; i++) { |
| 4460 as_signed[i] = std::abs(as_signed[i]); | 4484 src[i] = std::abs(src[i]); |
| 4461 } | 4485 } |
| 4486 set_q_register(Vd, src); |
| 4462 break; | 4487 break; |
| 4463 } | 4488 } |
| 4464 default: | 4489 default: |
| 4465 UNIMPLEMENTED(); | 4490 UNIMPLEMENTED(); |
| 4466 break; | 4491 break; |
| 4467 } | 4492 } |
| 4468 } | 4493 } |
| 4469 } else if (instr->Bits(9, 6) == 0xf) { | 4494 } else if (instr->Bits(9, 6) == 0xf) { |
| 4470 // vneg<type>.<size> Qd, Qm (signed integer) | 4495 // vneg<type>.<size> Qd, Qm (signed integer) |
| 4471 if (instr->Bit(10) != 0) { | 4496 if (instr->Bit(10) != 0) { |
| 4472 // floating point (toggle sign bits) | 4497 // floating point (toggle sign bits) |
| 4498 uint32_t src[4]; |
| 4499 get_q_register(Vm, src); |
| 4473 for (int i = 0; i < 4; i++) { | 4500 for (int i = 0; i < 4; i++) { |
| 4474 src[i] ^= 0x80000000; | 4501 src[i] ^= 0x80000000; |
| 4475 } | 4502 } |
| 4503 set_q_register(Vd, src); |
| 4476 } else { | 4504 } else { |
| 4477 // signed integer | 4505 // signed integer |
| 4478 switch (size) { | 4506 switch (size) { |
| 4479 case Neon8: { | 4507 case Neon8: { |
| 4480 int8_t* s = reinterpret_cast<int8_t*>(src); | 4508 int8_t src[16]; |
| 4509 get_q_register(Vm, src); |
| 4481 for (int i = 0; i < 16; i++) { | 4510 for (int i = 0; i < 16; i++) { |
| 4482 s[i] = -s[i]; | 4511 src[i] = -src[i]; |
| 4483 } | 4512 } |
| 4513 set_q_register(Vd, src); |
| 4484 break; | 4514 break; |
| 4485 } | 4515 } |
| 4486 case Neon16: | 4516 case Neon16: |
| 4487 int16_t s[8]; | 4517 int16_t src[8]; |
| 4488 memcpy(s, src, sizeof(s)); | 4518 get_q_register(Vm, src); |
| 4489 for (int i = 0; i < 8; i++) { | 4519 for (int i = 0; i < 8; i++) { |
| 4490 s[i] = -s[i]; | 4520 src[i] = -src[i]; |
| 4491 } | 4521 } |
| 4492 memcpy(src, s, sizeof(src)); | 4522 set_q_register(Vd, src); |
| 4493 break; | 4523 break; |
| 4494 case Neon32: { | 4524 case Neon32: { |
| 4495 int32_t* as_signed = reinterpret_cast<int32_t*>(src); | 4525 int32_t src[4]; |
| 4526 get_q_register(Vm, src); |
| 4496 for (int i = 0; i < 4; i++) { | 4527 for (int i = 0; i < 4; i++) { |
| 4497 as_signed[i] = -as_signed[i]; | 4528 src[i] = -src[i]; |
| 4498 } | 4529 } |
| 4530 set_q_register(Vd, src); |
| 4499 break; | 4531 break; |
| 4500 } | 4532 } |
| 4501 default: | 4533 default: |
| 4502 UNIMPLEMENTED(); | 4534 UNIMPLEMENTED(); |
| 4503 break; | 4535 break; |
| 4504 } | 4536 } |
| 4505 } | 4537 } |
| 4506 } else { | 4538 } else { |
| 4507 UNIMPLEMENTED(); | 4539 UNIMPLEMENTED(); |
| 4508 } | 4540 } |
| 4509 set_q_register(Vd, src); | |
| 4510 } else { | 4541 } else { |
| 4511 UNIMPLEMENTED(); | 4542 UNIMPLEMENTED(); |
| 4512 } | 4543 } |
| 4513 } else { | 4544 } else { |
| 4514 UNIMPLEMENTED(); | 4545 UNIMPLEMENTED(); |
| 4515 } | 4546 } |
| 4516 break; | 4547 break; |
| 4517 case 8: | 4548 case 8: |
| 4518 if (instr->Bits(21, 20) == 0) { | 4549 if (instr->Bits(21, 20) == 0) { |
| 4519 // vst1 | 4550 // vst1 |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5023 set_register(sp, current_sp + sizeof(uintptr_t)); | 5054 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 5024 return address; | 5055 return address; |
| 5025 } | 5056 } |
| 5026 | 5057 |
| 5027 } // namespace internal | 5058 } // namespace internal |
| 5028 } // namespace v8 | 5059 } // namespace v8 |
| 5029 | 5060 |
| 5030 #endif // USE_SIMULATOR | 5061 #endif // USE_SIMULATOR |
| 5031 | 5062 |
| 5032 #endif // V8_TARGET_ARCH_ARM | 5063 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |