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 4056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4067 } | 4067 } |
| 4068 | 4068 |
| 4069 void Assembler::vcvt_u32_f32(const QwNeonRegister dst, | 4069 void Assembler::vcvt_u32_f32(const QwNeonRegister dst, |
| 4070 const QwNeonRegister src) { | 4070 const QwNeonRegister src) { |
| 4071 DCHECK(IsEnabled(NEON)); | 4071 DCHECK(IsEnabled(NEON)); |
| 4072 DCHECK(VfpRegisterIsAvailable(dst)); | 4072 DCHECK(VfpRegisterIsAvailable(dst)); |
| 4073 DCHECK(VfpRegisterIsAvailable(src)); | 4073 DCHECK(VfpRegisterIsAvailable(src)); |
| 4074 emit(EncodeNeonVCVT(U32, dst, F32, src)); | 4074 emit(EncodeNeonVCVT(U32, dst, F32, src)); |
| 4075 } | 4075 } |
| 4076 | 4076 |
| 4077 // op is instr->Bits(11, 7). | 4077 enum UnaryOp { VABS, VABSF, VNEG, VNEGF }; |
| 4078 static Instr EncodeNeonUnaryOp(int op, bool is_float, NeonSize size, | 4078 |
| 4079 const QwNeonRegister dst, | 4079 static Instr EncodeNeonUnaryOp(UnaryOp op, NeonSize size, QwNeonRegister dst, |
| 4080 const QwNeonRegister src) { | 4080 QwNeonRegister src) { |
| 4081 DCHECK_IMPLIES(is_float, size == Neon32); | 4081 int op_encoding = 0; |
| 4082 switch (op) { | |
| 4083 case VABS: | |
|
martyn.capewell
2017/02/28 15:45:24
Depending on whether you like fallthrough cases, t
bbudge
2017/02/28 17:39:34
I think v8 style is to avoid fall through unless i
| |
| 4084 op_encoding = 0x6 * B7; | |
| 4085 break; | |
| 4086 case VABSF: | |
| 4087 DCHECK_EQ(Neon32, size); | |
| 4088 op_encoding = 0x6 * B7 | B10; | |
| 4089 break; | |
| 4090 case VNEG: | |
| 4091 op_encoding = 0x7 * B7; | |
| 4092 break; | |
| 4093 case VNEGF: | |
| 4094 DCHECK_EQ(Neon32, size); | |
| 4095 op_encoding = 0x7 * B7 | B10; | |
| 4096 break; | |
| 4097 default: | |
| 4098 UNREACHABLE(); | |
| 4099 break; | |
| 4100 } | |
| 4082 int vd, d; | 4101 int vd, d; |
| 4083 dst.split_code(&vd, &d); | 4102 dst.split_code(&vd, &d); |
| 4084 int vm, m; | 4103 int vm, m; |
| 4085 src.split_code(&vm, &m); | 4104 src.split_code(&vm, &m); |
| 4086 int F = is_float ? 1 : 0; | 4105 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | size * B18 | B16 | vd * B12 | B8 | |
|
martyn.capewell
2017/02/28 15:45:24
The switch above always sets B8, so it can be remo
bbudge
2017/02/28 17:39:34
Wow, good eye. Done.
| |
| 4087 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | size * B18 | B16 | vd * B12 | | 4106 B6 | m * B5 | vm | op_encoding; |
| 4088 F * B10 | B8 | op * B7 | B6 | m * B5 | vm; | |
| 4089 } | 4107 } |
| 4090 | 4108 |
| 4091 void Assembler::vabs(const QwNeonRegister dst, const QwNeonRegister src) { | 4109 void Assembler::vabs(const QwNeonRegister dst, const QwNeonRegister src) { |
| 4092 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point absolute value. | 4110 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point absolute value. |
| 4093 // Instruction details available in ARM DDI 0406C.b, A8.8.824. | 4111 // Instruction details available in ARM DDI 0406C.b, A8.8.824. |
| 4094 DCHECK(IsEnabled(NEON)); | 4112 DCHECK(IsEnabled(NEON)); |
| 4095 emit(EncodeNeonUnaryOp(0x6, true, Neon32, dst, src)); | 4113 emit(EncodeNeonUnaryOp(VABSF, Neon32, dst, src)); |
| 4096 } | 4114 } |
| 4097 | 4115 |
| 4098 void Assembler::vabs(NeonSize size, const QwNeonRegister dst, | 4116 void Assembler::vabs(NeonSize size, const QwNeonRegister dst, |
| 4099 const QwNeonRegister src) { | 4117 const QwNeonRegister src) { |
| 4100 // Qd = vabs.s<size>(Qn, Qm) SIMD integer absolute value. | 4118 // Qd = vabs.s<size>(Qn, Qm) SIMD integer absolute value. |
| 4101 // Instruction details available in ARM DDI 0406C.b, A8.8.824. | 4119 // Instruction details available in ARM DDI 0406C.b, A8.8.824. |
| 4102 DCHECK(IsEnabled(NEON)); | 4120 DCHECK(IsEnabled(NEON)); |
| 4103 emit(EncodeNeonUnaryOp(0x6, false, size, dst, src)); | 4121 emit(EncodeNeonUnaryOp(VABS, size, dst, src)); |
| 4104 } | 4122 } |
| 4105 | 4123 |
| 4106 void Assembler::vneg(const QwNeonRegister dst, const QwNeonRegister src) { | 4124 void Assembler::vneg(const QwNeonRegister dst, const QwNeonRegister src) { |
| 4107 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point negate. | 4125 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point negate. |
| 4108 // Instruction details available in ARM DDI 0406C.b, A8.8.968. | 4126 // Instruction details available in ARM DDI 0406C.b, A8.8.968. |
| 4109 DCHECK(IsEnabled(NEON)); | 4127 DCHECK(IsEnabled(NEON)); |
| 4110 emit(EncodeNeonUnaryOp(0x7, true, Neon32, dst, src)); | 4128 emit(EncodeNeonUnaryOp(VNEGF, Neon32, dst, src)); |
| 4111 } | 4129 } |
| 4112 | 4130 |
| 4113 void Assembler::vneg(NeonSize size, const QwNeonRegister dst, | 4131 void Assembler::vneg(NeonSize size, const QwNeonRegister dst, |
| 4114 const QwNeonRegister src) { | 4132 const QwNeonRegister src) { |
| 4115 // Qd = vabs.s<size>(Qn, Qm) SIMD integer negate. | 4133 // Qd = vabs.s<size>(Qn, Qm) SIMD integer negate. |
| 4116 // Instruction details available in ARM DDI 0406C.b, A8.8.968. | 4134 // Instruction details available in ARM DDI 0406C.b, A8.8.968. |
| 4117 DCHECK(IsEnabled(NEON)); | 4135 DCHECK(IsEnabled(NEON)); |
| 4118 emit(EncodeNeonUnaryOp(0x7, false, size, dst, src)); | 4136 emit(EncodeNeonUnaryOp(VNEG, size, dst, src)); |
| 4119 } | 4137 } |
| 4120 | 4138 |
| 4121 void Assembler::veor(DwVfpRegister dst, DwVfpRegister src1, | 4139 void Assembler::veor(DwVfpRegister dst, DwVfpRegister src1, |
| 4122 DwVfpRegister src2) { | 4140 DwVfpRegister src2) { |
| 4123 // Dd = veor(Dn, Dm) 64 bit integer exclusive OR. | 4141 // Dd = veor(Dn, Dm) 64 bit integer exclusive OR. |
| 4124 // Instruction details available in ARM DDI 0406C.b, A8.8.888. | 4142 // Instruction details available in ARM DDI 0406C.b, A8.8.888. |
| 4125 DCHECK(IsEnabled(NEON)); | 4143 DCHECK(IsEnabled(NEON)); |
| 4126 int vd, d; | 4144 int vd, d; |
| 4127 dst.split_code(&vd, &d); | 4145 dst.split_code(&vd, &d); |
| 4128 int vn, n; | 4146 int vn, n; |
| 4129 src1.split_code(&vn, &n); | 4147 src1.split_code(&vn, &n); |
| 4130 int vm, m; | 4148 int vm, m; |
| 4131 src2.split_code(&vm, &m); | 4149 src2.split_code(&vm, &m); |
| 4132 emit(0x1E6U * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | m * B5 | | 4150 emit(0x1E6U * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | m * B5 | |
| 4133 B4 | vm); | 4151 B4 | vm); |
| 4134 } | 4152 } |
| 4135 | 4153 |
| 4136 enum BinaryBitwiseOp { VAND, VBIC, VBIF, VBIT, VBSL, VEOR, VORR, VORN }; | 4154 enum BinaryBitwiseOp { VAND, VBIC, VBIF, VBIT, VBSL, VEOR, VORR, VORN }; |
| 4137 | 4155 |
| 4138 static Instr EncodeNeonBinaryBitwiseOp(BinaryBitwiseOp op, | 4156 static Instr EncodeNeonBinaryBitwiseOp(BinaryBitwiseOp op, QwNeonRegister dst, |
| 4139 const QwNeonRegister dst, | 4157 QwNeonRegister src1, |
| 4140 const QwNeonRegister src1, | 4158 QwNeonRegister src2) { |
| 4141 const QwNeonRegister src2) { | |
| 4142 int op_encoding = 0; | 4159 int op_encoding = 0; |
| 4143 switch (op) { | 4160 switch (op) { |
| 4144 case VBIC: | 4161 case VBIC: |
| 4145 op_encoding = 0x1 * B20; | 4162 op_encoding = 0x1 * B20; |
| 4146 break; | 4163 break; |
| 4147 case VBIF: | 4164 case VBIF: |
| 4148 op_encoding = B24 | 0x3 * B20; | 4165 op_encoding = B24 | 0x3 * B20; |
| 4149 break; | 4166 break; |
| 4150 case VBIT: | 4167 case VBIT: |
| 4151 op_encoding = B24 | 0x2 * B20; | 4168 op_encoding = B24 | 0x2 * B20; |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4280 VMUL, | 4297 VMUL, |
| 4281 VMIN, | 4298 VMIN, |
| 4282 VMAX, | 4299 VMAX, |
| 4283 VTST, | 4300 VTST, |
| 4284 VCEQ, | 4301 VCEQ, |
| 4285 VCGE, | 4302 VCGE, |
| 4286 VCGT | 4303 VCGT |
| 4287 }; | 4304 }; |
| 4288 | 4305 |
| 4289 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonDataType dt, | 4306 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonDataType dt, |
| 4290 const QwNeonRegister dst, | 4307 QwNeonRegister dst, QwNeonRegister src1, |
| 4291 const QwNeonRegister src1, | 4308 QwNeonRegister src2) { |
| 4292 const QwNeonRegister src2) { | |
| 4293 int op_encoding = 0; | 4309 int op_encoding = 0; |
| 4294 switch (op) { | 4310 switch (op) { |
| 4295 case VADD: | 4311 case VADD: |
| 4296 op_encoding = 0x8 * B8; | 4312 op_encoding = 0x8 * B8; |
| 4297 break; | 4313 break; |
| 4298 case VQADD: | 4314 case VQADD: |
| 4299 op_encoding = B4; | 4315 op_encoding = B4; |
| 4300 break; | 4316 break; |
| 4301 case VSUB: | 4317 case VSUB: |
| 4302 op_encoding = B24 | 0x8 * B8; | 4318 op_encoding = B24 | 0x8 * B8; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4334 int vn, n; | 4350 int vn, n; |
| 4335 src1.split_code(&vn, &n); | 4351 src1.split_code(&vn, &n); |
| 4336 int vm, m; | 4352 int vm, m; |
| 4337 src2.split_code(&vm, &m); | 4353 src2.split_code(&vm, &m); |
| 4338 int size = NeonSz(dt); | 4354 int size = NeonSz(dt); |
| 4339 int u = NeonU(dt); | 4355 int u = NeonU(dt); |
| 4340 return 0x1E4U * B23 | u * B24 | d * B22 | size * B20 | vn * B16 | vd * B12 | | 4356 return 0x1E4U * B23 | u * B24 | d * B22 | size * B20 | vn * B16 | vd * B12 | |
| 4341 n * B7 | B6 | m * B5 | vm | op_encoding; | 4357 n * B7 | B6 | m * B5 | vm | op_encoding; |
| 4342 } | 4358 } |
| 4343 | 4359 |
| 4344 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonSize size, | 4360 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonSize size, QwNeonRegister dst, |
| 4345 const QwNeonRegister dst, | 4361 QwNeonRegister src1, QwNeonRegister src2) { |
| 4346 const QwNeonRegister src1, | |
| 4347 const QwNeonRegister src2) { | |
| 4348 // Map NeonSize values to the signed values in NeonDataType, so the U bit | 4362 // Map NeonSize values to the signed values in NeonDataType, so the U bit |
| 4349 // will be 0. | 4363 // will be 0. |
| 4350 return EncodeNeonBinOp(op, static_cast<NeonDataType>(size), dst, src1, src2); | 4364 return EncodeNeonBinOp(op, static_cast<NeonDataType>(size), dst, src1, src2); |
| 4351 } | 4365 } |
| 4352 | 4366 |
| 4353 void Assembler::vadd(QwNeonRegister dst, QwNeonRegister src1, | 4367 void Assembler::vadd(QwNeonRegister dst, QwNeonRegister src1, |
| 4354 QwNeonRegister src2) { | 4368 QwNeonRegister src2) { |
| 4355 DCHECK(IsEnabled(NEON)); | 4369 DCHECK(IsEnabled(NEON)); |
| 4356 // Qd = vadd(Qn, Qm) SIMD floating point addition. | 4370 // Qd = vadd(Qn, Qm) SIMD floating point addition. |
| 4357 // Instruction details available in ARM DDI 0406C.b, A8-830. | 4371 // Instruction details available in ARM DDI 0406C.b, A8-830. |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4522 } | 4536 } |
| 4523 | 4537 |
| 4524 void Assembler::vrsqrts(QwNeonRegister dst, QwNeonRegister src1, | 4538 void Assembler::vrsqrts(QwNeonRegister dst, QwNeonRegister src1, |
| 4525 QwNeonRegister src2) { | 4539 QwNeonRegister src2) { |
| 4526 DCHECK(IsEnabled(NEON)); | 4540 DCHECK(IsEnabled(NEON)); |
| 4527 // Qd = vrsqrts(Qn, Qm) SIMD reciprocal square root refinement step. | 4541 // Qd = vrsqrts(Qn, Qm) SIMD reciprocal square root refinement step. |
| 4528 // Instruction details available in ARM DDI 0406C.b, A8-1040. | 4542 // Instruction details available in ARM DDI 0406C.b, A8-1040. |
| 4529 emit(EncodeNeonBinOp(VRSQRTS, dst, src1, src2)); | 4543 emit(EncodeNeonBinOp(VRSQRTS, dst, src1, src2)); |
| 4530 } | 4544 } |
| 4531 | 4545 |
| 4546 enum PairwiseOp { VPMIN, VPMAX }; | |
| 4547 | |
| 4548 static Instr EncodeNeonPairwiseOp(PairwiseOp op, NeonDataType dt, | |
| 4549 DwVfpRegister dst, DwVfpRegister src1, | |
| 4550 DwVfpRegister src2) { | |
| 4551 int op_encoding = 0; | |
| 4552 switch (op) { | |
| 4553 case VPMIN: | |
| 4554 op_encoding = 0xA * B8 | B4; | |
| 4555 break; | |
| 4556 case VPMAX: | |
| 4557 op_encoding = 0xA * B8; | |
| 4558 break; | |
| 4559 default: | |
| 4560 UNREACHABLE(); | |
| 4561 break; | |
| 4562 } | |
| 4563 int vd, d; | |
| 4564 dst.split_code(&vd, &d); | |
| 4565 int vn, n; | |
| 4566 src1.split_code(&vn, &n); | |
| 4567 int vm, m; | |
| 4568 src2.split_code(&vm, &m); | |
| 4569 int size = NeonSz(dt); | |
| 4570 int u = NeonU(dt); | |
| 4571 return 0x1E4U * B23 | u * B24 | d * B22 | size * B20 | vn * B16 | vd * B12 | | |
| 4572 n * B7 | m * B5 | vm | op_encoding; | |
| 4573 } | |
| 4574 | |
| 4575 void Assembler::vpmin(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1, | |
| 4576 DwVfpRegister src2) { | |
| 4577 DCHECK(IsEnabled(NEON)); | |
| 4578 // Qd = vpmin(Qn, Qm) SIMD integer pairwise MIN. | |
|
martyn.capewell
2017/02/28 15:45:24
These are D registers for min and max.
bbudge
2017/02/28 17:39:35
Done here and below.
| |
| 4579 // Instruction details available in ARM DDI 0406C.b, A8-986. | |
| 4580 emit(EncodeNeonPairwiseOp(VPMIN, dt, dst, src1, src2)); | |
| 4581 } | |
| 4582 | |
| 4583 void Assembler::vpmax(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1, | |
| 4584 DwVfpRegister src2) { | |
| 4585 DCHECK(IsEnabled(NEON)); | |
| 4586 // Qd = vpmax(Qn, Qm) SIMD integer pairwise MAX. | |
| 4587 // Instruction details available in ARM DDI 0406C.b, A8-986. | |
| 4588 emit(EncodeNeonPairwiseOp(VPMAX, dt, dst, src1, src2)); | |
| 4589 } | |
| 4590 | |
| 4532 void Assembler::vtst(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, | 4591 void Assembler::vtst(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, |
| 4533 QwNeonRegister src2) { | 4592 QwNeonRegister src2) { |
| 4534 DCHECK(IsEnabled(NEON)); | 4593 DCHECK(IsEnabled(NEON)); |
| 4535 // Qd = vtst(Qn, Qm) SIMD test integer operands. | 4594 // Qd = vtst(Qn, Qm) SIMD test integer operands. |
| 4536 // Instruction details available in ARM DDI 0406C.b, A8-1098. | 4595 // Instruction details available in ARM DDI 0406C.b, A8-1098. |
| 4537 emit(EncodeNeonBinOp(VTST, size, dst, src1, src2)); | 4596 emit(EncodeNeonBinOp(VTST, size, dst, src1, src2)); |
| 4538 } | 4597 } |
| 4539 | 4598 |
| 4540 void Assembler::vceq(QwNeonRegister dst, QwNeonRegister src1, | 4599 void Assembler::vceq(QwNeonRegister dst, QwNeonRegister src1, |
| 4541 QwNeonRegister src2) { | 4600 QwNeonRegister src2) { |
| (...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5225 DCHECK(is_uint12(offset)); | 5284 DCHECK(is_uint12(offset)); |
| 5226 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 5285 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
| 5227 } | 5286 } |
| 5228 } | 5287 } |
| 5229 | 5288 |
| 5230 | 5289 |
| 5231 } // namespace internal | 5290 } // namespace internal |
| 5232 } // namespace v8 | 5291 } // namespace v8 |
| 5233 | 5292 |
| 5234 #endif // V8_TARGET_ARCH_ARM | 5293 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |