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

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

Issue 2546933002: [Turbofan] Add ARM NEON instructions for implementing SIMD. (Closed)
Patch Set: Review comments. 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 (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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698