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

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

Powered by Google App Engine
This is Rietveld 408576698