[llvm-commits] [llvm] r78460 - in /llvm/trunk/lib/Target/ARM: ARMISelDAGToDAG.cpp ARMInstrNEON.td
Bob Wilson
bob.wilson at apple.com
Fri Aug 7 23:13:25 PDT 2009
Author: bwilson
Date: Sat Aug 8 01:13:25 2009
New Revision: 78460
URL: http://llvm.org/viewvc/llvm-project?rev=78460&view=rev
Log:
Implement Neon VZIP and VUZP instructions. These are very similar to VTRN,
so I generalized the class for VTRN in the .td file to handle all 3 of them.
Modified:
llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
Modified: llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp?rev=78460&r1=78459&r2=78460&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/ARM/ARMISelDAGToDAG.cpp Sat Aug 8 01:13:25 2009
@@ -1459,6 +1459,7 @@
default: break;
case Intrinsic::arm_neon_vtrni:
+ case Intrinsic::arm_neon_vtrnf:
switch (VT.getSimpleVT()) {
default: return NULL;
case MVT::v8i8: Opc = ARM::VTRNd8; break;
@@ -1472,6 +1473,38 @@
}
return CurDAG->getTargetNode(Opc, dl, VT, VT, N->getOperand(1),
N->getOperand(2));
+
+ case Intrinsic::arm_neon_vuzpi:
+ case Intrinsic::arm_neon_vuzpf:
+ switch (VT.getSimpleVT()) {
+ default: return NULL;
+ case MVT::v8i8: Opc = ARM::VUZPd8; break;
+ case MVT::v4i16: Opc = ARM::VUZPd16; break;
+ case MVT::v2f32:
+ case MVT::v2i32: Opc = ARM::VUZPd32; break;
+ case MVT::v16i8: Opc = ARM::VUZPq8; break;
+ case MVT::v8i16: Opc = ARM::VUZPq16; break;
+ case MVT::v4f32:
+ case MVT::v4i32: Opc = ARM::VUZPq32; break;
+ }
+ return CurDAG->getTargetNode(Opc, dl, VT, VT, N->getOperand(1),
+ N->getOperand(2));
+
+ case Intrinsic::arm_neon_vzipi:
+ case Intrinsic::arm_neon_vzipf:
+ switch (VT.getSimpleVT()) {
+ default: return NULL;
+ case MVT::v8i8: Opc = ARM::VZIPd8; break;
+ case MVT::v4i16: Opc = ARM::VZIPd16; break;
+ case MVT::v2f32:
+ case MVT::v2i32: Opc = ARM::VZIPd32; break;
+ case MVT::v16i8: Opc = ARM::VZIPq8; break;
+ case MVT::v8i16: Opc = ARM::VZIPq16; break;
+ case MVT::v4f32:
+ case MVT::v4i32: Opc = ARM::VZIPq32; break;
+ }
+ return CurDAG->getTargetNode(Opc, dl, VT, VT, N->getOperand(1),
+ N->getOperand(2));
}
break;
}
Modified: llvm/trunk/lib/Target/ARM/ARMInstrNEON.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrNEON.td?rev=78460&r1=78459&r2=78460&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrNEON.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrNEON.td Sat Aug 8 01:13:25 2009
@@ -364,6 +364,18 @@
(ins DPR:$src), NoItinerary, !strconcat(OpcodeStr, "\t$dst, $src"), "",
[(set QPR:$dst, (TyQ (IntOp (TyD DPR:$src))))]>;
+// 2-register shuffles (VTRN/VZIP/VUZP), both double- and quad-register.
+class N2VDShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr>
+ : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 0, 0, (outs DPR:$dst1, DPR:$dst2),
+ (ins DPR:$src1, DPR:$src2), NoItinerary,
+ !strconcat(OpcodeStr, "\t$dst1, $dst2"),
+ "$src1 = $dst1, $src2 = $dst2", []>;
+class N2VQShuffle<bits<2> op19_18, bits<5> op11_7, string OpcodeStr>
+ : N2V<0b11, 0b11, op19_18, 0b10, op11_7, 1, 0, (outs QPR:$dst1, QPR:$dst2),
+ (ins QPR:$src1, QPR:$src2), NoItinerary,
+ !strconcat(OpcodeStr, "\t$dst1, $dst2"),
+ "$src1 = $dst1, $src2 = $dst2", []>;
+
// Basic 3-register operations, both double- and quad-register.
class N3VD<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op4,
string OpcodeStr, ValueType ResTy, ValueType OpTy,
@@ -1919,24 +1931,33 @@
// VTRN : Vector Transpose
-class VTRND<bits<2> op19_18, string OpcodeStr>
- : N2V<0b11, 0b11, op19_18, 0b10, 0b00001, 0, 0, (outs DPR:$dst1, DPR:$dst2),
- (ins DPR:$src1, DPR:$src2), NoItinerary,
- !strconcat(OpcodeStr, "\t$dst1, $dst2"),
- "$src1 = $dst1, $src2 = $dst2", []>;
-class VTRNQ<bits<2> op19_18, string OpcodeStr>
- : N2V<0b11, 0b11, op19_18, 0b10, 0b00001, 1, 0, (outs QPR:$dst1, QPR:$dst2),
- (ins QPR:$src1, QPR:$src2), NoItinerary,
- !strconcat(OpcodeStr, "\t$dst1, $dst2"),
- "$src1 = $dst1, $src2 = $dst2", []>;
+def VTRNd8 : N2VDShuffle<0b00, 0b00001, "vtrn.8">;
+def VTRNd16 : N2VDShuffle<0b01, 0b00001, "vtrn.16">;
+def VTRNd32 : N2VDShuffle<0b10, 0b00001, "vtrn.32">;
+
+def VTRNq8 : N2VQShuffle<0b00, 0b00001, "vtrn.8">;
+def VTRNq16 : N2VQShuffle<0b01, 0b00001, "vtrn.16">;
+def VTRNq32 : N2VQShuffle<0b10, 0b00001, "vtrn.32">;
+
+// VUZP : Vector Unzip (Deinterleave)
+
+def VUZPd8 : N2VDShuffle<0b00, 0b00010, "vuzp.8">;
+def VUZPd16 : N2VDShuffle<0b01, 0b00010, "vuzp.16">;
+def VUZPd32 : N2VDShuffle<0b10, 0b00010, "vuzp.32">;
+
+def VUZPq8 : N2VQShuffle<0b00, 0b00010, "vuzp.8">;
+def VUZPq16 : N2VQShuffle<0b01, 0b00010, "vuzp.16">;
+def VUZPq32 : N2VQShuffle<0b10, 0b00010, "vuzp.32">;
+
+// VZIP : Vector Zip (Interleave)
+
+def VZIPd8 : N2VDShuffle<0b00, 0b00011, "vzip.8">;
+def VZIPd16 : N2VDShuffle<0b01, 0b00011, "vzip.16">;
+def VZIPd32 : N2VDShuffle<0b10, 0b00011, "vzip.32">;
-def VTRNd8 : VTRND<0b00, "vtrn.8">;
-def VTRNd16 : VTRND<0b01, "vtrn.16">;
-def VTRNd32 : VTRND<0b10, "vtrn.32">;
-
-def VTRNq8 : VTRNQ<0b00, "vtrn.8">;
-def VTRNq16 : VTRNQ<0b01, "vtrn.16">;
-def VTRNq32 : VTRNQ<0b10, "vtrn.32">;
+def VZIPq8 : N2VQShuffle<0b00, 0b00011, "vzip.8">;
+def VZIPq16 : N2VQShuffle<0b01, 0b00011, "vzip.16">;
+def VZIPq32 : N2VQShuffle<0b10, 0b00011, "vzip.32">;
//===----------------------------------------------------------------------===//
// NEON instructions for single-precision FP math
More information about the llvm-commits
mailing list