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 4105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4116 } | 4116 } |
4117 | 4117 |
4118 void Assembler::vcvt_u32_f32(const QwNeonRegister dst, | 4118 void Assembler::vcvt_u32_f32(const QwNeonRegister dst, |
4119 const QwNeonRegister src) { | 4119 const QwNeonRegister src) { |
4120 DCHECK(IsEnabled(NEON)); | 4120 DCHECK(IsEnabled(NEON)); |
4121 DCHECK(VfpRegisterIsAvailable(dst)); | 4121 DCHECK(VfpRegisterIsAvailable(dst)); |
4122 DCHECK(VfpRegisterIsAvailable(src)); | 4122 DCHECK(VfpRegisterIsAvailable(src)); |
4123 emit(EncodeNeonVCVT(U32, dst, F32, src)); | 4123 emit(EncodeNeonVCVT(U32, dst, F32, src)); |
4124 } | 4124 } |
4125 | 4125 |
4126 // op is instr->Bits(11, 7). | 4126 enum UnaryOp { VABS, VABSF, VNEG, VNEGF }; |
4127 static Instr EncodeNeonUnaryOp(int op, bool is_float, NeonSize size, | 4127 |
4128 const QwNeonRegister dst, | 4128 static Instr EncodeNeonUnaryOp(UnaryOp op, NeonSize size, QwNeonRegister dst, |
4129 const QwNeonRegister src) { | 4129 QwNeonRegister src) { |
4130 DCHECK_IMPLIES(is_float, size == Neon32); | 4130 int op_encoding = 0; |
| 4131 switch (op) { |
| 4132 case VABS: |
| 4133 op_encoding = 0x6 * B7; |
| 4134 break; |
| 4135 case VABSF: |
| 4136 DCHECK_EQ(Neon32, size); |
| 4137 op_encoding = 0x6 * B7 | B10; |
| 4138 break; |
| 4139 case VNEG: |
| 4140 op_encoding = 0x7 * B7; |
| 4141 break; |
| 4142 case VNEGF: |
| 4143 DCHECK_EQ(Neon32, size); |
| 4144 op_encoding = 0x7 * B7 | B10; |
| 4145 break; |
| 4146 default: |
| 4147 UNREACHABLE(); |
| 4148 break; |
| 4149 } |
4131 int vd, d; | 4150 int vd, d; |
4132 dst.split_code(&vd, &d); | 4151 dst.split_code(&vd, &d); |
4133 int vm, m; | 4152 int vm, m; |
4134 src.split_code(&vm, &m); | 4153 src.split_code(&vm, &m); |
4135 int F = is_float ? 1 : 0; | 4154 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | size * B18 | B16 | vd * B12 | B6 | |
4136 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | size * B18 | B16 | vd * B12 | | 4155 m * B5 | vm | op_encoding; |
4137 F * B10 | B8 | op * B7 | B6 | m * B5 | vm; | |
4138 } | 4156 } |
4139 | 4157 |
4140 void Assembler::vabs(const QwNeonRegister dst, const QwNeonRegister src) { | 4158 void Assembler::vabs(const QwNeonRegister dst, const QwNeonRegister src) { |
4141 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point absolute value. | 4159 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point absolute value. |
4142 // Instruction details available in ARM DDI 0406C.b, A8.8.824. | 4160 // Instruction details available in ARM DDI 0406C.b, A8.8.824. |
4143 DCHECK(IsEnabled(NEON)); | 4161 DCHECK(IsEnabled(NEON)); |
4144 emit(EncodeNeonUnaryOp(0x6, true, Neon32, dst, src)); | 4162 emit(EncodeNeonUnaryOp(VABSF, Neon32, dst, src)); |
4145 } | 4163 } |
4146 | 4164 |
4147 void Assembler::vabs(NeonSize size, const QwNeonRegister dst, | 4165 void Assembler::vabs(NeonSize size, const QwNeonRegister dst, |
4148 const QwNeonRegister src) { | 4166 const QwNeonRegister src) { |
4149 // Qd = vabs.s<size>(Qn, Qm) SIMD integer absolute value. | 4167 // Qd = vabs.s<size>(Qn, Qm) SIMD integer absolute value. |
4150 // Instruction details available in ARM DDI 0406C.b, A8.8.824. | 4168 // Instruction details available in ARM DDI 0406C.b, A8.8.824. |
4151 DCHECK(IsEnabled(NEON)); | 4169 DCHECK(IsEnabled(NEON)); |
4152 emit(EncodeNeonUnaryOp(0x6, false, size, dst, src)); | 4170 emit(EncodeNeonUnaryOp(VABS, size, dst, src)); |
4153 } | 4171 } |
4154 | 4172 |
4155 void Assembler::vneg(const QwNeonRegister dst, const QwNeonRegister src) { | 4173 void Assembler::vneg(const QwNeonRegister dst, const QwNeonRegister src) { |
4156 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point negate. | 4174 // Qd = vabs.f<size>(Qn, Qm) SIMD floating point negate. |
4157 // Instruction details available in ARM DDI 0406C.b, A8.8.968. | 4175 // Instruction details available in ARM DDI 0406C.b, A8.8.968. |
4158 DCHECK(IsEnabled(NEON)); | 4176 DCHECK(IsEnabled(NEON)); |
4159 emit(EncodeNeonUnaryOp(0x7, true, Neon32, dst, src)); | 4177 emit(EncodeNeonUnaryOp(VNEGF, Neon32, dst, src)); |
4160 } | 4178 } |
4161 | 4179 |
4162 void Assembler::vneg(NeonSize size, const QwNeonRegister dst, | 4180 void Assembler::vneg(NeonSize size, const QwNeonRegister dst, |
4163 const QwNeonRegister src) { | 4181 const QwNeonRegister src) { |
4164 // Qd = vabs.s<size>(Qn, Qm) SIMD integer negate. | 4182 // Qd = vabs.s<size>(Qn, Qm) SIMD integer negate. |
4165 // Instruction details available in ARM DDI 0406C.b, A8.8.968. | 4183 // Instruction details available in ARM DDI 0406C.b, A8.8.968. |
4166 DCHECK(IsEnabled(NEON)); | 4184 DCHECK(IsEnabled(NEON)); |
4167 emit(EncodeNeonUnaryOp(0x7, false, size, dst, src)); | 4185 emit(EncodeNeonUnaryOp(VNEG, size, dst, src)); |
4168 } | 4186 } |
4169 | 4187 |
4170 void Assembler::veor(DwVfpRegister dst, DwVfpRegister src1, | 4188 void Assembler::veor(DwVfpRegister dst, DwVfpRegister src1, |
4171 DwVfpRegister src2) { | 4189 DwVfpRegister src2) { |
4172 // Dd = veor(Dn, Dm) 64 bit integer exclusive OR. | 4190 // Dd = veor(Dn, Dm) 64 bit integer exclusive OR. |
4173 // Instruction details available in ARM DDI 0406C.b, A8.8.888. | 4191 // Instruction details available in ARM DDI 0406C.b, A8.8.888. |
4174 DCHECK(IsEnabled(NEON)); | 4192 DCHECK(IsEnabled(NEON)); |
4175 int vd, d; | 4193 int vd, d; |
4176 dst.split_code(&vd, &d); | 4194 dst.split_code(&vd, &d); |
4177 int vn, n; | 4195 int vn, n; |
4178 src1.split_code(&vn, &n); | 4196 src1.split_code(&vn, &n); |
4179 int vm, m; | 4197 int vm, m; |
4180 src2.split_code(&vm, &m); | 4198 src2.split_code(&vm, &m); |
4181 emit(0x1E6U * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | m * B5 | | 4199 emit(0x1E6U * B23 | d * B22 | vn * B16 | vd * B12 | B8 | n * B7 | m * B5 | |
4182 B4 | vm); | 4200 B4 | vm); |
4183 } | 4201 } |
4184 | 4202 |
4185 enum BinaryBitwiseOp { VAND, VBIC, VBIF, VBIT, VBSL, VEOR, VORR, VORN }; | 4203 enum BinaryBitwiseOp { VAND, VBIC, VBIF, VBIT, VBSL, VEOR, VORR, VORN }; |
4186 | 4204 |
4187 static Instr EncodeNeonBinaryBitwiseOp(BinaryBitwiseOp op, | 4205 static Instr EncodeNeonBinaryBitwiseOp(BinaryBitwiseOp op, QwNeonRegister dst, |
4188 const QwNeonRegister dst, | 4206 QwNeonRegister src1, |
4189 const QwNeonRegister src1, | 4207 QwNeonRegister src2) { |
4190 const QwNeonRegister src2) { | |
4191 int op_encoding = 0; | 4208 int op_encoding = 0; |
4192 switch (op) { | 4209 switch (op) { |
4193 case VBIC: | 4210 case VBIC: |
4194 op_encoding = 0x1 * B20; | 4211 op_encoding = 0x1 * B20; |
4195 break; | 4212 break; |
4196 case VBIF: | 4213 case VBIF: |
4197 op_encoding = B24 | 0x3 * B20; | 4214 op_encoding = B24 | 0x3 * B20; |
4198 break; | 4215 break; |
4199 case VBIT: | 4216 case VBIT: |
4200 op_encoding = B24 | 0x2 * B20; | 4217 op_encoding = B24 | 0x2 * B20; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4329 VMUL, | 4346 VMUL, |
4330 VMIN, | 4347 VMIN, |
4331 VMAX, | 4348 VMAX, |
4332 VTST, | 4349 VTST, |
4333 VCEQ, | 4350 VCEQ, |
4334 VCGE, | 4351 VCGE, |
4335 VCGT | 4352 VCGT |
4336 }; | 4353 }; |
4337 | 4354 |
4338 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonDataType dt, | 4355 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonDataType dt, |
4339 const QwNeonRegister dst, | 4356 QwNeonRegister dst, QwNeonRegister src1, |
4340 const QwNeonRegister src1, | 4357 QwNeonRegister src2) { |
4341 const QwNeonRegister src2) { | |
4342 int op_encoding = 0; | 4358 int op_encoding = 0; |
4343 switch (op) { | 4359 switch (op) { |
4344 case VADD: | 4360 case VADD: |
4345 op_encoding = 0x8 * B8; | 4361 op_encoding = 0x8 * B8; |
4346 break; | 4362 break; |
4347 case VQADD: | 4363 case VQADD: |
4348 op_encoding = B4; | 4364 op_encoding = B4; |
4349 break; | 4365 break; |
4350 case VSUB: | 4366 case VSUB: |
4351 op_encoding = B24 | 0x8 * B8; | 4367 op_encoding = B24 | 0x8 * B8; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4383 int vn, n; | 4399 int vn, n; |
4384 src1.split_code(&vn, &n); | 4400 src1.split_code(&vn, &n); |
4385 int vm, m; | 4401 int vm, m; |
4386 src2.split_code(&vm, &m); | 4402 src2.split_code(&vm, &m); |
4387 int size = NeonSz(dt); | 4403 int size = NeonSz(dt); |
4388 int u = NeonU(dt); | 4404 int u = NeonU(dt); |
4389 return 0x1E4U * B23 | u * B24 | d * B22 | size * B20 | vn * B16 | vd * B12 | | 4405 return 0x1E4U * B23 | u * B24 | d * B22 | size * B20 | vn * B16 | vd * B12 | |
4390 n * B7 | B6 | m * B5 | vm | op_encoding; | 4406 n * B7 | B6 | m * B5 | vm | op_encoding; |
4391 } | 4407 } |
4392 | 4408 |
4393 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonSize size, | 4409 static Instr EncodeNeonBinOp(IntegerBinOp op, NeonSize size, QwNeonRegister dst, |
4394 const QwNeonRegister dst, | 4410 QwNeonRegister src1, QwNeonRegister src2) { |
4395 const QwNeonRegister src1, | |
4396 const QwNeonRegister src2) { | |
4397 // Map NeonSize values to the signed values in NeonDataType, so the U bit | 4411 // Map NeonSize values to the signed values in NeonDataType, so the U bit |
4398 // will be 0. | 4412 // will be 0. |
4399 return EncodeNeonBinOp(op, static_cast<NeonDataType>(size), dst, src1, src2); | 4413 return EncodeNeonBinOp(op, static_cast<NeonDataType>(size), dst, src1, src2); |
4400 } | 4414 } |
4401 | 4415 |
4402 void Assembler::vadd(QwNeonRegister dst, QwNeonRegister src1, | 4416 void Assembler::vadd(QwNeonRegister dst, QwNeonRegister src1, |
4403 QwNeonRegister src2) { | 4417 QwNeonRegister src2) { |
4404 DCHECK(IsEnabled(NEON)); | 4418 DCHECK(IsEnabled(NEON)); |
4405 // Qd = vadd(Qn, Qm) SIMD floating point addition. | 4419 // Qd = vadd(Qn, Qm) SIMD floating point addition. |
4406 // Instruction details available in ARM DDI 0406C.b, A8-830. | 4420 // Instruction details available in ARM DDI 0406C.b, A8-830. |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4571 } | 4585 } |
4572 | 4586 |
4573 void Assembler::vrsqrts(QwNeonRegister dst, QwNeonRegister src1, | 4587 void Assembler::vrsqrts(QwNeonRegister dst, QwNeonRegister src1, |
4574 QwNeonRegister src2) { | 4588 QwNeonRegister src2) { |
4575 DCHECK(IsEnabled(NEON)); | 4589 DCHECK(IsEnabled(NEON)); |
4576 // Qd = vrsqrts(Qn, Qm) SIMD reciprocal square root refinement step. | 4590 // Qd = vrsqrts(Qn, Qm) SIMD reciprocal square root refinement step. |
4577 // Instruction details available in ARM DDI 0406C.b, A8-1040. | 4591 // Instruction details available in ARM DDI 0406C.b, A8-1040. |
4578 emit(EncodeNeonBinOp(VRSQRTS, dst, src1, src2)); | 4592 emit(EncodeNeonBinOp(VRSQRTS, dst, src1, src2)); |
4579 } | 4593 } |
4580 | 4594 |
| 4595 enum PairwiseOp { VPMIN, VPMAX }; |
| 4596 |
| 4597 static Instr EncodeNeonPairwiseOp(PairwiseOp op, NeonDataType dt, |
| 4598 DwVfpRegister dst, DwVfpRegister src1, |
| 4599 DwVfpRegister src2) { |
| 4600 int op_encoding = 0; |
| 4601 switch (op) { |
| 4602 case VPMIN: |
| 4603 op_encoding = 0xA * B8 | B4; |
| 4604 break; |
| 4605 case VPMAX: |
| 4606 op_encoding = 0xA * B8; |
| 4607 break; |
| 4608 default: |
| 4609 UNREACHABLE(); |
| 4610 break; |
| 4611 } |
| 4612 int vd, d; |
| 4613 dst.split_code(&vd, &d); |
| 4614 int vn, n; |
| 4615 src1.split_code(&vn, &n); |
| 4616 int vm, m; |
| 4617 src2.split_code(&vm, &m); |
| 4618 int size = NeonSz(dt); |
| 4619 int u = NeonU(dt); |
| 4620 return 0x1E4U * B23 | u * B24 | d * B22 | size * B20 | vn * B16 | vd * B12 | |
| 4621 n * B7 | m * B5 | vm | op_encoding; |
| 4622 } |
| 4623 |
| 4624 void Assembler::vpmin(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1, |
| 4625 DwVfpRegister src2) { |
| 4626 DCHECK(IsEnabled(NEON)); |
| 4627 // Dd = vpmin(Dn, Dm) SIMD integer pairwise MIN. |
| 4628 // Instruction details available in ARM DDI 0406C.b, A8-986. |
| 4629 emit(EncodeNeonPairwiseOp(VPMIN, dt, dst, src1, src2)); |
| 4630 } |
| 4631 |
| 4632 void Assembler::vpmax(NeonDataType dt, DwVfpRegister dst, DwVfpRegister src1, |
| 4633 DwVfpRegister src2) { |
| 4634 DCHECK(IsEnabled(NEON)); |
| 4635 // Dd = vpmax(Dn, Dm) SIMD integer pairwise MAX. |
| 4636 // Instruction details available in ARM DDI 0406C.b, A8-986. |
| 4637 emit(EncodeNeonPairwiseOp(VPMAX, dt, dst, src1, src2)); |
| 4638 } |
| 4639 |
4581 void Assembler::vtst(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, | 4640 void Assembler::vtst(NeonSize size, QwNeonRegister dst, QwNeonRegister src1, |
4582 QwNeonRegister src2) { | 4641 QwNeonRegister src2) { |
4583 DCHECK(IsEnabled(NEON)); | 4642 DCHECK(IsEnabled(NEON)); |
4584 // Qd = vtst(Qn, Qm) SIMD test integer operands. | 4643 // Qd = vtst(Qn, Qm) SIMD test integer operands. |
4585 // Instruction details available in ARM DDI 0406C.b, A8-1098. | 4644 // Instruction details available in ARM DDI 0406C.b, A8-1098. |
4586 emit(EncodeNeonBinOp(VTST, size, dst, src1, src2)); | 4645 emit(EncodeNeonBinOp(VTST, size, dst, src1, src2)); |
4587 } | 4646 } |
4588 | 4647 |
4589 void Assembler::vceq(QwNeonRegister dst, QwNeonRegister src1, | 4648 void Assembler::vceq(QwNeonRegister dst, QwNeonRegister src1, |
4590 QwNeonRegister src2) { | 4649 QwNeonRegister src2) { |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5275 DCHECK(is_uint12(offset)); | 5334 DCHECK(is_uint12(offset)); |
5276 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); | 5335 instr_at_put(pc, SetLdrRegisterImmediateOffset(instr, offset)); |
5277 } | 5336 } |
5278 } | 5337 } |
5279 | 5338 |
5280 | 5339 |
5281 } // namespace internal | 5340 } // namespace internal |
5282 } // namespace v8 | 5341 } // namespace v8 |
5283 | 5342 |
5284 #endif // V8_TARGET_ARCH_ARM | 5343 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |