diff options
author | Bob Wilson <bob.wilson@apple.com> | 2010-07-07 00:08:54 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2010-07-07 00:08:54 +0000 |
commit | c1c0833f5c20e2558f5767735b60fdae654f8fe2 (patch) | |
tree | 2f1936970b93e35a920899dbba1c31ebd39e43a1 | |
parent | ebb6efb9531854b8daa1eeb24255753db2a225ae (diff) | |
download | external_llvm-c1c0833f5c20e2558f5767735b60fdae654f8fe2.zip external_llvm-c1c0833f5c20e2558f5767735b60fdae654f8fe2.tar.gz external_llvm-c1c0833f5c20e2558f5767735b60fdae654f8fe2.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.cpp | 41 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrNEON.td | 13 |
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 //===----------------------------------------------------------------------===// |