| 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 4066 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4077 | 4077 |
| 4078 void Assembler::vcvt_u32_f32(QwNeonRegister dst, QwNeonRegister src) { | 4078 void Assembler::vcvt_u32_f32(QwNeonRegister dst, QwNeonRegister src) { |
| 4079 DCHECK(IsEnabled(NEON)); | 4079 DCHECK(IsEnabled(NEON)); |
| 4080 DCHECK(VfpRegisterIsAvailable(dst)); | 4080 DCHECK(VfpRegisterIsAvailable(dst)); |
| 4081 DCHECK(VfpRegisterIsAvailable(src)); | 4081 DCHECK(VfpRegisterIsAvailable(src)); |
| 4082 emit(EncodeNeonVCVT(U32, dst, F32, src)); | 4082 emit(EncodeNeonVCVT(U32, dst, F32, src)); |
| 4083 } | 4083 } |
| 4084 | 4084 |
| 4085 enum NeonRegType { NEON_D, NEON_Q }; | 4085 enum NeonRegType { NEON_D, NEON_Q }; |
| 4086 | 4086 |
| 4087 void NeonSplitCode(NeonRegType type, int code, int* vm, int* m, int* encoding) { | |
| 4088 if (type == NEON_D) { | |
| 4089 DwVfpRegister::split_code(code, vm, m); | |
| 4090 } else { | |
| 4091 DCHECK_EQ(type, NEON_Q); | |
| 4092 QwNeonRegister::split_code(code, vm, m); | |
| 4093 *encoding |= B6; | |
| 4094 } | |
| 4095 } | |
| 4096 | |
| 4097 enum UnaryOp { VMVN, VSWP, VABS, VABSF, VNEG, VNEGF }; | 4087 enum UnaryOp { VMVN, VSWP, VABS, VABSF, VNEG, VNEGF }; |
| 4098 | 4088 |
| 4099 static Instr EncodeNeonUnaryOp(UnaryOp op, NeonRegType reg_type, NeonSize size, | 4089 static Instr EncodeNeonUnaryOp(UnaryOp op, NeonRegType reg_type, NeonSize size, |
| 4100 int dst_code, int src_code) { | 4090 int dst_code, int src_code) { |
| 4101 int op_encoding = 0; | 4091 int op_encoding = 0; |
| 4102 switch (op) { | 4092 switch (op) { |
| 4103 case VMVN: | 4093 case VMVN: |
| 4104 DCHECK_EQ(Neon8, size); // size == 0 for vmvn | 4094 DCHECK_EQ(Neon8, size); // size == 0 for vmvn |
| 4105 op_encoding = B10 | 0x3 * B7; | 4095 op_encoding = B10 | 0x3 * B7; |
| 4106 break; | 4096 break; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 4119 op_encoding = B16 | 0x7 * B7; | 4109 op_encoding = B16 | 0x7 * B7; |
| 4120 break; | 4110 break; |
| 4121 case VNEGF: | 4111 case VNEGF: |
| 4122 DCHECK_EQ(Neon32, size); | 4112 DCHECK_EQ(Neon32, size); |
| 4123 op_encoding = B16 | B10 | 0x7 * B7; | 4113 op_encoding = B16 | B10 | 0x7 * B7; |
| 4124 break; | 4114 break; |
| 4125 default: | 4115 default: |
| 4126 UNREACHABLE(); | 4116 UNREACHABLE(); |
| 4127 break; | 4117 break; |
| 4128 } | 4118 } |
| 4129 int vd, d; | 4119 int vd, d, vm, m; |
| 4130 NeonSplitCode(reg_type, dst_code, &vd, &d, &op_encoding); | 4120 if (reg_type == NEON_Q) { |
| 4131 int vm, m; | 4121 op_encoding |= B6; |
| 4132 NeonSplitCode(reg_type, src_code, &vm, &m, &op_encoding); | 4122 QwNeonRegister::split_code(dst_code, &vd, &d); |
| 4133 | 4123 QwNeonRegister::split_code(src_code, &vm, &m); |
| 4124 } else { |
| 4125 DCHECK_EQ(reg_type, NEON_D); |
| 4126 DwVfpRegister::split_code(dst_code, &vd, &d); |
| 4127 DwVfpRegister::split_code(src_code, &vm, &m); |
| 4128 } |
| 4134 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | size * B18 | vd * B12 | m * B5 | | 4129 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | size * B18 | vd * B12 | m * B5 | |
| 4135 vm | op_encoding; | 4130 vm | op_encoding; |
| 4136 } | 4131 } |
| 4137 | 4132 |
| 4138 void Assembler::vmvn(QwNeonRegister dst, QwNeonRegister src) { | 4133 void Assembler::vmvn(QwNeonRegister dst, QwNeonRegister src) { |
| 4139 // Qd = vmvn(Qn, Qm) SIMD bitwise negate. | 4134 // Qd = vmvn(Qn, Qm) SIMD bitwise negate. |
| 4140 // Instruction details available in ARM DDI 0406C.b, A8-966. | 4135 // Instruction details available in ARM DDI 0406C.b, A8-966. |
| 4141 DCHECK(IsEnabled(NEON)); | 4136 DCHECK(IsEnabled(NEON)); |
| 4142 emit(EncodeNeonUnaryOp(VMVN, NEON_Q, Neon8, dst.code(), src.code())); | 4137 emit(EncodeNeonUnaryOp(VMVN, NEON_Q, Neon8, dst.code(), src.code())); |
| 4143 } | 4138 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4213 case VORN: | 4208 case VORN: |
| 4214 op_encoding = 0x3 * B20; | 4209 op_encoding = 0x3 * B20; |
| 4215 break; | 4210 break; |
| 4216 case VAND: | 4211 case VAND: |
| 4217 // op_encoding is 0. | 4212 // op_encoding is 0. |
| 4218 break; | 4213 break; |
| 4219 default: | 4214 default: |
| 4220 UNREACHABLE(); | 4215 UNREACHABLE(); |
| 4221 break; | 4216 break; |
| 4222 } | 4217 } |
| 4223 int vd, d; | 4218 int vd, d, vn, n, vm, m; |
| 4224 NeonSplitCode(reg_type, dst_code, &vd, &d, &op_encoding); | 4219 if (reg_type == NEON_Q) { |
| 4225 int vn, n; | 4220 op_encoding |= B6; |
| 4226 NeonSplitCode(reg_type, src_code1, &vn, &n, &op_encoding); | 4221 QwNeonRegister::split_code(dst_code, &vd, &d); |
| 4227 int vm, m; | 4222 QwNeonRegister::split_code(src_code1, &vn, &n); |
| 4228 NeonSplitCode(reg_type, src_code2, &vm, &m, &op_encoding); | 4223 QwNeonRegister::split_code(src_code2, &vm, &m); |
| 4229 | 4224 } else { |
| 4225 DCHECK_EQ(reg_type, NEON_D); |
| 4226 DwVfpRegister::split_code(dst_code, &vd, &d); |
| 4227 DwVfpRegister::split_code(src_code1, &vn, &n); |
| 4228 DwVfpRegister::split_code(src_code2, &vm, &m); |
| 4229 } |
| 4230 return 0x1E4U * B23 | op_encoding | d * B22 | vn * B16 | vd * B12 | B8 | | 4230 return 0x1E4U * B23 | op_encoding | d * B22 | vn * B16 | vd * B12 | B8 | |
| 4231 n * B7 | m * B5 | B4 | vm; | 4231 n * B7 | m * B5 | B4 | vm; |
| 4232 } | 4232 } |
| 4233 | 4233 |
| 4234 void Assembler::vand(QwNeonRegister dst, QwNeonRegister src1, | 4234 void Assembler::vand(QwNeonRegister dst, QwNeonRegister src1, |
| 4235 QwNeonRegister src2) { | 4235 QwNeonRegister src2) { |
| 4236 // Qd = vand(Qn, Qm) SIMD AND. | 4236 // Qd = vand(Qn, Qm) SIMD AND. |
| 4237 // Instruction details available in ARM DDI 0406C.b, A8.8.836. | 4237 // Instruction details available in ARM DDI 0406C.b, A8.8.836. |
| 4238 DCHECK(IsEnabled(NEON)); | 4238 DCHECK(IsEnabled(NEON)); |
| 4239 emit(EncodeNeonBinaryBitwiseOp(VAND, NEON_Q, dst.code(), src1.code(), | 4239 emit(EncodeNeonBinaryBitwiseOp(VAND, NEON_Q, dst.code(), src1.code(), |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4703 src1.split_code(&vn, &n); | 4703 src1.split_code(&vn, &n); |
| 4704 int vm, m; | 4704 int vm, m; |
| 4705 src2.split_code(&vm, &m); | 4705 src2.split_code(&vm, &m); |
| 4706 DCHECK_GT(16, bytes); | 4706 DCHECK_GT(16, bytes); |
| 4707 emit(0x1E5U * B23 | d * B22 | 0x3 * B20 | vn * B16 | vd * B12 | bytes * B8 | | 4707 emit(0x1E5U * B23 | d * B22 | 0x3 * B20 | vn * B16 | vd * B12 | bytes * B8 | |
| 4708 n * B7 | B6 | m * B5 | vm); | 4708 n * B7 | B6 | m * B5 | vm); |
| 4709 } | 4709 } |
| 4710 | 4710 |
| 4711 enum NeonSizedOp { VZIP, VUZP, VREV16, VREV32, VREV64, VTRN }; | 4711 enum NeonSizedOp { VZIP, VUZP, VREV16, VREV32, VREV64, VTRN }; |
| 4712 | 4712 |
| 4713 static Instr EncodeNeonSizedOp(NeonSizedOp op, NeonRegType reg_type, | 4713 static Instr EncodeNeonSizedOp(NeonSizedOp op, NeonSize size, |
| 4714 NeonSize size, int dst_code, int src_code) { | 4714 QwNeonRegister dst, QwNeonRegister src) { |
| 4715 int op_encoding = 0; | 4715 int op_encoding = 0; |
| 4716 switch (op) { | 4716 switch (op) { |
| 4717 case VZIP: | 4717 case VZIP: |
| 4718 op_encoding = 0x2 * B16 | 0x3 * B7; | 4718 op_encoding = 0x2 * B16 | 0x3 * B7; |
| 4719 break; | 4719 break; |
| 4720 case VUZP: | 4720 case VUZP: |
| 4721 op_encoding = 0x2 * B16 | 0x2 * B7; | 4721 op_encoding = 0x2 * B16 | 0x2 * B7; |
| 4722 break; | 4722 break; |
| 4723 case VREV16: | 4723 case VREV16: |
| 4724 op_encoding = 0x2 * B7; | 4724 op_encoding = 0x2 * B7; |
| 4725 break; | 4725 break; |
| 4726 case VREV32: | 4726 case VREV32: |
| 4727 op_encoding = 0x1 * B7; | 4727 op_encoding = 0x1 * B7; |
| 4728 break; | 4728 break; |
| 4729 case VREV64: | 4729 case VREV64: |
| 4730 // op_encoding is 0; | 4730 // op_encoding is 0; |
| 4731 break; | 4731 break; |
| 4732 case VTRN: | 4732 case VTRN: |
| 4733 op_encoding = 0x2 * B16 | B7; | 4733 op_encoding = 0x2 * B16 | B7; |
| 4734 break; | 4734 break; |
| 4735 default: | 4735 default: |
| 4736 UNREACHABLE(); | 4736 UNREACHABLE(); |
| 4737 break; | 4737 break; |
| 4738 } | 4738 } |
| 4739 int vd, d; | 4739 int vd, d; |
| 4740 NeonSplitCode(reg_type, dst_code, &vd, &d, &op_encoding); | 4740 dst.split_code(&vd, &d); |
| 4741 int vm, m; | 4741 int vm, m; |
| 4742 NeonSplitCode(reg_type, src_code, &vm, &m, &op_encoding); | 4742 src.split_code(&vm, &m); |
| 4743 | |
| 4744 int sz = static_cast<int>(size); | 4743 int sz = static_cast<int>(size); |
| 4745 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | sz * B18 | vd * B12 | m * B5 | | 4744 return 0x1E7U * B23 | d * B22 | 0x3 * B20 | sz * B18 | vd * B12 | B6 | |
| 4746 vm | op_encoding; | 4745 m * B5 | vm | op_encoding; |
| 4747 } | |
| 4748 | |
| 4749 void Assembler::vzip(NeonSize size, DwVfpRegister src1, DwVfpRegister src2) { | |
| 4750 DCHECK(IsEnabled(NEON)); | |
| 4751 // vzip.<size>(Dn, Dm) SIMD zip (interleave). | |
| 4752 // Instruction details available in ARM DDI 0406C.b, A8-1102. | |
| 4753 emit(EncodeNeonSizedOp(VZIP, NEON_D, size, src1.code(), src2.code())); | |
| 4754 } | 4746 } |
| 4755 | 4747 |
| 4756 void Assembler::vzip(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { | 4748 void Assembler::vzip(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { |
| 4757 DCHECK(IsEnabled(NEON)); | 4749 DCHECK(IsEnabled(NEON)); |
| 4758 // vzip.<size>(Qn, Qm) SIMD zip (interleave). | 4750 // Qd = vzip.<size>(Qn, Qm) SIMD zip (interleave). |
| 4759 // Instruction details available in ARM DDI 0406C.b, A8-1102. | 4751 // Instruction details available in ARM DDI 0406C.b, A8-1102. |
| 4760 emit(EncodeNeonSizedOp(VZIP, NEON_Q, size, src1.code(), src2.code())); | 4752 emit(EncodeNeonSizedOp(VZIP, size, src1, src2)); |
| 4761 } | |
| 4762 | |
| 4763 void Assembler::vuzp(NeonSize size, DwVfpRegister src1, DwVfpRegister src2) { | |
| 4764 DCHECK(IsEnabled(NEON)); | |
| 4765 // vuzp.<size>(Dn, Dm) SIMD un-zip (de-interleave). | |
| 4766 // Instruction details available in ARM DDI 0406C.b, A8-1100. | |
| 4767 emit(EncodeNeonSizedOp(VUZP, NEON_D, size, src1.code(), src2.code())); | |
| 4768 } | 4753 } |
| 4769 | 4754 |
| 4770 void Assembler::vuzp(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { | 4755 void Assembler::vuzp(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { |
| 4771 DCHECK(IsEnabled(NEON)); | 4756 DCHECK(IsEnabled(NEON)); |
| 4772 // vuzp.<size>(Qn, Qm) SIMD un-zip (de-interleave). | 4757 // Qd = vuzp.<size>(Qn, Qm) SIMD un-zip (de-interleave). |
| 4773 // Instruction details available in ARM DDI 0406C.b, A8-1100. | 4758 // Instruction details available in ARM DDI 0406C.b, A8-1100. |
| 4774 emit(EncodeNeonSizedOp(VUZP, NEON_Q, size, src1.code(), src2.code())); | 4759 emit(EncodeNeonSizedOp(VUZP, size, src1, src2)); |
| 4775 } | 4760 } |
| 4776 | 4761 |
| 4777 void Assembler::vrev16(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { | 4762 void Assembler::vrev16(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { |
| 4778 DCHECK(IsEnabled(NEON)); | 4763 DCHECK(IsEnabled(NEON)); |
| 4779 // Qd = vrev16.<size>(Qm) SIMD element reverse. | 4764 // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| 4780 // Instruction details available in ARM DDI 0406C.b, A8-1028. | 4765 // Instruction details available in ARM DDI 0406C.b, A8-1028. |
| 4781 emit(EncodeNeonSizedOp(VREV16, NEON_Q, size, dst.code(), src.code())); | 4766 emit(EncodeNeonSizedOp(VREV16, size, dst, src)); |
| 4782 } | 4767 } |
| 4783 | 4768 |
| 4784 void Assembler::vrev32(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { | 4769 void Assembler::vrev32(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { |
| 4785 DCHECK(IsEnabled(NEON)); | 4770 DCHECK(IsEnabled(NEON)); |
| 4786 // Qd = vrev32.<size>(Qm) SIMD element reverse. | 4771 // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| 4787 // Instruction details available in ARM DDI 0406C.b, A8-1028. | 4772 // Instruction details available in ARM DDI 0406C.b, A8-1028. |
| 4788 emit(EncodeNeonSizedOp(VREV32, NEON_Q, size, dst.code(), src.code())); | 4773 emit(EncodeNeonSizedOp(VREV32, size, dst, src)); |
| 4789 } | 4774 } |
| 4790 | 4775 |
| 4791 void Assembler::vrev64(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { | 4776 void Assembler::vrev64(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { |
| 4792 DCHECK(IsEnabled(NEON)); | 4777 DCHECK(IsEnabled(NEON)); |
| 4793 // Qd = vrev64.<size>(Qm) SIMD element reverse. | 4778 // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| 4794 // Instruction details available in ARM DDI 0406C.b, A8-1028. | 4779 // Instruction details available in ARM DDI 0406C.b, A8-1028. |
| 4795 emit(EncodeNeonSizedOp(VREV64, NEON_Q, size, dst.code(), src.code())); | 4780 emit(EncodeNeonSizedOp(VREV64, size, dst, src)); |
| 4796 } | |
| 4797 | |
| 4798 void Assembler::vtrn(NeonSize size, DwVfpRegister src1, DwVfpRegister src2) { | |
| 4799 DCHECK(IsEnabled(NEON)); | |
| 4800 // vtrn.<size>(Dn, Dm) SIMD element transpose. | |
| 4801 // Instruction details available in ARM DDI 0406C.b, A8-1096. | |
| 4802 emit(EncodeNeonSizedOp(VTRN, NEON_D, size, src1.code(), src2.code())); | |
| 4803 } | 4781 } |
| 4804 | 4782 |
| 4805 void Assembler::vtrn(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { | 4783 void Assembler::vtrn(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { |
| 4806 DCHECK(IsEnabled(NEON)); | 4784 DCHECK(IsEnabled(NEON)); |
| 4807 // vtrn.<size>(Qn, Qm) SIMD element transpose. | 4785 // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| 4808 // Instruction details available in ARM DDI 0406C.b, A8-1096. | 4786 // Instruction details available in ARM DDI 0406C.b, A8-1096. |
| 4809 emit(EncodeNeonSizedOp(VTRN, NEON_Q, size, src1.code(), src2.code())); | 4787 emit(EncodeNeonSizedOp(VTRN, size, src1, src2)); |
| 4810 } | 4788 } |
| 4811 | 4789 |
| 4812 // Encode NEON vtbl / vtbx instruction. | 4790 // Encode NEON vtbl / vtbx instruction. |
| 4813 static Instr EncodeNeonVTB(DwVfpRegister dst, const NeonListOperand& list, | 4791 static Instr EncodeNeonVTB(DwVfpRegister dst, const NeonListOperand& list, |
| 4814 DwVfpRegister index, bool vtbx) { | 4792 DwVfpRegister index, bool vtbx) { |
| 4815 // Dd = vtbl(table, Dm) SIMD vector permute, zero at out of range indices. | 4793 // Dd = vtbl(table, Dm) SIMD vector permute, zero at out of range indices. |
| 4816 // Instruction details available in ARM DDI 0406C.b, A8-1094. | 4794 // Instruction details available in ARM DDI 0406C.b, A8-1094. |
| 4817 // Dd = vtbx(table, Dm) SIMD vector permute, skip out of range indices. | 4795 // Dd = vtbx(table, Dm) SIMD vector permute, skip out of range indices. |
| 4818 // Instruction details available in ARM DDI 0406C.b, A8-1094. | 4796 // Instruction details available in ARM DDI 0406C.b, A8-1094. |
| 4819 int vd, d; | 4797 int vd, d; |
| (...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5409 } | 5387 } |
| 5410 | 5388 |
| 5411 void PatchingAssembler::FlushICache(Isolate* isolate) { | 5389 void PatchingAssembler::FlushICache(Isolate* isolate) { |
| 5412 Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap); | 5390 Assembler::FlushICache(isolate, buffer_, buffer_size_ - kGap); |
| 5413 } | 5391 } |
| 5414 | 5392 |
| 5415 } // namespace internal | 5393 } // namespace internal |
| 5416 } // namespace v8 | 5394 } // namespace v8 |
| 5417 | 5395 |
| 5418 #endif // V8_TARGET_ARCH_ARM | 5396 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |