OLD | NEW |
---|---|
1 // Copyright (c) 1994-2006 Sun Microsystems Inc. | 1 // Copyright (c) 1994-2006 Sun Microsystems Inc. |
2 // All Rights Reserved. | 2 // All Rights Reserved. |
3 // | 3 // |
4 // Redistribution and use in source and binary forms, with or without | 4 // Redistribution and use in source and binary forms, with or without |
5 // modification, are permitted provided that the following conditions | 5 // modification, are permitted provided that the following conditions |
6 // are met: | 6 // are met: |
7 // | 7 // |
8 // - Redistributions of source code must retain the above copyright notice, | 8 // - Redistributions of source code must retain the above copyright notice, |
9 // this list of conditions and the following disclaimer. | 9 // this list of conditions and the following disclaimer. |
10 // | 10 // |
(...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
476 case 256: | 476 case 256: |
477 align_ = 3; | 477 align_ = 3; |
478 break; | 478 break; |
479 default: | 479 default: |
480 UNREACHABLE(); | 480 UNREACHABLE(); |
481 align_ = 0; | 481 align_ = 0; |
482 break; | 482 break; |
483 } | 483 } |
484 } | 484 } |
485 | 485 |
486 | |
487 NeonListOperand::NeonListOperand(DoubleRegister base, int registers_count) { | |
488 base_ = base; | |
489 switch (registers_count) { | |
490 case 1: | |
491 type_ = nlt_1; | |
492 break; | |
493 case 2: | |
494 type_ = nlt_2; | |
495 break; | |
496 case 3: | |
497 type_ = nlt_3; | |
498 break; | |
499 case 4: | |
500 type_ = nlt_4; | |
501 break; | |
502 default: | |
503 UNREACHABLE(); | |
504 type_ = nlt_1; | |
505 break; | |
506 } | |
507 } | |
508 | |
509 | |
510 // ----------------------------------------------------------------------------- | 486 // ----------------------------------------------------------------------------- |
511 // Specific instructions, constants, and masks. | 487 // Specific instructions, constants, and masks. |
512 | 488 |
513 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) | 489 // str(r, MemOperand(sp, 4, NegPreIndex), al) instruction (aka push(r)) |
514 // register r is not encoded. | 490 // register r is not encoded. |
515 const Instr kPushRegPattern = | 491 const Instr kPushRegPattern = |
516 al | B26 | 4 | NegPreIndex | Register::kCode_sp * B16; | 492 al | B26 | 4 | NegPreIndex | Register::kCode_sp * B16; |
517 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) | 493 // ldr(r, MemOperand(sp, 4, PostIndex), al) instruction (aka pop(r)) |
518 // register r is not encoded. | 494 // register r is not encoded. |
519 const Instr kPopRegPattern = | 495 const Instr kPopRegPattern = |
(...skipping 2441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2961 // Rt = Sn. | 2937 // Rt = Sn. |
2962 // Instruction details available in ARM DDI 0406A, A8-642. | 2938 // Instruction details available in ARM DDI 0406A, A8-642. |
2963 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | | 2939 // cond(31-28) | 1110(27-24)| 000(23-21) | op=1(20) | Vn(19-16) | |
2964 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) | 2940 // Rt(15-12) | 1010(11-8) | N(7)=0 | 00(6-5) | 1(4) | 0000(3-0) |
2965 DCHECK(!dst.is(pc)); | 2941 DCHECK(!dst.is(pc)); |
2966 int sn, n; | 2942 int sn, n; |
2967 src.split_code(&sn, &n); | 2943 src.split_code(&sn, &n); |
2968 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); | 2944 emit(cond | 0xE*B24 | B20 | sn*B16 | dst.code()*B12 | 0xA*B8 | n*B7 | B4); |
2969 } | 2945 } |
2970 | 2946 |
2971 | |
2972 // Type of data to read from or write to VFP register. | 2947 // Type of data to read from or write to VFP register. |
2973 // Used as specifier in generic vcvt instruction. | 2948 // Used as specifier in generic vcvt instruction. |
2974 enum VFPType { S32, U32, F32, F64 }; | 2949 enum VFPType { S32, U32, F32, F64 }; |
2975 | 2950 |
2976 | 2951 |
2977 static bool IsSignedVFPType(VFPType type) { | 2952 static bool IsSignedVFPType(VFPType type) { |
2978 switch (type) { | 2953 switch (type) { |
2979 case S32: | 2954 case S32: |
2980 return true; | 2955 return true; |
2981 case U32: | 2956 case U32: |
(...skipping 926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3908 DCHECK(VfpRegisterIsAvailable(dst)); | 3883 DCHECK(VfpRegisterIsAvailable(dst)); |
3909 DCHECK(VfpRegisterIsAvailable(src)); | 3884 DCHECK(VfpRegisterIsAvailable(src)); |
3910 int vd, d; | 3885 int vd, d; |
3911 dst.split_code(&vd, &d); | 3886 dst.split_code(&vd, &d); |
3912 int vm, m; | 3887 int vm, m; |
3913 src.split_code(&vm, &m); | 3888 src.split_code(&vm, &m); |
3914 emit(0x1E4 * B23 | d * B22 | 2 * B20 | vm * B16 | vd * B12 | B8 | m * B7 | | 3889 emit(0x1E4 * B23 | d * B22 | 2 * B20 | vm * B16 | vd * B12 | B8 | m * B7 | |
3915 B6 | m * B5 | B4 | vm); | 3890 B6 | m * B5 | B4 | vm); |
3916 } | 3891 } |
3917 | 3892 |
3893 void Assembler::vmvn(const QwNeonRegister dst, const QwNeonRegister src) { | |
3894 DCHECK(IsEnabled(NEON)); | |
3895 // Instruction details available in ARM DDI 0406C.b, A8-966. | |
3896 DCHECK(VfpRegisterIsAvailable(dst)); | |
3897 DCHECK(VfpRegisterIsAvailable(src)); | |
3898 int vd, d; | |
3899 dst.split_code(&vd, &d); | |
3900 int vm, m; | |
3901 src.split_code(&vm, &m); | |
3902 emit(0x1E7 * B23 | d * B22 | 3 * B20 | vd * B12 | 0x17 * B6 | m * B5 | vm); | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
0x1E7U according to issue 5725
bbudge
2016/12/10 21:33:03
Done.
| |
3903 } | |
3904 | |
3918 void Assembler::vswp(DwVfpRegister dst, DwVfpRegister src) { | 3905 void Assembler::vswp(DwVfpRegister dst, DwVfpRegister src) { |
3919 // Instruction details available in ARM DDI 0406C.b, A8.8.418. | 3906 // Instruction details available in ARM DDI 0406C.b, A8.8.418. |
3920 // 1111(31-28) | 00111(27-23) | D(22) | 110010(21-16) | | 3907 // 1111(31-28) | 00111(27-23) | D(22) | 110010(21-16) | |
3921 // Vd(15-12) | 000000(11-6) | M(5) | 0(4) | Vm(3-0) | 3908 // Vd(15-12) | 000000(11-6) | M(5) | 0(4) | Vm(3-0) |
3922 DCHECK(IsEnabled(NEON)); | 3909 DCHECK(IsEnabled(NEON)); |
3923 int vd, d; | 3910 int vd, d; |
3924 dst.split_code(&vd, &d); | 3911 dst.split_code(&vd, &d); |
3925 int vm, m; | 3912 int vm, m; |
3926 src.split_code(&vm, &m); | 3913 src.split_code(&vm, &m); |
3927 emit(0xFU * B28 | 7 * B23 | d * B22 | 0x32 * B16 | vd * B12 | m * B5 | vm); | 3914 emit(0xFU * B28 | 7 * B23 | d * B22 | 0x32 * B16 | vd * B12 | m * B5 | vm); |
3928 } | 3915 } |
3929 | 3916 |
3930 void Assembler::vswp(QwNeonRegister dst, QwNeonRegister src) { | 3917 void Assembler::vswp(QwNeonRegister dst, QwNeonRegister src) { |
3931 // Instruction details available in ARM DDI 0406C.b, A8.8.418. | 3918 // Instruction details available in ARM DDI 0406C.b, A8.8.418. |
3932 // 1111(31-28) | 00111(27-23) | D(22) | 110010(21-16) | | 3919 // 1111(31-28) | 00111(27-23) | D(22) | 110010(21-16) | |
3933 // Vd(15-12) | 000000(11-6) | M(5) | 0(4) | Vm(3-0) | 3920 // Vd(15-12) | 000000(11-6) | M(5) | 0(4) | Vm(3-0) |
3934 DCHECK(IsEnabled(NEON)); | 3921 DCHECK(IsEnabled(NEON)); |
3935 int vd, d; | 3922 int vd, d; |
3936 dst.split_code(&vd, &d); | 3923 dst.split_code(&vd, &d); |
3937 int vm, m; | 3924 int vm, m; |
3938 src.split_code(&vm, &m); | 3925 src.split_code(&vm, &m); |
3939 emit(0xFU * B28 | 7 * B23 | d * B22 | 0x32 * B16 | vd * B12 | B6 | m * B5 | | 3926 emit(0xFU * B28 | 7 * B23 | d * B22 | 0x32 * B16 | vd * B12 | B6 | m * B5 | |
3940 vm); | 3927 vm); |
3941 } | 3928 } |
3942 | 3929 |
3930 void Assembler::vdup(const QwNeonRegister dst, const Register src, | |
3931 NeonSize size) { | |
3932 DCHECK(IsEnabled(NEON)); | |
3933 // Instruction details available in ARM DDI 0406C.b, A8-886. | |
3934 int B = 0, E = 0; | |
3935 switch (size) { | |
3936 case Neon8: | |
3937 B = 1; | |
3938 break; | |
3939 case Neon16: | |
3940 E = 1; | |
3941 break; | |
3942 case Neon32: | |
3943 break; | |
3944 default: | |
3945 UNREACHABLE(); | |
3946 break; | |
3947 } | |
3948 int vd, d; | |
3949 dst.split_code(&vd, &d); | |
3950 | |
3951 emit(al | 0x1D * B23 | B * B22 | B21 | vd * B16 | src.code() * B12 | | |
3952 0xB * B8 | d * B7 | E * B5 | B4); | |
3953 } | |
3954 | |
3955 void Assembler::vdup(const QwNeonRegister dst, const SwVfpRegister src) { | |
3956 DCHECK(IsEnabled(NEON)); | |
3957 // Instruction details available in ARM DDI 0406C.b, A8-884. | |
3958 int index = src.code() & 1; | |
3959 int d_reg = src.code() / 2; | |
3960 int imm4 = 4 | index << 3; // esize = 32, index in bit 3. | |
3961 int vd, d; | |
3962 dst.split_code(&vd, &d); | |
3963 int vm, m; | |
3964 DwVfpRegister::from_code(d_reg).split_code(&vm, &m); | |
3965 | |
3966 emit(0x1E7 * B23 | d * B22 | 0x3 * B20 | imm4 * B16 | vd * B12 | 0x18 * B7 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
0x1E7U
bbudge
2016/12/10 21:33:03
Done.
| |
3967 B6 | m * B5 | vm); | |
3968 } | |
3969 | |
3970 // Encode NEON vcvt.src_type.dst_type instruction. | |
3971 static Instr EncodeNeonVCVT(const VFPType dst_type, const QwNeonRegister dst, | |
3972 const VFPType src_type, const QwNeonRegister src) { | |
3973 DCHECK(src_type != dst_type); | |
3974 DCHECK(src_type == F32 || dst_type == F32); | |
3975 DCHECK(src_type != F64 && dst_type != F64); | |
3976 // Instruction details available in ARM DDI 0406C.b, A8.8.868. | |
3977 int vd, d; | |
3978 dst.split_code(&vd, &d); | |
3979 int vm, m; | |
3980 src.split_code(&vm, &m); | |
3981 | |
3982 int op = 0; | |
3983 if (src_type == F32) { | |
3984 op = dst_type == U32 ? 3 : 2; | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
DCECHK((dst_type == U32) || (dst_type == S32));
bbudge
2016/12/10 21:33:03
It's (subtly) implied by the existing DCHECKs abov
| |
3985 } else { | |
3986 DCHECK_EQ(F32, dst_type); | |
3987 op = src_type == U32 ? 1 : 0; | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
ditto with src_type
bbudge
2016/12/10 21:33:03
Done.
| |
3988 } | |
3989 | |
3990 return 0x1E7u * B23 | d * B22 | 0x3B * B16 | vd * B12 | 0x3 * B9 | op * B7 | | |
3991 B6 | m * B5 | vm; | |
3992 } | |
3993 | |
3994 void Assembler::vcvt_f32_s32(const QwNeonRegister dst, | |
3995 const QwNeonRegister src) { | |
3996 DCHECK(IsEnabled(NEON)); | |
3997 DCHECK(VfpRegisterIsAvailable(dst)); | |
3998 DCHECK(VfpRegisterIsAvailable(src)); | |
3999 emit(EncodeNeonVCVT(F32, dst, S32, src)); | |
4000 } | |
4001 | |
4002 void Assembler::vcvt_f32_u32(const QwNeonRegister dst, | |
4003 const QwNeonRegister src) { | |
4004 DCHECK(IsEnabled(NEON)); | |
4005 DCHECK(VfpRegisterIsAvailable(dst)); | |
4006 DCHECK(VfpRegisterIsAvailable(src)); | |
4007 emit(EncodeNeonVCVT(F32, dst, U32, src)); | |
4008 } | |
4009 | |
4010 void Assembler::vcvt_s32_f32(const QwNeonRegister dst, | |
4011 const QwNeonRegister src) { | |
4012 DCHECK(IsEnabled(NEON)); | |
4013 DCHECK(VfpRegisterIsAvailable(dst)); | |
4014 DCHECK(VfpRegisterIsAvailable(src)); | |
4015 emit(EncodeNeonVCVT(S32, dst, F32, src)); | |
4016 } | |
4017 | |
4018 void Assembler::vcvt_u32_f32(const QwNeonRegister dst, | |
4019 const QwNeonRegister src) { | |
4020 DCHECK(IsEnabled(NEON)); | |
4021 DCHECK(VfpRegisterIsAvailable(dst)); | |
4022 DCHECK(VfpRegisterIsAvailable(src)); | |
4023 emit(EncodeNeonVCVT(U32, dst, F32, src)); | |
4024 } | |
4025 | |
3943 void Assembler::veor(DwVfpRegister dst, DwVfpRegister src1, | 4026 void Assembler::veor(DwVfpRegister dst, DwVfpRegister src1, |
3944 DwVfpRegister src2) { | 4027 DwVfpRegister src2) { |
4028 // Dd = veor(Dn, Dm) 64 bit integer exclusive OR. | |
3945 // Instruction details available in ARM DDI 0406C.b, A8.8.888. | 4029 // Instruction details available in ARM DDI 0406C.b, A8.8.888. |
3946 DCHECK(IsEnabled(NEON)); | 4030 DCHECK(IsEnabled(NEON)); |
3947 int vd, d; | 4031 int vd, d; |
3948 dst.split_code(&vd, &d); | 4032 dst.split_code(&vd, &d); |
3949 int vn, n; | 4033 int vn, n; |
3950 src1.split_code(&vn, &n); | 4034 src1.split_code(&vn, &n); |
3951 int vm, m; | 4035 int vm, m; |
3952 src2.split_code(&vm, &m); | 4036 src2.split_code(&vm, &m); |
3953 emit(0x1E6 * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | m * B5 | B4 | | 4037 emit(0x1E6 * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | m * B5 | B4 | |
3954 vm); | 4038 vm); |
3955 } | 4039 } |
3956 | 4040 |
3957 void Assembler::veor(QwNeonRegister dst, QwNeonRegister src1, | 4041 void Assembler::veor(QwNeonRegister dst, QwNeonRegister src1, |
3958 QwNeonRegister src2) { | 4042 QwNeonRegister src2) { |
4043 // Qd = veor(Qn, Qm) SIMD integer exclusive OR. | |
3959 // Instruction details available in ARM DDI 0406C.b, A8.8.888. | 4044 // Instruction details available in ARM DDI 0406C.b, A8.8.888. |
3960 DCHECK(IsEnabled(NEON)); | 4045 DCHECK(IsEnabled(NEON)); |
3961 int vd, d; | 4046 int vd, d; |
3962 dst.split_code(&vd, &d); | 4047 dst.split_code(&vd, &d); |
3963 int vn, n; | 4048 int vn, n; |
3964 src1.split_code(&vn, &n); | 4049 src1.split_code(&vn, &n); |
3965 int vm, m; | 4050 int vm, m; |
3966 src2.split_code(&vm, &m); | 4051 src2.split_code(&vm, &m); |
3967 emit(0x1E6 * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | B6 | m * B5 | | 4052 emit(0x1E6 * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | B6 | m * B5 | |
3968 B4 | vm); | 4053 B4 | vm); |
3969 } | 4054 } |
3970 | 4055 |
4056 void Assembler::vadd(QwNeonRegister dst, const QwNeonRegister src1, | |
4057 const QwNeonRegister src2) { | |
4058 DCHECK(IsEnabled(NEON)); | |
4059 // Qd = vadd(Qn, Qm) SIMD floating point addition. | |
4060 // Instruction details available in ARM DDI 0406C.b, A8-830. | |
4061 int vd, d; | |
4062 dst.split_code(&vd, &d); | |
4063 int vn, n; | |
4064 src1.split_code(&vn, &n); | |
4065 int vm, m; | |
4066 src2.split_code(&vm, &m); | |
4067 emit(0x1E4 * B23 | d * B22 | vn * B16 | vd * B12 | 0xD * B8 | n * B7 | B6 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
0x1E4U
bbudge
2016/12/10 21:33:03
Done.
| |
4068 m * B5 | vm); | |
4069 } | |
4070 | |
4071 void Assembler::vadd(QwNeonRegister dst, const QwNeonRegister src1, | |
4072 const QwNeonRegister src2, NeonSize size) { | |
4073 DCHECK(IsEnabled(NEON)); | |
4074 // Qd = vadd(Qn, Qm) SIMD integer addition. | |
4075 // Instruction details available in ARM DDI 0406C.b, A8-828. | |
4076 int vd, d; | |
4077 dst.split_code(&vd, &d); | |
4078 int vn, n; | |
4079 src1.split_code(&vn, &n); | |
4080 int vm, m; | |
4081 src2.split_code(&vm, &m); | |
4082 int sz = static_cast<int>(size); | |
4083 emit(0x1E4 * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
ditto
bbudge
2016/12/10 21:33:03
Done.
| |
4084 n * B7 | B6 | m * B5 | vm); | |
4085 } | |
4086 | |
4087 void Assembler::vsub(QwNeonRegister dst, const QwNeonRegister src1, | |
4088 const QwNeonRegister src2) { | |
4089 DCHECK(IsEnabled(NEON)); | |
4090 // Qd = vsub(Qn, Qm) SIMD floating point subtraction. | |
4091 // Instruction details available in ARM DDI 0406C.b, A8-1086. | |
4092 int vd, d; | |
4093 dst.split_code(&vd, &d); | |
4094 int vn, n; | |
4095 src1.split_code(&vn, &n); | |
4096 int vm, m; | |
4097 src2.split_code(&vm, &m); | |
4098 emit(0x1E4 * B23 | d * B22 | B21 | vn * B16 | vd * B12 | 0xD * B8 | n * B7 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
ditto
bbudge
2016/12/10 21:33:03
Done.
| |
4099 B6 | m * B5 | vm); | |
4100 } | |
4101 | |
4102 void Assembler::vsub(QwNeonRegister dst, const QwNeonRegister src1, | |
4103 const QwNeonRegister src2, NeonSize size) { | |
4104 DCHECK(IsEnabled(NEON)); | |
4105 // Qd = vsub(Qn, Qm) SIMD integer subtraction. | |
4106 // Instruction details available in ARM DDI 0406C.b, A8-1084. | |
4107 int vd, d; | |
4108 dst.split_code(&vd, &d); | |
4109 int vn, n; | |
4110 src1.split_code(&vn, &n); | |
4111 int vm, m; | |
4112 src2.split_code(&vm, &m); | |
4113 int sz = static_cast<int>(size); | |
4114 emit(0x1E6 * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
ditto
bbudge
2016/12/10 21:33:03
Done.
| |
4115 n * B7 | B6 | m * B5 | vm); | |
4116 } | |
4117 | |
4118 void Assembler::vtst(QwNeonRegister dst, const QwNeonRegister src1, | |
4119 const QwNeonRegister src2, NeonSize size) { | |
4120 DCHECK(IsEnabled(NEON)); | |
4121 // Qd = vtst(Qn, Qm) SIMD test integer operands. | |
4122 // Instruction details available in ARM DDI 0406C.b, A8-1098. | |
4123 int vd, d; | |
4124 dst.split_code(&vd, &d); | |
4125 int vn, n; | |
4126 src1.split_code(&vn, &n); | |
4127 int vm, m; | |
4128 src2.split_code(&vm, &m); | |
4129 int sz = static_cast<int>(size); | |
4130 emit(0x1E4 * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
ditto
bbudge
2016/12/10 21:33:03
Done.
| |
4131 n * B7 | B6 | m * B5 | B4 | vm); | |
4132 } | |
4133 | |
4134 void Assembler::vceq(QwNeonRegister dst, const QwNeonRegister src1, | |
4135 const QwNeonRegister src2, NeonSize size) { | |
4136 DCHECK(IsEnabled(NEON)); | |
4137 // Qd = vceq(Qn, Qm) SIMD integer compare equal. | |
4138 // Instruction details available in ARM DDI 0406C.b, A8-844. | |
4139 int vd, d; | |
4140 dst.split_code(&vd, &d); | |
4141 int vn, n; | |
4142 src1.split_code(&vn, &n); | |
4143 int vm, m; | |
4144 src2.split_code(&vm, &m); | |
4145 int sz = static_cast<int>(size); | |
4146 emit(0x1E6 * B23 | d * B22 | sz * B20 | vn * B16 | vd * B12 | 0x8 * B8 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
ditto
bbudge
2016/12/10 21:33:04
Done.
| |
4147 n * B7 | B6 | m * B5 | B4 | vm); | |
4148 } | |
4149 | |
4150 void Assembler::vbsl(QwNeonRegister dst, const QwNeonRegister src1, | |
4151 const QwNeonRegister src2) { | |
4152 DCHECK(IsEnabled(NEON)); | |
4153 // Qd = vbsl(Qn, Qm) SIMD bitwise select. | |
4154 // Instruction details available in ARM DDI 0406C.b, A8-844. | |
4155 int vd, d; | |
4156 dst.split_code(&vd, &d); | |
4157 int vn, n; | |
4158 src1.split_code(&vn, &n); | |
4159 int vm, m; | |
4160 src2.split_code(&vm, &m); | |
4161 int op = 1; // vbsl | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
is that necessary? why not using B20 directly belo
bbudge
2016/12/10 21:33:04
Done.
| |
4162 emit(0x1E6 * B23 | d * B22 | op * B20 | vn * B16 | vd * B12 | 0x1 * B8 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
0x1E6U
bbudge
2016/12/10 21:33:03
Done.
| |
4163 n * B7 | B6 | m * B5 | B4 | vm); | |
4164 } | |
4165 | |
4166 void Assembler::vtbl(const DwVfpRegister dst, const NeonListOperand& list, | |
4167 const DwVfpRegister index) { | |
4168 DCHECK(IsEnabled(NEON)); | |
4169 // Dd = vtbl(table, Dm) SIMD vector permute, zero at out of range indices. | |
4170 // Instruction details available in ARM DDI 0406C.b, A8-1094. | |
4171 int vd, d; | |
4172 dst.split_code(&vd, &d); | |
4173 int vn, n; | |
4174 list.base().split_code(&vn, &n); | |
4175 int vm, m; | |
4176 index.split_code(&vm, &m); | |
4177 int op = 1; // vbsl | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
unused.
bbudge
2016/12/10 21:33:04
Done.
| |
4178 emit(0x1E7 * B23 | d * B22 | 0x3 * B20 | vn * B16 | vd * B12 | 0x2 * B10 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
0x1E7U
bbudge
2016/12/10 21:33:03
Done.
| |
4179 list.len() * B8 | n * B7 | m * B5 | vm); | |
4180 } | |
4181 | |
4182 void Assembler::vtbx(const DwVfpRegister dst, const NeonListOperand& list, | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
vtbl and vtbx encoding only differ by the value of
bbudge
2016/12/10 21:33:03
Yes, Done.
| |
4183 const DwVfpRegister index) { | |
4184 DCHECK(IsEnabled(NEON)); | |
4185 // Dd = vtbx(table, Dm) SIMD vector permute, skip out of range indices. | |
4186 // Instruction details available in ARM DDI 0406C.b, A8-1094. | |
4187 int vd, d; | |
4188 dst.split_code(&vd, &d); | |
4189 int vn, n; | |
4190 list.base().split_code(&vn, &n); | |
4191 int vm, m; | |
4192 index.split_code(&vm, &m); | |
4193 int op = 1; // vbsl | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
unused
bbudge
2016/12/10 21:33:03
Done.
| |
4194 emit(0x1E7 * B23 | d * B22 | 0x3 * B20 | vn * B16 | vd * B12 | 0x2 * B10 | | |
Rodolph Perfetta (ARM)
2016/12/08 18:08:27
0x1E7U
bbudge
2016/12/10 21:33:04
Done.
| |
4195 list.len() * B8 | n * B7 | B6 | m * B5 | vm); | |
4196 } | |
4197 | |
3971 // Pseudo instructions. | 4198 // Pseudo instructions. |
3972 void Assembler::nop(int type) { | 4199 void Assembler::nop(int type) { |
3973 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes | 4200 // ARMv6{K/T2} and v7 have an actual NOP instruction but it serializes |
3974 // some of the CPU's pipeline and has to issue. Older ARM chips simply used | 4201 // some of the CPU's pipeline and has to issue. Older ARM chips simply used |
3975 // MOV Rx, Rx as NOP and it performs better even in newer CPUs. | 4202 // MOV Rx, Rx as NOP and it performs better even in newer CPUs. |
3976 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode | 4203 // We therefore use MOV Rx, Rx, even on newer CPUs, and use Rx to encode |
3977 // a type. | 4204 // a type. |
3978 DCHECK(0 <= type && type <= 14); // mov pc, pc isn't a nop. | 4205 DCHECK(0 <= type && type <= 14); // mov pc, pc isn't a nop. |
3979 emit(al | 13*B21 | type*B12 | type); | 4206 emit(al | 13*B21 | type*B12 | type); |
3980 } | 4207 } |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4514 DCHECK(is_uint12(offset)); | 4741 DCHECK(is_uint12(offset)); |
4515 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 4742 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
4516 } | 4743 } |
4517 } | 4744 } |
4518 | 4745 |
4519 | 4746 |
4520 } // namespace internal | 4747 } // namespace internal |
4521 } // namespace v8 | 4748 } // namespace v8 |
4522 | 4749 |
4523 #endif // V8_TARGET_ARCH_ARM | 4750 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |