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 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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |