Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Side by Side Diff: src/arm/simulator-arm.cc

Issue 2619223002: [ARM] Add get_q_register, set_q_register overloads for NEON instructions. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« src/arm/simulator-arm.h ('K') | « src/arm/simulator-arm.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« src/arm/simulator-arm.h ('K') | « src/arm/simulator-arm.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698