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

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

Issue 2546933002: [Turbofan] Add ARM NEON instructions for implementing SIMD. (Closed)
Patch Set: Review comments. Created 4 years 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
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 3049 matching lines...) Expand 10 before | Expand all | Expand 10 after
3060 // Sd = vsub(Sn, Sm) 3060 // Sd = vsub(Sn, Sm)
3061 // Dd = vmul(Dn, Dm) 3061 // Dd = vmul(Dn, Dm)
3062 // Sd = vmul(Sn, Sm) 3062 // Sd = vmul(Sn, Sm)
3063 // Dd = vdiv(Dn, Dm) 3063 // Dd = vdiv(Dn, Dm)
3064 // Sd = vdiv(Sn, Sm) 3064 // Sd = vdiv(Sn, Sm)
3065 // vcmp(Dd, Dm) 3065 // vcmp(Dd, Dm)
3066 // vcmp(Sd, Sm) 3066 // vcmp(Sd, Sm)
3067 // Dd = vsqrt(Dm) 3067 // Dd = vsqrt(Dm)
3068 // Sd = vsqrt(Sm) 3068 // Sd = vsqrt(Sm)
3069 // vmrs 3069 // vmrs
3070 // vdup.size Qd, Rt.
3070 void Simulator::DecodeTypeVFP(Instruction* instr) { 3071 void Simulator::DecodeTypeVFP(Instruction* instr) {
3071 DCHECK((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); 3072 DCHECK((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
3072 DCHECK(instr->Bits(11, 9) == 0x5); 3073 DCHECK(instr->Bits(11, 9) == 0x5);
3073 3074
3074 // Obtain single precision register codes. 3075 // Obtain single precision register codes.
3075 int m = instr->VFPMRegValue(kSinglePrecision); 3076 int m = instr->VFPMRegValue(kSinglePrecision);
3076 int d = instr->VFPDRegValue(kSinglePrecision); 3077 int d = instr->VFPDRegValue(kSinglePrecision);
3077 int n = instr->VFPNRegValue(kSinglePrecision); 3078 int n = instr->VFPNRegValue(kSinglePrecision);
3078 // Obtain double precision register codes. 3079 // Obtain double precision register codes.
3079 int vm = instr->VFPMRegValue(kDoublePrecision); 3080 int vm = instr->VFPMRegValue(kDoublePrecision);
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
3279 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); 3280 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
3280 } else if ((instr->VLValue() == 0x0) && 3281 } else if ((instr->VLValue() == 0x0) &&
3281 (instr->VCValue() == 0x1) && 3282 (instr->VCValue() == 0x1) &&
3282 (instr->Bit(23) == 0x0)) { 3283 (instr->Bit(23) == 0x0)) {
3283 // vmov (ARM core register to scalar) 3284 // vmov (ARM core register to scalar)
3284 int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4); 3285 int vd = instr->Bits(19, 16) | (instr->Bit(7) << 4);
3285 uint32_t data[2]; 3286 uint32_t data[2];
3286 get_d_register(vd, data); 3287 get_d_register(vd, data);
3287 data[instr->Bit(21)] = get_register(instr->RtValue()); 3288 data[instr->Bit(21)] = get_register(instr->RtValue());
3288 set_d_register(vd, data); 3289 set_d_register(vd, data);
3290 } else if (instr->VLValue() == 0x0 && instr->VCValue() == 0x1 &&
3291 instr->Bit(23) == 0x1) {
3292 // vdup.size Qd, Rt.
3293 int size = 32;
3294 if (instr->Bit(5) != 0)
3295 size = 16;
3296 else if (instr->Bit(22) != 0)
3297 size = 8;
3298 int vd = instr->VFPNRegValue(kSimd128Precision);
3299 int rt = instr->RtValue();
3300 uint32_t rt_value = get_register(rt);
3301 uint32_t q_data[4];
3302 switch (size) {
3303 case 8: {
3304 rt_value &= 0xFF;
3305 uint8_t* dst = reinterpret_cast<uint8_t*>(q_data);
3306 for (int i = 0; i < 16; i++) {
3307 dst[i] = rt_value;
3308 }
3309 break;
3310 }
3311 case 16: {
3312 // Perform pairwise ops instead of casting to uint16_t.
3313 rt_value &= 0xFFFFu;
3314 uint32_t rt_rt = (rt_value << 16) | (rt_value & 0xFFFFu);
3315 for (int i = 0; i < 4; i++) {
3316 q_data[i] = rt_rt;
3317 }
3318 break;
3319 }
3320 case 32: {
3321 for (int i = 0; i < 4; i++) {
3322 q_data[i] = rt_value;
3323 }
3324 break;
3325 }
3326 }
3327 set_q_register(vd, q_data);
3289 } else if ((instr->VLValue() == 0x1) && 3328 } else if ((instr->VLValue() == 0x1) &&
3290 (instr->VCValue() == 0x1) && 3329 (instr->VCValue() == 0x1) &&
3291 (instr->Bit(23) == 0x0)) { 3330 (instr->Bit(23) == 0x0)) {
3292 // vmov (scalar to ARM core register) 3331 // vmov (scalar to ARM core register)
3293 int vn = instr->Bits(19, 16) | (instr->Bit(7) << 4); 3332 int vn = instr->Bits(19, 16) | (instr->Bit(7) << 4);
3294 double dn_value = get_double_from_d_register(vn); 3333 double dn_value = get_double_from_d_register(vn);
3295 int32_t data[2]; 3334 int32_t data[2];
3296 memcpy(data, &dn_value, 8); 3335 memcpy(data, &dn_value, 8);
3297 set_register(instr->RtValue(), data[instr->Bit(21)]); 3336 set_register(instr->RtValue(), data[instr->Bit(21)]);
3298 } else if ((instr->VLValue() == 0x1) && 3337 } else if ((instr->VLValue() == 0x1) &&
(...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after
3733 HandleVList(instr); 3772 HandleVList(instr);
3734 break; 3773 break;
3735 default: 3774 default:
3736 UNIMPLEMENTED(); // Not used by V8. 3775 UNIMPLEMENTED(); // Not used by V8.
3737 } 3776 }
3738 } else { 3777 } else {
3739 UNIMPLEMENTED(); // Not used by V8. 3778 UNIMPLEMENTED(); // Not used by V8.
3740 } 3779 }
3741 } 3780 }
3742 3781
3782 #define HIGH_16(x) ((x) >> 16)
3783 #define LOW_16(x) ((x)&0xFFFFu)
3784 #define COMBINE_32(high, low) ((high) << 16 | (low)&0xFFFFu)
3785 #define PAIRWISE_OP(x, y, OP) \
3786 COMBINE_32(OP(HIGH_16((x)), HIGH_16((y))), OP(LOW_16((x)), LOW_16((y))))
3787
3788 #define ADD(x, y) ((x) + (y))
3789 #define SUB(x, y) ((x) - (y))
3790 #define CEQ(x, y) ((x) == (y) ? 0xFFFFu : 0)
3791 #define TST(x, y) (((x) & (y)) == 0 ? 0xFFFFu : 0)
Rodolph Perfetta (ARM) 2016/12/08 18:08:28 != 0
bbudge 2016/12/10 21:33:04 Done. I need to figure out why the test didn't cat
3743 3792
3744 void Simulator::DecodeSpecialCondition(Instruction* instr) { 3793 void Simulator::DecodeSpecialCondition(Instruction* instr) {
3745 switch (instr->SpecialValue()) { 3794 switch (instr->SpecialValue()) {
3746 case 4: 3795 case 4:
3747 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 && 3796 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 &&
3748 instr->Bit(4) == 1) { 3797 instr->Bit(4) == 1) {
3749 // vmov Qd, Qm 3798 // vmov Qd, Qm
3750 int Vd = instr->VFPDRegValue(kSimd128Precision); 3799 int Vd = instr->VFPDRegValue(kSimd128Precision);
3751 int Vm = instr->VFPMRegValue(kSimd128Precision); 3800 int Vm = instr->VFPMRegValue(kSimd128Precision);
3752 uint32_t data[4]; 3801 uint32_t data[4];
3753 get_q_register(Vm, data); 3802 get_q_register(Vm, data);
3754 set_q_register(Vd, data); 3803 set_q_register(Vd, data);
3804 } else if (instr->Bits(11, 8) == 8) {
3805 // vadd/vtst
3806 int size = instr->Bits(21, 20);
Rodolph Perfetta (ARM) 2016/12/08 18:08:28 NeonSize size = static_cast<NeonSize>(instr->Bit(2
bbudge 2016/12/10 21:33:04 Done. Here and 4 other switches.
3807 int Vd = instr->VFPDRegValue(kSimd128Precision);
3808 int Vm = instr->VFPMRegValue(kSimd128Precision);
3809 int Vn = instr->VFPNRegValue(kSimd128Precision);
3810 uint32_t src1[4], src2[4];
3811 get_q_register(Vn, src1);
3812 get_q_register(Vm, src2);
3813 if (instr->Bit(4) == 0) {
3814 // vadd.i<size> Qd, Qm, Qn.
3815 switch (size) {
3816 case 0: {
3817 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3818 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3819 for (int i = 0; i < 16; i++) {
3820 s1[i] += s2[i];
3821 }
3822 break;
3823 }
3824 case 1: {
3825 for (int i = 0; i < 4; i++) {
3826 src1[i] = PAIRWISE_OP(src1[i], src2[i], ADD);
3827 }
3828 break;
3829 }
3830 case 2: {
3831 for (int i = 0; i < 4; i++) {
3832 src1[i] += src2[i];
3833 }
3834 break;
3835 }
3836 }
3837 } else {
3838 // vtst.i<size> Qd, Qm, Qn.
3839 switch (size) {
3840 case 0: {
3841 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3842 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3843 for (int i = 0; i < 16; i++) {
3844 s1[i] = (s1[i] & s2[i]) != 0 ? 0xFFu : 0;
3845 }
3846 break;
3847 }
3848 case 1: {
3849 for (int i = 0; i < 4; i++) {
3850 src1[i] = PAIRWISE_OP(src1[i], src2[i], TST);
3851 }
3852 break;
3853 }
3854 case 2: {
3855 for (int i = 0; i < 4; i++) {
3856 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFFFFFu : 0;
3857 }
3858 break;
3859 }
3860 }
3861 }
3862 set_q_register(Vd, src1);
3863 } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xd &&
3864 instr->Bit(4) == 0) {
3865 int Vd = instr->VFPDRegValue(kSimd128Precision);
3866 int Vm = instr->VFPMRegValue(kSimd128Precision);
3867 int Vn = instr->VFPNRegValue(kSimd128Precision);
3868 uint32_t src1[4], src2[4];
3869 get_q_register(Vn, src1);
3870 get_q_register(Vm, src2);
3871 for (int i = 0; i < 4; i++) {
3872 if (instr->Bit(21) == 0) {
3873 // vadd.f32 Qd, Qm, Qn.
3874 src1[i] = bit_cast<uint32_t>(bit_cast<float>(src1[i]) +
3875 bit_cast<float>(src2[i]));
3876 } else {
3877 // vsub.f32 Qd, Qm, Qn.
3878 src1[i] = bit_cast<uint32_t>(bit_cast<float>(src1[i]) -
3879 bit_cast<float>(src2[i]));
3880 }
3881 }
3882 set_q_register(Vd, src1);
3755 } else { 3883 } else {
3756 UNIMPLEMENTED(); 3884 UNIMPLEMENTED();
3757 } 3885 }
3758 break; 3886 break;
3759 case 5: 3887 case 5:
3760 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 3888 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
3761 (instr->Bit(4) == 1)) { 3889 (instr->Bit(4) == 1)) {
3762 // vmovl signed 3890 // vmovl signed
3763 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); 3891 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED();
3764 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 3892 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
3765 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 3893 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
3766 int imm3 = instr->Bits(21, 19); 3894 int imm3 = instr->Bits(21, 19);
3767 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); 3895 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
3768 int esize = 8 * imm3; 3896 int esize = 8 * imm3;
3769 int elements = 64 / esize; 3897 int elements = 64 / esize;
3770 int8_t from[8]; 3898 int8_t from[8];
3771 get_d_register(Vm, reinterpret_cast<uint64_t*>(from)); 3899 get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
3772 int16_t to[8]; 3900 int16_t to[8];
3773 int e = 0; 3901 int e = 0;
3774 while (e < elements) { 3902 while (e < elements) {
3775 to[e] = from[e]; 3903 to[e] = from[e];
3776 e++; 3904 e++;
3777 } 3905 }
3778 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); 3906 set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
3779 } else { 3907 } else {
3780 UNIMPLEMENTED(); 3908 UNIMPLEMENTED();
3781 } 3909 }
3782 break; 3910 break;
3783 case 6: 3911 case 6:
3784 if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 && 3912 if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) {
3785 instr->Bit(4) == 1) { 3913 // vsub.size Qd, Qm, Qn.
3914 int size = instr->Bits(21, 20);
3915 int Vd = instr->VFPDRegValue(kSimd128Precision);
3916 int Vm = instr->VFPMRegValue(kSimd128Precision);
3917 int Vn = instr->VFPNRegValue(kSimd128Precision);
3918 uint32_t src1[4], src2[4];
3919 get_q_register(Vn, src1);
3920 get_q_register(Vm, src2);
3921 switch (size) {
3922 case 0: {
3923 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3924 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3925 for (int i = 0; i < 16; i++) {
3926 s1[i] -= s2[i];
3927 }
3928 break;
3929 }
3930 case 1: {
3931 for (int i = 0; i < 4; i++) {
3932 src1[i] = PAIRWISE_OP(src1[i], src2[i], SUB);
3933 }
3934 break;
3935 }
3936 case 2: {
3937 for (int i = 0; i < 4; i++) {
3938 src1[i] -= src2[i];
3939 }
3940 break;
3941 }
3942 }
3943 set_q_register(Vd, src1);
3944 } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) {
3945 // vceq.size Qd, Qm, Qn.
3946 int size = instr->Bits(21, 20);
3947 int Vd = instr->VFPDRegValue(kSimd128Precision);
3948 int Vm = instr->VFPMRegValue(kSimd128Precision);
3949 int Vn = instr->VFPNRegValue(kSimd128Precision);
3950 uint32_t src1[4], src2[4];
3951 get_q_register(Vn, src1);
3952 get_q_register(Vm, src2);
3953 switch (size) {
3954 case 0: {
3955 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3956 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3957 for (int i = 0; i < 16; i++) {
3958 s1[i] = s1[i] == s2[i] ? 0xFF : 0;
3959 }
3960 break;
3961 }
3962 case 1: {
3963 for (int i = 0; i < 4; i++) {
3964 src1[i] = PAIRWISE_OP(src1[i], src2[i], CEQ);
3965 }
3966 break;
3967 }
3968 case 2: {
3969 for (int i = 0; i < 4; i++) {
3970 src1[i] = src1[i] == src2[i] ? 0xFFFFFFFF : 0;
3971 }
3972 break;
3973 }
3974 }
3975 set_q_register(Vd, src1);
3976 } else if (instr->Bits(21, 20) == 1 && instr->Bits(11, 8) == 1 &&
3977 instr->Bit(4) == 1) {
3978 // vbsl.size Qd, Qm, Qn.
3979 int Vd = instr->VFPDRegValue(kSimd128Precision);
3980 int Vm = instr->VFPMRegValue(kSimd128Precision);
3981 int Vn = instr->VFPNRegValue(kSimd128Precision);
3982 uint32_t dst[4], src1[4], src2[4];
3983 get_q_register(Vd, dst);
3984 get_q_register(Vn, src1);
3985 get_q_register(Vm, src2);
3986 for (int i = 0; i < 4; i++) {
3987 dst[i] = (dst[i] & src1[i]) | (~dst[i] & src2[i]);
3988 }
3989 set_q_register(Vd, dst);
3990 } else if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 &&
3991 instr->Bit(4) == 1) {
3786 if (instr->Bit(6) == 0) { 3992 if (instr->Bit(6) == 0) {
3787 // veor Dd, Dn, Dm 3993 // veor Dd, Dn, Dm
3788 int Vd = instr->VFPDRegValue(kDoublePrecision); 3994 int Vd = instr->VFPDRegValue(kDoublePrecision);
3789 int Vn = instr->VFPNRegValue(kDoublePrecision); 3995 int Vn = instr->VFPNRegValue(kDoublePrecision);
3790 int Vm = instr->VFPMRegValue(kDoublePrecision); 3996 int Vm = instr->VFPMRegValue(kDoublePrecision);
3791 uint64_t n_data, m_data; 3997 uint64_t n_data, m_data;
3792 get_d_register(Vn, &n_data); 3998 get_d_register(Vn, &n_data);
3793 get_d_register(Vm, &m_data); 3999 get_d_register(Vm, &m_data);
3794 n_data ^= m_data; 4000 n_data ^= m_data;
3795 set_d_register(Vd, &n_data); 4001 set_d_register(Vd, &n_data);
(...skipping 26 matching lines...) Expand all
3822 int elements = 64 / esize; 4028 int elements = 64 / esize;
3823 uint8_t from[8]; 4029 uint8_t from[8];
3824 get_d_register(Vm, reinterpret_cast<uint64_t*>(from)); 4030 get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
3825 uint16_t to[8]; 4031 uint16_t to[8];
3826 int e = 0; 4032 int e = 0;
3827 while (e < elements) { 4033 while (e < elements) {
3828 to[e] = from[e]; 4034 to[e] = from[e];
3829 e++; 4035 e++;
3830 } 4036 }
3831 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); 4037 set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
4038 } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0xB &&
4039 instr->Bits(11, 9) == 0x3 && instr->Bit(6) == 1 &&
4040 instr->Bit(4) == 0) {
4041 // vcvt.<Td>.<Tm> Qd, Qm.
4042 int Vd = instr->VFPDRegValue(kSimd128Precision);
4043 int Vm = instr->VFPMRegValue(kSimd128Precision);
4044 uint32_t q_data[4];
4045 get_q_register(Vm, q_data);
4046 float* as_float = reinterpret_cast<float*>(q_data);
Rodolph Perfetta (ARM) 2016/12/08 18:08:28 undefined
bbudge 2016/12/10 21:33:04 Removed.
4047 int32_t* as_int = reinterpret_cast<int32_t*>(q_data);
4048 uint32_t* as_uint = reinterpret_cast<uint32_t*>(q_data);
Rodolph Perfetta (ARM) 2016/12/08 18:08:28 cast not needed.
bbudge 2016/12/10 21:33:04 Done.
4049 int op = instr->Bits(8, 7);
4050 for (int i = 0; i < 4; i++) {
4051 switch (op) {
4052 case 0: // s32 -> f32
4053 as_float[i] = static_cast<float>(as_int[i]); // round towards 0.
4054 break;
4055 case 1: // u32 -> Ff2
4056 as_float[i] = static_cast<float>(as_uint[i]); // round towards 0.
4057 break;
4058 case 2: // f32 -> s32
4059 as_int[i] = static_cast<int32_t>(as_float[i]);
4060 break;
4061 case 3: // f32 -> u32
4062 as_uint[i] = static_cast<uint32_t>(as_float[i]);
Rodolph Perfetta (ARM) 2016/12/08 18:08:28 this is undefined if the float value is negative.
bbudge 2016/12/10 21:33:04 I've pulled a helper method out of the existing VC
4063 break;
4064 }
4065 }
4066 set_q_register(Vd, q_data);
3832 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) && 4067 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) &&
3833 (instr->Bit(4) == 0)) { 4068 (instr->Bit(4) == 0)) {
3834 if (instr->Bit(6) == 0) { 4069 if (instr->Bit(6) == 0) {
3835 // vswp Dd, Dm. 4070 // vswp Dd, Dm.
3836 uint64_t dval, mval; 4071 uint64_t dval, mval;
3837 int vd = instr->VFPDRegValue(kDoublePrecision); 4072 int vd = instr->VFPDRegValue(kDoublePrecision);
3838 int vm = instr->VFPMRegValue(kDoublePrecision); 4073 int vm = instr->VFPMRegValue(kDoublePrecision);
3839 get_d_register(vd, &dval); 4074 get_d_register(vd, &dval);
3840 get_d_register(vm, &mval); 4075 get_d_register(vm, &mval);
3841 set_d_register(vm, &dval); 4076 set_d_register(vm, &dval);
3842 set_d_register(vd, &mval); 4077 set_d_register(vd, &mval);
3843 } else { 4078 } else {
3844 // vswp Qd, Qm. 4079 // vswp Qd, Qm.
3845 uint32_t dval[4], mval[4]; 4080 uint32_t dval[4], mval[4];
3846 int vd = instr->VFPDRegValue(kSimd128Precision); 4081 int vd = instr->VFPDRegValue(kSimd128Precision);
3847 int vm = instr->VFPMRegValue(kSimd128Precision); 4082 int vm = instr->VFPMRegValue(kSimd128Precision);
3848 get_q_register(vd, dval); 4083 get_q_register(vd, dval);
3849 get_q_register(vm, mval); 4084 get_q_register(vm, mval);
3850 set_q_register(vm, dval); 4085 set_q_register(vm, dval);
3851 set_q_register(vd, mval); 4086 set_q_register(vd, mval);
3852 } 4087 }
4088 } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 7) == 0x18 &&
4089 instr->Bit(4) == 0x0) {
4090 // vdup.32 Qd, Sm.
4091 int vd = instr->VFPDRegValue(kSimd128Precision);
4092 int vm = instr->VFPMRegValue(kDoublePrecision);
4093 int index = instr->Bit(19);
4094 uint32_t s_data = get_s_register(vm * 2 + index);
4095 uint32_t q_data[4];
4096 for (int i = 0; i < 4; i++) q_data[i] = s_data;
4097 set_q_register(vd, q_data);
4098 } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0 &&
4099 instr->Bits(11, 6) == 0x17 && instr->Bit(4) == 0) {
4100 // vmvn Qd, Qm.
4101 int vd = instr->VFPDRegValue(kSimd128Precision);
4102 int vm = instr->VFPMRegValue(kSimd128Precision);
4103 uint32_t q_data[4];
4104 get_q_register(vm, q_data);
4105 for (int i = 0; i < 4; i++) q_data[i] = ~q_data[i];
4106 set_q_register(vd, q_data);
4107 } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 10) == 0x2 &&
4108 instr->Bit(4) == 0x0) {
4109 // vtb[l,x] Dd, <list>, Dm.
4110 int vd = instr->VFPDRegValue(kDoublePrecision);
4111 int vn = instr->VFPNRegValue(kDoublePrecision);
4112 int vm = instr->VFPMRegValue(kDoublePrecision);
4113 int table_len = (instr->Bits(9, 8) + 1) * kDoubleSize;
4114 bool vtbx = instr->Bit(6) != 0; // vtbl / vtbx
4115 uint64_t destination = 0, indices = 0, result = 0;
4116 get_d_register(vd, &destination);
4117 get_d_register(vm, &indices);
4118 for (int i = 0; i < kDoubleSize; i++) {
4119 int shift = i * kBitsPerByte;
4120 int index = (indices >> shift) & 0xFF;
4121 if (index < table_len) {
4122 uint64_t table;
4123 get_d_register(vn + index / kDoubleSize, &table);
4124 result |= ((table >> ((index % kDoubleSize) * kBitsPerByte)) & 0xFF)
4125 << shift;
4126 } else if (vtbx) {
4127 result |= destination & (0xFFull << shift);
4128 }
4129 }
4130 set_d_register(vd, &result);
3853 } else { 4131 } else {
3854 UNIMPLEMENTED(); 4132 UNIMPLEMENTED();
3855 } 4133 }
3856 break; 4134 break;
3857 case 8: 4135 case 8:
3858 if (instr->Bits(21, 20) == 0) { 4136 if (instr->Bits(21, 20) == 0) {
3859 // vst1 4137 // vst1
3860 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); 4138 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
3861 int Rn = instr->VnValue(); 4139 int Rn = instr->VnValue();
3862 int type = instr->Bits(11, 8); 4140 int type = instr->Bits(11, 8);
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
4363 set_register(sp, current_sp + sizeof(uintptr_t)); 4641 set_register(sp, current_sp + sizeof(uintptr_t));
4364 return address; 4642 return address;
4365 } 4643 }
4366 4644
4367 } // namespace internal 4645 } // namespace internal
4368 } // namespace v8 4646 } // namespace v8
4369 4647
4370 #endif // USE_SIMULATOR 4648 #endif // USE_SIMULATOR
4371 4649
4372 #endif // V8_TARGET_ARCH_ARM 4650 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698