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

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

Issue 2546933002: [Turbofan] Add ARM NEON instructions for implementing SIMD. (Closed)
Patch Set: Don't use temporary FP regs in tests. 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 rt_value &= 0xFFFF;
3313 uint16_t* dst = reinterpret_cast<uint16_t*>(q_data);
Rodolph Perfetta (ARM) 2016/12/07 15:59:00 I believe this is only safe for bytes, you may enc
bbudge 2016/12/08 03:07:31 I worked around this by performing operations in p
3314 for (int i = 0; i < 8; i++) {
3315 dst[i] = rt_value;
3316 }
3317 break;
3318 }
3319 case 32: {
3320 for (int i = 0; i < 4; i++) {
3321 q_data[i] = rt_value;
3322 }
3323 break;
3324 }
3325 }
3326 set_q_register(vd, q_data);
3289 } else if ((instr->VLValue() == 0x1) && 3327 } else if ((instr->VLValue() == 0x1) &&
3290 (instr->VCValue() == 0x1) && 3328 (instr->VCValue() == 0x1) &&
3291 (instr->Bit(23) == 0x0)) { 3329 (instr->Bit(23) == 0x0)) {
3292 // vmov (scalar to ARM core register) 3330 // vmov (scalar to ARM core register)
3293 int vn = instr->Bits(19, 16) | (instr->Bit(7) << 4); 3331 int vn = instr->Bits(19, 16) | (instr->Bit(7) << 4);
3294 double dn_value = get_double_from_d_register(vn); 3332 double dn_value = get_double_from_d_register(vn);
3295 int32_t data[2]; 3333 int32_t data[2];
3296 memcpy(data, &dn_value, 8); 3334 memcpy(data, &dn_value, 8);
3297 set_register(instr->RtValue(), data[instr->Bit(21)]); 3335 set_register(instr->RtValue(), data[instr->Bit(21)]);
3298 } else if ((instr->VLValue() == 0x1) && 3336 } else if ((instr->VLValue() == 0x1) &&
(...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after
3745 switch (instr->SpecialValue()) { 3783 switch (instr->SpecialValue()) {
3746 case 4: 3784 case 4:
3747 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 && 3785 if (instr->Bits(21, 20) == 2 && instr->Bits(11, 8) == 1 &&
3748 instr->Bit(4) == 1) { 3786 instr->Bit(4) == 1) {
3749 // vmov Qd, Qm 3787 // vmov Qd, Qm
3750 int Vd = instr->VFPDRegValue(kSimd128Precision); 3788 int Vd = instr->VFPDRegValue(kSimd128Precision);
3751 int Vm = instr->VFPMRegValue(kSimd128Precision); 3789 int Vm = instr->VFPMRegValue(kSimd128Precision);
3752 uint32_t data[4]; 3790 uint32_t data[4];
3753 get_q_register(Vm, data); 3791 get_q_register(Vm, data);
3754 set_q_register(Vd, data); 3792 set_q_register(Vd, data);
3793 } else if (instr->Bits(11, 8) == 8) {
3794 // vadd/vtst
3795 int size = instr->Bits(21, 20);
3796 int Vd = instr->VFPDRegValue(kSimd128Precision);
3797 int Vm = instr->VFPMRegValue(kSimd128Precision);
3798 int Vn = instr->VFPNRegValue(kSimd128Precision);
3799 uint32_t src1[4], src2[4];
3800 get_q_register(Vn, src1);
3801 get_q_register(Vm, src2);
3802 if (instr->Bit(4) == 0) {
3803 // vadd.I<size> Qd, Qm, Qn.
3804 switch (size) {
3805 case 0: {
3806 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3807 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3808 for (int i = 0; i < 16; i++) {
3809 s1[i] += s2[i];
3810 }
3811 break;
3812 }
3813 case 1: {
3814 uint16_t* s1 = reinterpret_cast<uint16_t*>(src1);
3815 uint16_t* s2 = reinterpret_cast<uint16_t*>(src2);
3816 for (int i = 0; i < 8; i++) {
3817 s1[i] += s2[i];
3818 }
3819 break;
3820 }
3821 case 2: {
3822 for (int i = 0; i < 4; i++) {
3823 src1[i] += src2[i];
3824 }
3825 break;
3826 }
3827 }
3828 } else {
3829 // vtst.I<size> Qd, Qm, Qn.
3830 switch (size) {
3831 case 0: {
3832 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3833 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3834 for (int i = 0; i < 16; i++) {
3835 s1[i] = (s1[i] & s2[i]) != 0 ? 0xFFu : 0;
3836 }
3837 break;
3838 }
3839 case 1: {
3840 uint16_t* s1 = reinterpret_cast<uint16_t*>(src1);
3841 uint16_t* s2 = reinterpret_cast<uint16_t*>(src2);
3842 for (int i = 0; i < 8; i++) {
3843 s1[i] = (s1[i] & s2[i]) != 0 ? 0xFFFFu : 0;
3844 }
3845 break;
3846 }
3847 case 2: {
3848 for (int i = 0; i < 4; i++) {
3849 src1[i] = (src1[i] & src2[i]) != 0 ? 0xFFFFFFFFu : 0;
3850 }
3851 break;
3852 }
3853 }
3854 }
3855 set_q_register(Vd, src1);
3856 } else if (instr->Bit(20) == 0 && instr->Bits(11, 8) == 0xd &&
3857 instr->Bit(4) == 0) {
3858 int Vd = instr->VFPDRegValue(kSimd128Precision);
3859 int Vm = instr->VFPMRegValue(kSimd128Precision);
3860 int Vn = instr->VFPNRegValue(kSimd128Precision);
3861 uint32_t src1[4], src2[4];
3862 get_q_register(Vn, src1);
3863 get_q_register(Vm, src2);
3864 float* s1 = reinterpret_cast<float*>(src1);
3865 float* s2 = reinterpret_cast<float*>(src2);
3866 for (int i = 0; i < 4; i++) {
3867 if (instr->Bit(21) == 0) {
3868 // vadd.F32 Qd, Qm, Qn.
3869 s1[i] += s2[i];
3870 } else {
3871 // vsub.F32 Qd, Qm, Qn.
3872 s1[i] -= s2[i];
3873 }
3874 }
3875 set_q_register(Vd, src1);
3755 } else { 3876 } else {
3756 UNIMPLEMENTED(); 3877 UNIMPLEMENTED();
3757 } 3878 }
3758 break; 3879 break;
3759 case 5: 3880 case 5:
3760 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) && 3881 if ((instr->Bits(18, 16) == 0) && (instr->Bits(11, 6) == 0x28) &&
3761 (instr->Bit(4) == 1)) { 3882 (instr->Bit(4) == 1)) {
3762 // vmovl signed 3883 // vmovl signed
3763 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED(); 3884 if ((instr->VdValue() & 1) != 0) UNIMPLEMENTED();
3764 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1); 3885 int Vd = (instr->Bit(22) << 3) | (instr->VdValue() >> 1);
3765 int Vm = (instr->Bit(5) << 4) | instr->VmValue(); 3886 int Vm = (instr->Bit(5) << 4) | instr->VmValue();
3766 int imm3 = instr->Bits(21, 19); 3887 int imm3 = instr->Bits(21, 19);
3767 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED(); 3888 if ((imm3 != 1) && (imm3 != 2) && (imm3 != 4)) UNIMPLEMENTED();
3768 int esize = 8 * imm3; 3889 int esize = 8 * imm3;
3769 int elements = 64 / esize; 3890 int elements = 64 / esize;
3770 int8_t from[8]; 3891 int8_t from[8];
3771 get_d_register(Vm, reinterpret_cast<uint64_t*>(from)); 3892 get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
3772 int16_t to[8]; 3893 int16_t to[8];
3773 int e = 0; 3894 int e = 0;
3774 while (e < elements) { 3895 while (e < elements) {
3775 to[e] = from[e]; 3896 to[e] = from[e];
3776 e++; 3897 e++;
3777 } 3898 }
3778 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); 3899 set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
3779 } else { 3900 } else {
3780 UNIMPLEMENTED(); 3901 UNIMPLEMENTED();
3781 } 3902 }
3782 break; 3903 break;
3783 case 6: 3904 case 6:
3784 if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 && 3905 if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 0) {
3785 instr->Bit(4) == 1) { 3906 // vsub.size Qd, Qm, Qn.
3907 int size = instr->Bits(21, 20);
3908 int Vd = instr->VFPDRegValue(kSimd128Precision);
3909 int Vm = instr->VFPMRegValue(kSimd128Precision);
3910 int Vn = instr->VFPNRegValue(kSimd128Precision);
3911 uint32_t src1[4], src2[4];
3912 get_q_register(Vn, src1);
3913 get_q_register(Vm, src2);
3914 switch (size) {
3915 case 0: {
3916 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3917 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3918 for (int i = 0; i < 16; i++) {
3919 s1[i] -= s2[i];
3920 }
3921 break;
3922 }
3923 case 1: {
3924 uint16_t* s1 = reinterpret_cast<uint16_t*>(src1);
3925 uint16_t* s2 = reinterpret_cast<uint16_t*>(src2);
3926 for (int i = 0; i < 8; i++) {
3927 s1[i] -= s2[i];
3928 }
3929 break;
3930 }
3931 case 2: {
3932 for (int i = 0; i < 4; i++) {
3933 src1[i] -= src2[i];
3934 }
3935 break;
3936 }
3937 }
3938 set_q_register(Vd, src1);
3939 } else if (instr->Bits(11, 8) == 8 && instr->Bit(4) == 1) {
3940 // vceq.size Qd, Qm, Qn.
3941 int size = instr->Bits(21, 20);
3942 int Vd = instr->VFPDRegValue(kSimd128Precision);
3943 int Vm = instr->VFPMRegValue(kSimd128Precision);
3944 int Vn = instr->VFPNRegValue(kSimd128Precision);
3945 uint32_t src1[4], src2[4];
3946 get_q_register(Vn, src1);
3947 get_q_register(Vm, src2);
3948 switch (size) {
3949 case 0: {
3950 uint8_t* s1 = reinterpret_cast<uint8_t*>(src1);
3951 uint8_t* s2 = reinterpret_cast<uint8_t*>(src2);
3952 for (int i = 0; i < 16; i++) {
3953 s1[i] = s1[i] == s2[i] ? 0xFF : 0;
3954 }
3955 break;
3956 }
3957 case 1: {
3958 uint16_t* s1 = reinterpret_cast<uint16_t*>(src1);
3959 uint16_t* s2 = reinterpret_cast<uint16_t*>(src2);
3960 for (int i = 0; i < 8; i++) {
3961 s1[i] = s1[i] == s2[i] ? 0xFFFF : 0;
3962 }
3963 break;
3964 }
3965 case 2: {
3966 for (int i = 0; i < 4; i++) {
3967 src1[i] = src1[i] == src2[i] ? 0xFFFFFFFF : 0;
3968 }
3969 break;
3970 }
3971 }
3972 set_q_register(Vd, src1);
3973 } else if (instr->Bits(21, 20) == 1 && instr->Bits(11, 8) == 1 &&
3974 instr->Bit(4) == 1) {
3975 // vbsl.size Qd, Qm, Qn.
3976 int Vd = instr->VFPDRegValue(kSimd128Precision);
3977 int Vm = instr->VFPMRegValue(kSimd128Precision);
3978 int Vn = instr->VFPNRegValue(kSimd128Precision);
3979 uint32_t dst[4], src1[4], src2[4];
3980 get_q_register(Vd, dst);
3981 get_q_register(Vn, src1);
3982 get_q_register(Vm, src2);
3983 for (int i = 0; i < 4; i++) {
3984 dst[i] = (dst[i] & src1[i]) | (~dst[i] & src2[i]);
3985 }
3986 set_q_register(Vd, dst);
3987 } else if (instr->Bits(21, 20) == 0 && instr->Bits(11, 8) == 1 &&
3988 instr->Bit(4) == 1) {
3786 if (instr->Bit(6) == 0) { 3989 if (instr->Bit(6) == 0) {
3787 // veor Dd, Dn, Dm 3990 // veor Dd, Dn, Dm
3788 int Vd = instr->VFPDRegValue(kDoublePrecision); 3991 int Vd = instr->VFPDRegValue(kDoublePrecision);
3789 int Vn = instr->VFPNRegValue(kDoublePrecision); 3992 int Vn = instr->VFPNRegValue(kDoublePrecision);
3790 int Vm = instr->VFPMRegValue(kDoublePrecision); 3993 int Vm = instr->VFPMRegValue(kDoublePrecision);
3791 uint64_t n_data, m_data; 3994 uint64_t n_data, m_data;
3792 get_d_register(Vn, &n_data); 3995 get_d_register(Vn, &n_data);
3793 get_d_register(Vm, &m_data); 3996 get_d_register(Vm, &m_data);
3794 n_data ^= m_data; 3997 n_data ^= m_data;
3795 set_d_register(Vd, &n_data); 3998 set_d_register(Vd, &n_data);
(...skipping 26 matching lines...) Expand all
3822 int elements = 64 / esize; 4025 int elements = 64 / esize;
3823 uint8_t from[8]; 4026 uint8_t from[8];
3824 get_d_register(Vm, reinterpret_cast<uint64_t*>(from)); 4027 get_d_register(Vm, reinterpret_cast<uint64_t*>(from));
3825 uint16_t to[8]; 4028 uint16_t to[8];
3826 int e = 0; 4029 int e = 0;
3827 while (e < elements) { 4030 while (e < elements) {
3828 to[e] = from[e]; 4031 to[e] = from[e];
3829 e++; 4032 e++;
3830 } 4033 }
3831 set_q_register(Vd, reinterpret_cast<uint64_t*>(to)); 4034 set_q_register(Vd, reinterpret_cast<uint64_t*>(to));
4035 } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0xB &&
4036 instr->Bits(11, 9) == 0x3 && instr->Bit(4) == 0) {
4037 // vcvt.<Td>.<Tm> Qd, Qm.
4038 int Vd = instr->VFPDRegValue(kSimd128Precision);
4039 int Vm = instr->VFPMRegValue(kSimd128Precision);
4040 uint32_t q_data[4];
4041 get_q_register(Vm, q_data);
4042 float* as_float = reinterpret_cast<float*>(q_data);
4043 int32_t* as_int = reinterpret_cast<int32_t*>(q_data);
4044 uint32_t* as_uint = reinterpret_cast<uint32_t*>(q_data);
4045 int op = instr->Bits(8, 7);
4046 for (int i = 0; i < 4; i++) {
4047 switch (op) {
4048 case 0: // F32 -> S32
Rodolph Perfetta (ARM) 2016/12/07 15:59:00 as for the assembler, op interpretation is incorre
bbudge 2016/12/08 03:07:31 Done.
4049 as_int[i] = static_cast<int32_t>(as_float[i]);
4050 break;
4051 case 1: // F32 -> U32
4052 as_uint[i] = static_cast<uint32_t>(as_float[i]);
4053 break;
4054 case 2: // S32 -> F32
4055 as_float[i] = static_cast<float>(as_int[i]); // round towards 0.
4056 break;
4057 case 3: // U32 -> F32
4058 as_float[i] = static_cast<float>(as_uint[i]); // round towards 0.
4059 break;
4060 }
4061 }
4062 set_q_register(Vd, q_data);
3832 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) && 4063 } else if ((instr->Bits(21, 16) == 0x32) && (instr->Bits(11, 7) == 0) &&
3833 (instr->Bit(4) == 0)) { 4064 (instr->Bit(4) == 0)) {
3834 if (instr->Bit(6) == 0) { 4065 if (instr->Bit(6) == 0) {
3835 // vswp Dd, Dm. 4066 // vswp Dd, Dm.
3836 uint64_t dval, mval; 4067 uint64_t dval, mval;
3837 int vd = instr->VFPDRegValue(kDoublePrecision); 4068 int vd = instr->VFPDRegValue(kDoublePrecision);
3838 int vm = instr->VFPMRegValue(kDoublePrecision); 4069 int vm = instr->VFPMRegValue(kDoublePrecision);
3839 get_d_register(vd, &dval); 4070 get_d_register(vd, &dval);
3840 get_d_register(vm, &mval); 4071 get_d_register(vm, &mval);
3841 set_d_register(vm, &dval); 4072 set_d_register(vm, &dval);
3842 set_d_register(vd, &mval); 4073 set_d_register(vd, &mval);
3843 } else { 4074 } else {
3844 // vswp Qd, Qm. 4075 // vswp Qd, Qm.
3845 uint32_t dval[4], mval[4]; 4076 uint32_t dval[4], mval[4];
3846 int vd = instr->VFPDRegValue(kSimd128Precision); 4077 int vd = instr->VFPDRegValue(kSimd128Precision);
3847 int vm = instr->VFPMRegValue(kSimd128Precision); 4078 int vm = instr->VFPMRegValue(kSimd128Precision);
3848 get_q_register(vd, dval); 4079 get_q_register(vd, dval);
3849 get_q_register(vm, mval); 4080 get_q_register(vm, mval);
3850 set_q_register(vm, dval); 4081 set_q_register(vm, dval);
3851 set_q_register(vd, mval); 4082 set_q_register(vd, mval);
3852 } 4083 }
4084 } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 7) == 0x18 &&
4085 instr->Bit(4) == 0x0) {
4086 // vdup.32 Qd, Sm.
4087 int vd = instr->VFPDRegValue(kSimd128Precision);
4088 int vm = instr->VFPMRegValue(kDoublePrecision);
4089 int index = instr->Bit(19);
4090 uint32_t s_data = get_s_register(vm * 2 + index);
4091 uint32_t q_data[4];
4092 for (int i = 0; i < 4; i++) q_data[i] = s_data;
4093 set_q_register(vd, q_data);
4094 } else if (instr->Opc1Value() == 7 && instr->Bits(19, 16) == 0 &&
4095 instr->Bits(11, 6) == 0x17 && instr->Bit(4) == 0) {
4096 // vmvn Qd, Qm.
4097 int vd = instr->VFPDRegValue(kSimd128Precision);
4098 int vm = instr->VFPMRegValue(kSimd128Precision);
4099 uint32_t q_data[4];
4100 get_q_register(vm, q_data);
4101 for (int i = 0; i < 4; i++) q_data[i] = ~q_data[i];
4102 set_q_register(vd, q_data);
4103 } else if (instr->Opc1Value() == 0x7 && instr->Bits(11, 10) == 0x2 &&
4104 instr->Bit(4) == 0x0) {
4105 // vtb[l,x] Dd, <list>, Dm.
4106 int vd = instr->VFPDRegValue(kDoublePrecision);
4107 int vn = instr->VFPNRegValue(kDoublePrecision);
4108 int vm = instr->VFPMRegValue(kDoublePrecision);
4109 int table_len = (instr->Bits(9, 8) + 1) * kDoubleSize;
4110 bool vtbx = instr->Bit(6) != 0; // vtbl / vtbx
4111 uint64_t destination = 0, indices = 0, result = 0;
4112 get_d_register(vd, &destination);
4113 get_d_register(vm, &indices);
4114 for (int i = 0; i < kDoubleSize; i++) {
4115 int shift = i * kBitsPerByte;
4116 int index = (indices >> shift) & 0xFF;
4117 if (index < table_len) {
4118 uint64_t table;
4119 get_d_register(vn + index / kDoubleSize, &table);
4120 result |= ((table >> ((index % kDoubleSize) * kBitsPerByte)) & 0xFF)
4121 << shift;
4122 } else if (vtbx) {
4123 result |= destination & (0xFFull << shift);
4124 }
4125 }
4126 set_d_register(vd, &result);
3853 } else { 4127 } else {
3854 UNIMPLEMENTED(); 4128 UNIMPLEMENTED();
3855 } 4129 }
3856 break; 4130 break;
3857 case 8: 4131 case 8:
3858 if (instr->Bits(21, 20) == 0) { 4132 if (instr->Bits(21, 20) == 0) {
3859 // vst1 4133 // vst1
3860 int Vd = (instr->Bit(22) << 4) | instr->VdValue(); 4134 int Vd = (instr->Bit(22) << 4) | instr->VdValue();
3861 int Rn = instr->VnValue(); 4135 int Rn = instr->VnValue();
3862 int type = instr->Bits(11, 8); 4136 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)); 4637 set_register(sp, current_sp + sizeof(uintptr_t));
4364 return address; 4638 return address;
4365 } 4639 }
4366 4640
4367 } // namespace internal 4641 } // namespace internal
4368 } // namespace v8 4642 } // namespace v8
4369 4643
4370 #endif // USE_SIMULATOR 4644 #endif // USE_SIMULATOR
4371 4645
4372 #endif // V8_TARGET_ARCH_ARM 4646 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698