Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdarg.h> | 5 #include <stdarg.h> |
| 6 #include <stdlib.h> | 6 #include <stdlib.h> |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 | 8 |
| 9 #if V8_TARGET_ARCH_ARM | 9 #if V8_TARGET_ARCH_ARM |
| 10 | 10 |
| (...skipping 3049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |