Chromium Code Reviews| 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 |