aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2010-07-07 00:08:54 +0000
committerBob Wilson <bob.wilson@apple.com>2010-07-07 00:08:54 +0000
commit78dfbc380d685c59b9321e43c10677a179850e29 (patch)
tree2f1936970b93e35a920899dbba1c31ebd39e43a1
parente97f968a69d90ee61fbe16d1740ab7f7ea18d1bf (diff)
downloadexternal_llvm-78dfbc380d685c59b9321e43c10677a179850e29.zip
external_llvm-78dfbc380d685c59b9321e43c10677a179850e29.tar.gz
external_llvm-78dfbc380d685c59b9321e43c10677a179850e29.tar.bz2
Also use REG_SEQUENCE for VTBX instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107743 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp41
-rw-r--r--lib/Target/ARM/ARMInstrNEON.td13
2 files changed, 30 insertions, 24 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 235bf36..c84d3ff 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -143,10 +143,10 @@ private:
unsigned *DOpcodes, unsigned *QOpcodes0,
unsigned *QOpcodes1);
- /// SelectVTBL - Select NEON VTBL intrinsics. NumVecs should be 2, 3 or 4.
- /// These are custom-selected so that a REG_SEQUENCE can be generated to
- /// force the table registers to be consecutive.
- SDNode *SelectVTBL(SDNode *N, unsigned NumVecs, unsigned Opc);
+ /// SelectVTBL - Select NEON VTBL and VTBX intrinsics. NumVecs should be 2,
+ /// 3 or 4. These are custom-selected so that a REG_SEQUENCE can be
+ /// generated to force the table registers to be consecutive.
+ SDNode *SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs, unsigned Opc);
/// SelectV6T2BitfieldExtractOp - Select SBFX/UBFX instructions for ARM.
SDNode *SelectV6T2BitfieldExtractOp(SDNode *N, bool isSigned);
@@ -1529,29 +1529,33 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDNode *N, bool IsLoad,
return NULL;
}
-SDNode *ARMDAGToDAGISel::SelectVTBL(SDNode *N, unsigned NumVecs, unsigned Opc) {
+SDNode *ARMDAGToDAGISel::SelectVTBL(SDNode *N, bool IsExt, unsigned NumVecs,
+ unsigned Opc) {
assert(NumVecs >= 2 && NumVecs <= 4 && "VTBL NumVecs out-of-range");
DebugLoc dl = N->getDebugLoc();
EVT VT = N->getValueType(0);
+ unsigned FirstTblReg = IsExt ? 2 : 1;
// Form a REG_SEQUENCE to force register allocation.
SDValue RegSeq;
- SDValue V0 = N->getOperand(1);
- SDValue V1 = N->getOperand(2);
+ SDValue V0 = N->getOperand(FirstTblReg + 0);
+ SDValue V1 = N->getOperand(FirstTblReg + 1);
if (NumVecs == 2)
RegSeq = SDValue(PairDRegs(MVT::v16i8, V0, V1), 0);
else {
- SDValue V2 = N->getOperand(3);
+ SDValue V2 = N->getOperand(FirstTblReg + 2);
// If it's a vtbl3, form a quad D-register and leave the last part as
// an undef.
SDValue V3 = (NumVecs == 3)
? SDValue(CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, VT), 0)
- : N->getOperand(4);
+ : N->getOperand(FirstTblReg + 3);
RegSeq = SDValue(QuadDRegs(MVT::v4i64, V0, V1, V2, V3), 0);
}
// Now extract the D registers back out.
- SmallVector<SDValue, 5> Ops;
+ SmallVector<SDValue, 6> Ops;
+ if (IsExt)
+ Ops.push_back(N->getOperand(1));
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_0, dl, VT, RegSeq));
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_1, dl, VT, RegSeq));
if (NumVecs > 2)
@@ -1559,10 +1563,10 @@ SDNode *ARMDAGToDAGISel::SelectVTBL(SDNode *N, unsigned NumVecs, unsigned Opc) {
if (NumVecs > 3)
Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::dsub_3, dl, VT, RegSeq));
- Ops.push_back(N->getOperand(NumVecs+1));
+ Ops.push_back(N->getOperand(FirstTblReg + NumVecs));
Ops.push_back(getAL(CurDAG)); // predicate
Ops.push_back(CurDAG->getRegister(0, MVT::i32)); // predicate register
- return CurDAG->getMachineNode(Opc, dl, VT, Ops.data(), NumVecs+3);
+ return CurDAG->getMachineNode(Opc, dl, VT, Ops.data(), Ops.size());
}
SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDNode *N,
@@ -2329,11 +2333,18 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) {
break;
case Intrinsic::arm_neon_vtbl2:
- return SelectVTBL(N, 2, ARM::VTBL2);
+ return SelectVTBL(N, false, 2, ARM::VTBL2);
case Intrinsic::arm_neon_vtbl3:
- return SelectVTBL(N, 3, ARM::VTBL3);
+ return SelectVTBL(N, false, 3, ARM::VTBL3);
case Intrinsic::arm_neon_vtbl4:
- return SelectVTBL(N, 4, ARM::VTBL4);
+ return SelectVTBL(N, false, 4, ARM::VTBL4);
+
+ case Intrinsic::arm_neon_vtbx2:
+ return SelectVTBL(N, true, 2, ARM::VTBX2);
+ case Intrinsic::arm_neon_vtbx3:
+ return SelectVTBL(N, true, 3, ARM::VTBX3);
+ case Intrinsic::arm_neon_vtbx4:
+ return SelectVTBL(N, true, 4, ARM::VTBX4);
}
break;
}
diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td
index cdd8d5e..a84315f 100644
--- a/lib/Target/ARM/ARMInstrNEON.td
+++ b/lib/Target/ARM/ARMInstrNEON.td
@@ -3314,23 +3314,18 @@ let hasExtraSrcRegAllocReq = 1 in {
def VTBX2
: N3V<1,1,0b11,0b1001,1,0, (outs DPR:$dst),
(ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src), NVTBLFrm, IIC_VTBX2,
- "vtbx", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "$orig = $dst",
- [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx2
- DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$src)))]>;
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2\\}, $src", "$orig = $dst", []>;
def VTBX3
: N3V<1,1,0b11,0b1010,1,0, (outs DPR:$dst),
(ins DPR:$orig, DPR:$tbl1, DPR:$tbl2, DPR:$tbl3, DPR:$src),
NVTBLFrm, IIC_VTBX3,
- "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src", "$orig = $dst",
- [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx3 DPR:$orig, DPR:$tbl1,
- DPR:$tbl2, DPR:$tbl3, DPR:$src)))]>;
+ "vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3\\}, $src",
+ "$orig = $dst", []>;
def VTBX4
: N3V<1,1,0b11,0b1011,1,0, (outs DPR:$dst), (ins DPR:$orig, DPR:$tbl1,
DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src), NVTBLFrm, IIC_VTBX4,
"vtbx", "8", "$dst, \\{$tbl1, $tbl2, $tbl3, $tbl4\\}, $src",
- "$orig = $dst",
- [(set DPR:$dst, (v8i8 (int_arm_neon_vtbx4 DPR:$orig, DPR:$tbl1,
- DPR:$tbl2, DPR:$tbl3, DPR:$tbl4, DPR:$src)))]>;
+ "$orig = $dst", []>;
} // hasExtraSrcRegAllocReq = 1
//===----------------------------------------------------------------------===//