Chromium Code Reviews| Index: src/arm/assembler-arm.cc |
| diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc |
| index eef0a7cf5e9297f0f8d3f6d72d2797e7dabc2157..2fca55520ea364029874d0d3b249e6a5b426ebcc 100644 |
| --- a/src/arm/assembler-arm.cc |
| +++ b/src/arm/assembler-arm.cc |
| @@ -4710,8 +4710,8 @@ void Assembler::vext(QwNeonRegister dst, QwNeonRegister src1, |
| enum NeonSizedOp { VZIP, VUZP, VREV16, VREV32, VREV64, VTRN }; |
| -static Instr EncodeNeonSizedOp(NeonSizedOp op, NeonSize size, |
| - QwNeonRegister dst, QwNeonRegister src) { |
| +static Instr EncodeNeonSizedOp(NeonSizedOp op, NeonRegType reg_type, |
| + NeonSize size, int dst_code, int src_code) { |
| int op_encoding = 0; |
| switch (op) { |
| case VZIP: |
| @@ -4736,55 +4736,82 @@ static Instr EncodeNeonSizedOp(NeonSizedOp op, NeonSize size, |
| UNREACHABLE(); |
| break; |
| } |
| - int vd, d; |
| - dst.split_code(&vd, &d); |
| - int vm, m; |
| - src.split_code(&vm, &m); |
| + int vd, d, vm, m; |
| + if (reg_type == NEON_Q) { |
|
martyn.capewell
2017/04/06 13:09:49
This idiom may become common if more D/Q operation
bbudge
2017/04/06 17:49:43
Done.
|
| + op_encoding |= B6; |
| + QwNeonRegister::split_code(dst_code, &vd, &d); |
| + QwNeonRegister::split_code(src_code, &vm, &m); |
| + } else { |
| + DCHECK_EQ(reg_type, NEON_D); |
| + DwVfpRegister::split_code(dst_code, &vd, &d); |
| + DwVfpRegister::split_code(src_code, &vm, &m); |
| + } |
| int sz = static_cast<int>(size); |
| - return 0x1E7U * B23 | d * B22 | 0x3 * B20 | sz * B18 | vd * B12 | B6 | |
| - m * B5 | vm | op_encoding; |
| + return 0x1E7U * B23 | d * B22 | 0x3 * B20 | sz * B18 | vd * B12 | m * B5 | |
| + vm | op_encoding; |
| +} |
| + |
| +void Assembler::vzip(NeonSize size, DwVfpRegister src1, DwVfpRegister src2) { |
| + DCHECK(IsEnabled(NEON)); |
| + // vzip.<size>(Dn, Dm) SIMD zip (interleave). |
| + // Instruction details available in ARM DDI 0406C.b, A8-1102. |
| + emit(EncodeNeonSizedOp(VZIP, NEON_D, size, src1.code(), src2.code())); |
| } |
| void Assembler::vzip(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { |
| DCHECK(IsEnabled(NEON)); |
| - // Qd = vzip.<size>(Qn, Qm) SIMD zip (interleave). |
| + // vzip.<size>(Qn, Qm) SIMD zip (interleave). |
| // Instruction details available in ARM DDI 0406C.b, A8-1102. |
| - emit(EncodeNeonSizedOp(VZIP, size, src1, src2)); |
| + emit(EncodeNeonSizedOp(VZIP, NEON_Q, size, src1.code(), src2.code())); |
| +} |
| + |
| +void Assembler::vuzp(NeonSize size, DwVfpRegister src1, DwVfpRegister src2) { |
| + DCHECK(IsEnabled(NEON)); |
| + // vuzp.<size>(Dn, Dm) SIMD un-zip (de-interleave). |
| + // Instruction details available in ARM DDI 0406C.b, A8-1100. |
| + emit(EncodeNeonSizedOp(VUZP, NEON_D, size, src1.code(), src2.code())); |
| } |
| void Assembler::vuzp(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { |
| DCHECK(IsEnabled(NEON)); |
| - // Qd = vuzp.<size>(Qn, Qm) SIMD un-zip (de-interleave). |
| + // vuzp.<size>(Qn, Qm) SIMD un-zip (de-interleave). |
| // Instruction details available in ARM DDI 0406C.b, A8-1100. |
| - emit(EncodeNeonSizedOp(VUZP, size, src1, src2)); |
| + emit(EncodeNeonSizedOp(VUZP, NEON_Q, size, src1.code(), src2.code())); |
| } |
| void Assembler::vrev16(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { |
| DCHECK(IsEnabled(NEON)); |
| - // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| + // Qd = vrev16.<size>(Qm) SIMD element reverse. |
| // Instruction details available in ARM DDI 0406C.b, A8-1028. |
| - emit(EncodeNeonSizedOp(VREV16, size, dst, src)); |
| + emit(EncodeNeonSizedOp(VREV16, NEON_Q, size, dst.code(), src.code())); |
| } |
| void Assembler::vrev32(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { |
| DCHECK(IsEnabled(NEON)); |
| - // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| + // Qd = vrev32.<size>(Qm) SIMD element reverse. |
| // Instruction details available in ARM DDI 0406C.b, A8-1028. |
| - emit(EncodeNeonSizedOp(VREV32, size, dst, src)); |
| + emit(EncodeNeonSizedOp(VREV32, NEON_Q, size, dst.code(), src.code())); |
| } |
| void Assembler::vrev64(NeonSize size, QwNeonRegister dst, QwNeonRegister src) { |
| DCHECK(IsEnabled(NEON)); |
| - // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| + // Qd = vrev64.<size>(Qm) SIMD element reverse. |
| // Instruction details available in ARM DDI 0406C.b, A8-1028. |
| - emit(EncodeNeonSizedOp(VREV64, size, dst, src)); |
| + emit(EncodeNeonSizedOp(VREV64, NEON_Q, size, dst.code(), src.code())); |
| +} |
| + |
| +void Assembler::vtrn(NeonSize size, DwVfpRegister src1, DwVfpRegister src2) { |
| + DCHECK(IsEnabled(NEON)); |
| + // vtrn.<size>(Dn, Dm) SIMD element transpose. |
| + // Instruction details available in ARM DDI 0406C.b, A8-1096. |
| + emit(EncodeNeonSizedOp(VTRN, NEON_D, size, src1.code(), src2.code())); |
| } |
| void Assembler::vtrn(NeonSize size, QwNeonRegister src1, QwNeonRegister src2) { |
| DCHECK(IsEnabled(NEON)); |
| - // Qd = vrev<op_size>.<size>(Qn, Qm) SIMD scalar reverse. |
| + // vtrn.<size>(Qn, Qm) SIMD element transpose. |
| // Instruction details available in ARM DDI 0406C.b, A8-1096. |
| - emit(EncodeNeonSizedOp(VTRN, size, src1, src2)); |
| + emit(EncodeNeonSizedOp(VTRN, NEON_Q, size, src1.code(), src2.code())); |
| } |
| // Encode NEON vtbl / vtbx instruction. |