| 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 |