diff options
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.cpp | 47 | ||||
-rw-r--r-- | lib/Target/ARM/ARMBaseInstrInfo.h | 2 | ||||
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 73 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrFormats.td | 54 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrNEON.td | 531 | ||||
-rw-r--r-- | lib/Target/ARM/NEONMoveFix.cpp | 4 |
6 files changed, 414 insertions, 297 deletions
diff --git a/lib/Target/ARM/ARMBaseInstrInfo.cpp b/lib/Target/ARM/ARMBaseInstrInfo.cpp index 33a96f67d6..f5ae1b4557 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.cpp +++ b/lib/Target/ARM/ARMBaseInstrInfo.cpp @@ -39,6 +39,10 @@ static cl::opt<bool> EnableARM3Addr("enable-arm-3-addr-conv", cl::Hidden, cl::desc("Enable ARM 2-addr to 3-addr conv")); +static cl::opt<bool> +PredicateNEON("predicate-neon", cl::Hidden, + cl::desc("Allow NEON instructions to be predicated")); + ARMBaseInstrInfo::ARMBaseInstrInfo(const ARMSubtarget& STI) : TargetInstrInfoImpl(ARMInsts, array_lengthof(ARMInsts)), Subtarget(STI) { @@ -402,6 +406,21 @@ bool ARMBaseInstrInfo::DefinesPredicate(MachineInstr *MI, return Found; } +/// isPredicable - Return true if the specified instruction can be predicated. +/// By default, this returns true for every instruction with a +/// PredicateOperand. +bool ARMBaseInstrInfo::isPredicable(MachineInstr *MI) const { + const TargetInstrDesc &TID = MI->getDesc(); + if (!TID.isPredicable()) + return false; + + if ((TID.TSFlags & ARMII::DomainMask) == ARMII::DomainNEON) { + ARMFunctionInfo *AFI = + MI->getParent()->getParent()->getInfo<ARMFunctionInfo>(); + return PredicateNEON && AFI->isThumb2Function(); + } + return true; +} /// FIXME: Works around a gcc miscompilation with -fstrict-aliasing static unsigned getNumJTEntries(const std::vector<MachineJumpTableEntry> &JT, @@ -647,11 +666,13 @@ ARMBaseInstrInfo::copyRegToReg(MachineBasicBlock &MBB, SrcRC == ARM::DPR_VFP2RegisterClass || SrcRC == ARM::DPR_8RegisterClass) { // Always use neon reg-reg move if source or dest is NEON-only regclass. - BuildMI(MBB, I, DL, get(ARM::VMOVDneon), DestReg).addReg(SrcReg); + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVDneon), + DestReg).addReg(SrcReg)); } else if (DestRC == ARM::QPRRegisterClass || DestRC == ARM::QPR_VFP2RegisterClass || DestRC == ARM::QPR_8RegisterClass) { - BuildMI(MBB, I, DL, get(ARM::VMOVQ), DestReg).addReg(SrcReg); + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VMOVQ), + DestReg).addReg(SrcReg)); } else { return false; } @@ -695,13 +716,14 @@ storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, // FIXME: Neon instructions should support predicates if (Align >= 16 && (getRegisterInfo().needsStackRealignment(MF))) { - BuildMI(MBB, I, DL, get(ARM::VST1q64)) - .addFrameIndex(FI).addImm(0).addImm(0).addImm(128).addMemOperand(MMO) - .addReg(SrcReg, getKillRegState(isKill)); + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VST1q64)) + .addFrameIndex(FI).addImm(0).addImm(0).addImm(128) + .addMemOperand(MMO) + .addReg(SrcReg, getKillRegState(isKill))); } else { - BuildMI(MBB, I, DL, get(ARM::VSTRQ)). - addReg(SrcReg, getKillRegState(isKill)) - .addFrameIndex(FI).addImm(0).addMemOperand(MMO); + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VSTRQ)). + addReg(SrcReg, getKillRegState(isKill)) + .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); } } } @@ -740,11 +762,12 @@ loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, // FIXME: Neon instructions should support predicates if (Align >= 16 && (getRegisterInfo().needsStackRealignment(MF))) { - BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg) - .addFrameIndex(FI).addImm(0).addImm(0).addImm(128).addMemOperand(MMO); + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLD1q64), DestReg) + .addFrameIndex(FI).addImm(0).addImm(0).addImm(128) + .addMemOperand(MMO)); } else { - BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg).addFrameIndex(FI).addImm(0). - addMemOperand(MMO); + AddDefaultPred(BuildMI(MBB, I, DL, get(ARM::VLDRQ), DestReg) + .addFrameIndex(FI).addImm(0).addMemOperand(MMO)); } } } diff --git a/lib/Target/ARM/ARMBaseInstrInfo.h b/lib/Target/ARM/ARMBaseInstrInfo.h index 73e854faf2..db9716e944 100644 --- a/lib/Target/ARM/ARMBaseInstrInfo.h +++ b/lib/Target/ARM/ARMBaseInstrInfo.h @@ -220,6 +220,8 @@ public: virtual bool DefinesPredicate(MachineInstr *MI, std::vector<MachineOperand> &Pred) const; + virtual bool isPredicable(MachineInstr *MI) const; + /// GetInstSize - Returns the size of the specified MachineInstr. /// virtual unsigned GetInstSizeInBytes(const MachineInstr* MI) const; diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 41ce9039d7..c7a50ed0e5 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -1049,12 +1049,15 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDValue Op, unsigned NumVecs, case MVT::v4i32: OpcodeIndex = 2; break; } + SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); + SDValue PredReg = CurDAG->getRegister(0, MVT::i32); if (is64BitVector) { unsigned Opc = DOpcodes[OpcodeIndex]; - const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, Chain }; + const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, + Pred, PredReg, Chain }; std::vector<EVT> ResTys(NumVecs, VT); ResTys.push_back(MVT::Other); - return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); + return CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 7); } EVT RegVT = GetNEONSubregVT(VT); @@ -1062,10 +1065,11 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDValue Op, unsigned NumVecs, // Quad registers are directly supported for VLD2, // loading 2 pairs of D regs. unsigned Opc = QOpcodes0[OpcodeIndex]; - const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, Chain }; + const SDValue Ops[] = { MemAddr, MemUpdate, MemOpc, Align, + Pred, PredReg, Chain }; std::vector<EVT> ResTys(4, VT); ResTys.push_back(MVT::Other); - SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 5); + SDNode *VLd = CurDAG->getMachineNode(Opc, dl, ResTys, Ops, 7); Chain = SDValue(VLd, 4); // Combine the even and odd subregs to produce the result. @@ -1086,15 +1090,16 @@ SDNode *ARMDAGToDAGISel::SelectVLD(SDValue Op, unsigned NumVecs, // Load the even subregs. unsigned Opc = QOpcodes0[OpcodeIndex]; - const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Align, Chain }; - SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 5); + const SDValue OpsA[] = { MemAddr, MemUpdate, MemOpc, Align, + Pred, PredReg, Chain }; + SDNode *VLdA = CurDAG->getMachineNode(Opc, dl, ResTys, OpsA, 7); Chain = SDValue(VLdA, NumVecs+1); // Load the odd subregs. Opc = QOpcodes1[OpcodeIndex]; const SDValue OpsB[] = { SDValue(VLdA, NumVecs), MemUpdate, MemOpc, - Align, Chain }; - SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 5); + Align, Pred, PredReg, Chain }; + SDNode *VLdB = CurDAG->getMachineNode(Opc, dl, ResTys, OpsB, 7); Chain = SDValue(VLdB, NumVecs+1); // Combine the even and odd subregs to produce the result. @@ -1138,6 +1143,9 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs, case MVT::v4i32: OpcodeIndex = 2; break; } + SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); + SDValue PredReg = CurDAG->getRegister(0, MVT::i32); + SmallVector<SDValue, 8> Ops; Ops.push_back(MemAddr); Ops.push_back(MemUpdate); @@ -1148,8 +1156,10 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs, unsigned Opc = DOpcodes[OpcodeIndex]; for (unsigned Vec = 0; Vec < NumVecs; ++Vec) Ops.push_back(N->getOperand(Vec+3)); + Ops.push_back(Pred); + Ops.push_back(PredReg); Ops.push_back(Chain); - return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+5); + return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+7); } EVT RegVT = GetNEONSubregVT(VT); @@ -1163,8 +1173,10 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs, Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, N->getOperand(Vec+3))); } + Ops.push_back(Pred); + Ops.push_back(PredReg); Ops.push_back(Chain); - return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 9); + return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), 11); } // Otherwise, quad registers are stored with two separate instructions, @@ -1177,10 +1189,12 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs, for (unsigned Vec = 0; Vec < NumVecs; ++Vec) Ops.push_back(CurDAG->getTargetExtractSubreg(ARM::DSUBREG_0, dl, RegVT, N->getOperand(Vec+3))); + Ops.push_back(Pred); + Ops.push_back(PredReg); Ops.push_back(Chain); unsigned Opc = QOpcodes0[OpcodeIndex]; SDNode *VStA = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), - MVT::Other, Ops.data(), NumVecs+5); + MVT::Other, Ops.data(), NumVecs+7); Chain = SDValue(VStA, 1); // Store the odd subregs. @@ -1188,10 +1202,12 @@ SDNode *ARMDAGToDAGISel::SelectVST(SDValue Op, unsigned NumVecs, for (unsigned Vec = 0; Vec < NumVecs; ++Vec) Ops[Vec+4] = CurDAG->getTargetExtractSubreg(ARM::DSUBREG_1, dl, RegVT, N->getOperand(Vec+3)); - Ops[NumVecs+4] = Chain; + Ops[NumVecs+4] = Pred; + Ops[NumVecs+5] = PredReg; + Ops[NumVecs+6] = Chain; Opc = QOpcodes1[OpcodeIndex]; SDNode *VStB = CurDAG->getMachineNode(Opc, dl, MemAddr.getValueType(), - MVT::Other, Ops.data(), NumVecs+5); + MVT::Other, Ops.data(), NumVecs+7); Chain = SDValue(VStB, 1); ReplaceUses(SDValue(N, 0), Chain); return NULL; @@ -1239,6 +1255,9 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDValue Op, bool IsLoad, case MVT::v4i32: OpcodeIndex = 1; break; } + SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); + SDValue PredReg = CurDAG->getRegister(0, MVT::i32); + SmallVector<SDValue, 9> Ops; Ops.push_back(MemAddr); Ops.push_back(MemUpdate); @@ -1264,15 +1283,17 @@ SDNode *ARMDAGToDAGISel::SelectVLDSTLane(SDValue Op, bool IsLoad, N->getOperand(Vec+3))); } Ops.push_back(getI32Imm(Lane)); + Ops.push_back(Pred); + Ops.push_back(PredReg); Ops.push_back(Chain); if (!IsLoad) - return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+5); + return CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops.data(), NumVecs+7); std::vector<EVT> ResTys(NumVecs, RegVT); ResTys.push_back(MVT::Other); SDNode *VLdLn = - CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+5); + CurDAG->getMachineNode(Opc, dl, ResTys, Ops.data(), NumVecs+7); // For a 64-bit vector load to D registers, nothing more needs to be done. if (is64BitVector) return VLdLn; @@ -1297,7 +1318,7 @@ SDNode *ARMDAGToDAGISel::SelectV6T2BitfieldExtractOp(SDValue Op, return NULL; unsigned Shl_imm = 0; - if (isOpcWithIntImmediate(Op.getOperand(0).getNode(), ISD::SHL, Shl_imm)){ + if (isOpcWithIntImmediate(Op.getOperand(0).getNode(), ISD::SHL, Shl_imm)) { assert(Shl_imm > 0 && Shl_imm < 32 && "bad amount in shift node!"); unsigned Srl_imm = 0; if (isInt32Immediate(Op.getOperand(1), Srl_imm)) { @@ -1519,7 +1540,7 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { SDNode *ResNode; if (Subtarget->isThumb1Only()) { - SDValue Pred = CurDAG->getTargetConstant(0xEULL, MVT::i32); + SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); SDValue PredReg = CurDAG->getRegister(0, MVT::i32); SDValue Ops[] = { CPIdx, Pred, PredReg, CurDAG->getEntryNode() }; ResNode = CurDAG->getMachineNode(ARM::tLDRcp, dl, MVT::i32, MVT::Other, @@ -1775,8 +1796,10 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { case MVT::v4f32: case MVT::v4i32: Opc = ARM::VZIPq32; break; } - return CurDAG->getMachineNode(Opc, dl, VT, VT, - N->getOperand(0), N->getOperand(1)); + SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); + SDValue PredReg = CurDAG->getRegister(0, MVT::i32); + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; + return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); } case ARMISD::VUZP: { unsigned Opc = 0; @@ -1792,8 +1815,10 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { case MVT::v4f32: case MVT::v4i32: Opc = ARM::VUZPq32; break; } - return CurDAG->getMachineNode(Opc, dl, VT, VT, - N->getOperand(0), N->getOperand(1)); + SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); + SDValue PredReg = CurDAG->getRegister(0, MVT::i32); + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; + return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); } case ARMISD::VTRN: { unsigned Opc = 0; @@ -1809,8 +1834,10 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) { case MVT::v4f32: case MVT::v4i32: Opc = ARM::VTRNq32; break; } - return CurDAG->getMachineNode(Opc, dl, VT, VT, - N->getOperand(0), N->getOperand(1)); + SDValue Pred = CurDAG->getTargetConstant(14, MVT::i32); + SDValue PredReg = CurDAG->getRegister(0, MVT::i32); + SDValue Ops[] = { N->getOperand(0), N->getOperand(1), Pred, PredReg }; + return CurDAG->getMachineNode(Opc, dl, VT, VT, Ops, 4); } case ISD::INTRINSIC_VOID: diff --git a/lib/Target/ARM/ARMInstrFormats.td b/lib/Target/ARM/ARMInstrFormats.td index 292fa8fcda..f840770f99 100644 --- a/lib/Target/ARM/ARMInstrFormats.td +++ b/lib/Target/ARM/ARMInstrFormats.td @@ -1217,27 +1217,30 @@ class AVConv5I<bits<8> opcod1, bits<4> opcod2, dag oops, dag iops, // class NeonI<dag oops, dag iops, AddrMode am, IndexMode im, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> + string opc, string asm, string cstr, list<dag> pattern> : InstARM<am, Size4Bytes, im, NEONFrm, NeonDomain, cstr, itin> { let OutOperandList = oops; - let InOperandList = iops; - let AsmString = asm; + let InOperandList = !con(iops, (ops pred:$p)); + let AsmString = !strconcat(opc, !strconcat("${p}", asm)); let Pattern = pattern; list<Predicate> Predicates = [HasNEON]; } -class NI<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> - : NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, asm, "", pattern> { +class NI<dag oops, dag iops, InstrItinClass itin, string opc, string asm, + list<dag> pattern> + : NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm, "", + pattern> { } -class NI4<dag oops, dag iops, InstrItinClass itin, string asm, list<dag> pattern> - : NeonI<oops, iops, AddrMode4, IndexModeNone, itin, asm, "", pattern> { +class NI4<dag oops, dag iops, InstrItinClass itin, string opc, string asm, + list<dag> pattern> + : NeonI<oops, iops, AddrMode4, IndexModeNone, itin, opc, asm, "", pattern> { } class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NeonI<oops, iops, AddrMode6, IndexModeNone, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NeonI<oops, iops, AddrMode6, IndexModeNone, itin, opc, asm, cstr, pattern> { let Inst{31-24} = 0b11110100; let Inst{23} = op23; let Inst{21-20} = op21_20; @@ -1248,8 +1251,8 @@ class NLdSt<bit op23, bits<2> op21_20, bits<4> op11_8, bits<4> op7_4, // With selective bit(s) from op7_4 specified by subclasses. class NLdStLN<bit op23, bits<2> op21_20, bits<4> op11_8, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NeonI<oops, iops, AddrMode6, IndexModeNone, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NeonI<oops, iops, AddrMode6, IndexModeNone, itin, opc, asm, cstr, pattern> { let Inst{31-24} = 0b11110100; let Inst{23} = op23; let Inst{21-20} = op21_20; @@ -1257,8 +1260,9 @@ class NLdStLN<bit op23, bits<2> op21_20, bits<4> op11_8, } class NDataI<dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NeonI<oops, iops, AddrModeNone, IndexModeNone, itin, opc, asm, + cstr, pattern> { let Inst{31-25} = 0b1111001; } @@ -1266,8 +1270,8 @@ class NDataI<dag oops, dag iops, InstrItinClass itin, class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, bit op5, bit op4, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NDataI<oops, iops, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NDataI<oops, iops, itin, opc, asm, cstr, pattern> { let Inst{23} = op23; let Inst{21-19} = op21_19; let Inst{11-8} = op11_8; @@ -1281,8 +1285,8 @@ class N1ModImm<bit op23, bits<3> op21_19, bits<4> op11_8, bit op7, bit op6, class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op6, bit op4, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NDataI<oops, iops, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NDataI<oops, iops, itin, opc, asm, cstr, pattern> { let Inst{24-23} = op24_23; let Inst{21-20} = op21_20; let Inst{19-18} = op19_18; @@ -1296,8 +1300,8 @@ class N2V<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, // Inst{19-16} is specified by subclasses. class N2VDup<bits<2> op24_23, bits<2> op21_20, bits<5> op11_7, bit op6, bit op4, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NDataI<oops, iops, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NDataI<oops, iops, itin, opc, asm, cstr, pattern> { let Inst{24-23} = op24_23; let Inst{21-20} = op21_20; let Inst{11-7} = op11_7; @@ -1308,8 +1312,8 @@ class N2VDup<bits<2> op24_23, bits<2> op21_20, bits<5> op11_7, bit op6, bit op4, // NEON 2 vector register with immediate. class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NDataI<oops, iops, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NDataI<oops, iops, itin, opc, asm, cstr, pattern> { let Inst{24} = op24; let Inst{23} = op23; let Inst{11-8} = op11_8; @@ -1321,8 +1325,8 @@ class N2VImm<bit op24, bit op23, bits<4> op11_8, bit op7, bit op6, bit op4, // NEON 3 vector register format. class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NDataI<oops, iops, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NDataI<oops, iops, itin, opc, asm, cstr, pattern> { let Inst{24} = op24; let Inst{23} = op23; let Inst{21-20} = op21_20; @@ -1336,8 +1340,8 @@ class N3V<bit op24, bit op23, bits<2> op21_20, bits<4> op11_8, bit op6, bit op4, // concatenation of the operands and is left unspecified. class N3VImm<bit op24, bit op23, bits<2> op21_20, bit op6, bit op4, dag oops, dag iops, InstrItinClass itin, - string asm, string cstr, list<dag> pattern> - : NDataI<oops, iops, itin, asm, cstr, pattern> { + string opc, string asm, string cstr, list<dag> pattern> + : NDataI<oops, iops, itin, opc, asm, cstr, pattern> { let Inst{24} = op24; let Inst{23} = op23; let Inst{21-20} = op21_20; diff --git a/lib/Target/ARM/ARMInstrNEON.td b/lib/Target/ARM/ARMInstrNEON.td index 3b47912431..124bf919cd 100644 --- a/lib/Target/ARM/ARMInstrNEON.td +++ b/lib/Target/ARM/ARMInstrNEON.td @@ -124,7 +124,7 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in { def VLDMD : NI<(outs), (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops), IIC_fpLoadm, - "vldm${addr:submode} ${addr:base}, $dst1", + "vldm", "${addr:submode} ${addr:base}, $dst1", []> { let Inst{27-25} = 0b110; let Inst{20} = 1; @@ -134,7 +134,7 @@ def VLDMD : NI<(outs), def VLDMS : NI<(outs), (ins addrmode_neonldstm:$addr, reglist:$dst1, variable_ops), IIC_fpLoadm, - "vldm${addr:submode} ${addr:base}, $dst1", + "vldm", "${addr:submode} ${addr:base}, $dst1", []> { let Inst{27-25} = 0b110; let Inst{20} = 1; @@ -146,7 +146,7 @@ def VLDMS : NI<(outs), // Use vldmia to load a Q register as a D register pair. def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), IIC_fpLoadm, - "vldmia\t$addr, ${dst:dregpair}", + "vldmia", "\t$addr, ${dst:dregpair}", [(set QPR:$dst, (v2f64 (load addrmode4:$addr)))]> { let Inst{27-25} = 0b110; let Inst{24} = 0; // P bit @@ -158,7 +158,7 @@ def VLDRQ : NI4<(outs QPR:$dst), (ins addrmode4:$addr), // Use vstmia to store a Q register as a D register pair. def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), IIC_fpStorem, - "vstmia\t$addr, ${src:dregpair}", + "vstmia", "\t$addr, ${src:dregpair}", [(store (v2f64 QPR:$src), addrmode4:$addr)]> { let Inst{27-25} = 0b110; let Inst{24} = 0; // P bit @@ -170,11 +170,11 @@ def VSTRQ : NI4<(outs), (ins QPR:$src, addrmode4:$addr), // VLD1 : Vector Load (multiple single elements) class VLD1D<bits<4> op7_4, string OpcodeStr, ValueType Ty, Intrinsic IntOp> : NLdSt<0,0b10,0b0111,op7_4, (outs DPR:$dst), (ins addrmode6:$addr), IIC_VLD1, - !strconcat(OpcodeStr, "\t\\{$dst\\}, $addr"), "", + OpcodeStr, "\t\\{$dst\\}, $addr", "", [(set DPR:$dst, (Ty (IntOp addrmode6:$addr)))]>; class VLD1Q<bits<4> op7_4, string OpcodeStr, ValueType Ty, Intrinsic IntOp> : NLdSt<0,0b10,0b1010,op7_4, (outs QPR:$dst), (ins addrmode6:$addr), IIC_VLD1, - !strconcat(OpcodeStr, "\t${dst:dregpair}, $addr"), "", + OpcodeStr, "\t${dst:dregpair}, $addr", "", [(set QPR:$dst, (Ty (IntOp addrmode6:$addr)))]>; def VLD1d8 : VLD1D<0b0000, "vld1.8", v8i8, int_arm_neon_vld1>; @@ -195,12 +195,12 @@ let mayLoad = 1, hasExtraDefRegAllocReq = 1 in { class VLD2D<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b10,0b1000,op7_4, (outs DPR:$dst1, DPR:$dst2), (ins addrmode6:$addr), IIC_VLD2, - !strconcat(OpcodeStr, "\t\\{$dst1,$dst2\\}, $addr"), "", []>; + OpcodeStr, "\t\\{$dst1,$dst2\\}, $addr", "", []>; class VLD2Q<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b10,0b0011,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4), (ins addrmode6:$addr), IIC_VLD2, - !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr"), + OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr", "", []>; def VLD2d8 : VLD2D<0b0000, "vld2.8">; @@ -208,7 +208,7 @@ def VLD2d16 : VLD2D<0b0100, "vld2.16">; def VLD2d32 : VLD2D<0b1000, "vld2.32">; def VLD2d64 : NLdSt<0,0b10,0b1010,0b1100, (outs DPR:$dst1, DPR:$dst2), (ins addrmode6:$addr), IIC_VLD1, - "vld1.64\t\\{$dst1,$dst2\\}, $addr", "", []>; + "vld1.64", "\t\\{$dst1,$dst2\\}, $addr", "", []>; def VLD2q8 : VLD2Q<0b0000, "vld2.8">; def VLD2q16 : VLD2Q<0b0100, "vld2.16">; @@ -218,11 +218,11 @@ def VLD2q32 : VLD2Q<0b1000, "vld2.32">; class VLD3D<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b10,0b0100,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3), (ins addrmode6:$addr), IIC_VLD3, - !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3\\}, $addr"), "", []>; + OpcodeStr, "\t\\{$dst1,$dst2,$dst3\\}, $addr", "", []>; class VLD3WB<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b10,0b0101,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, GPR:$wb), (ins addrmode6:$addr), IIC_VLD3, - !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3\\}, $addr"), + OpcodeStr, "\t\\{$dst1,$dst2,$dst3\\}, $addr", "$addr.addr = $wb", []>; def VLD3d8 : VLD3D<0b0000, "vld3.8">; @@ -231,7 +231,7 @@ def VLD3d32 : VLD3D<0b1000, "vld3.32">; def VLD3d64 : NLdSt<0,0b10,0b0110,0b1100, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3), (ins addrmode6:$addr), IIC_VLD1, - "vld1.64\t\\{$dst1,$dst2,$dst3\\}, $addr", "", []>; + "vld1.64", "\t\\{$dst1,$dst2,$dst3\\}, $addr", "", []>; // vld3 to double-spaced even registers. def VLD3q8a : VLD3WB<0b0000, "vld3.8">; @@ -248,13 +248,13 @@ class VLD4D<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b10,0b0000,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4), (ins addrmode6:$addr), IIC_VLD4, - !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr"), + OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr", "", []>; class VLD4WB<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b10,0b0001,op7_4, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4, GPR:$wb), (ins addrmode6:$addr), IIC_VLD4, - !strconcat(OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr"), + OpcodeStr, "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr", "$addr.addr = $wb", []>; def VLD4d8 : VLD4D<0b0000, "vld4.8">; @@ -263,7 +263,7 @@ def VLD4d32 : VLD4D<0b1000, "vld4.32">; def VLD4d64 : NLdSt<0,0b10,0b0010,0b1100, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4), (ins addrmode6:$addr), IIC_VLD1, - "vld1.64\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr", "", []>; + "vld1.64", "\t\\{$dst1,$dst2,$dst3,$dst4\\}, $addr", "", []>; // vld4 to double-spaced even registers. def VLD4q8a : VLD4WB<0b0000, "vld4.8">; @@ -283,7 +283,7 @@ class VLD2LN<bits<4> op11_8, string OpcodeStr> : NLdStLN<1,0b10,op11_8, (outs DPR:$dst1, DPR:$dst2), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane), IIC_VLD2, - !strconcat(OpcodeStr, "\t\\{$dst1[$lane],$dst2[$lane]\\}, $addr"), + OpcodeStr, "\t\\{$dst1[$lane],$dst2[$lane]\\}, $addr", "$src1 = $dst1, $src2 = $dst2", []>; // vld2 to single-spaced registers. @@ -316,8 +316,8 @@ class VLD3LN<bits<4> op11_8, string OpcodeStr> : NLdStLN<1,0b10,op11_8, (outs DPR:$dst1, DPR:$dst2, DPR:$dst3), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, nohash_imm:$lane), IIC_VLD3, - !strconcat(OpcodeStr, - "\t\\{$dst1[$lane],$dst2[$lane],$dst3[$lane]\\}, $addr"), + OpcodeStr, + "\t\\{$dst1[$lane],$dst2[$lane],$dst3[$lane]\\}, $addr", "$src1 = $dst1, $src2 = $dst2, $src3 = $dst3", []>; // vld3 to single-spaced registers. @@ -353,8 +353,8 @@ class VLD4LN<bits<4> op11_8, string OpcodeStr> (outs DPR:$dst1, DPR:$dst2, DPR:$dst3, DPR:$dst4), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane), IIC_VLD4, - !strconcat(OpcodeStr, - "\t\\{$dst1[$lane],$dst2[$lane],$dst3[$lane],$dst4[$lane]\\}, $addr"), + OpcodeStr, + "\t\\{$dst1[$lane],$dst2[$lane],$dst3[$lane],$dst4[$lane]\\}, $addr", "$src1 = $dst1, $src2 = $dst2, $src3 = $dst3, $src4 = $dst4", []>; // vld4 to single-spaced registers. @@ -392,11 +392,11 @@ def VLD4LNq32b: VLD4LN<0b1011, "vld4.32"> { // VST1 : Vector Store (multiple single elements) class VST1D<bits<4> op7_4, string OpcodeStr, ValueType Ty, Intrinsic IntOp> : NLdSt<0,0b00,0b0111,op7_4, (outs), (ins addrmode6:$addr, DPR:$src), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src\\}, $addr"), "", + OpcodeStr, "\t\\{$src\\}, $addr", "", [(IntOp addrmode6:$addr, (Ty DPR:$src))]>; class VST1Q<bits<4> op7_4, string OpcodeStr, ValueType Ty, Intrinsic IntOp> : NLdSt<0,0b00,0b1010,op7_4, (outs), (ins addrmode6:$addr, QPR:$src), IIC_VST, - !strconcat(OpcodeStr, "\t${src:dregpair}, $addr"), "", + OpcodeStr, "\t${src:dregpair}, $addr", "", [(IntOp addrmode6:$addr, (Ty QPR:$src))]>; let hasExtraSrcRegAllocReq = 1 in { @@ -419,12 +419,12 @@ let mayStore = 1, hasExtraSrcRegAllocReq = 1 in { class VST2D<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b00,0b1000,op7_4, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src1,$src2\\}, $addr"), "", []>; + OpcodeStr, "\t\\{$src1,$src2\\}, $addr", "", []>; class VST2Q<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b00,0b0011,op7_4, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src1,$src2,$src3,$src4\\}, $addr"), + OpcodeStr, "\t\\{$src1,$src2,$src3,$src4\\}, $addr", "", []>; def VST2d8 : VST2D<0b0000, "vst2.8">; @@ -432,7 +432,7 @@ def VST2d16 : VST2D<0b0100, "vst2.16">; def VST2d32 : VST2D<0b1000, "vst2.32">; def VST2d64 : NLdSt<0,0b00,0b1010,0b1100, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2), IIC_VST, - "vst1.64\t\\{$src1,$src2\\}, $addr", "", []>; + "vst1.64", "\t\\{$src1,$src2\\}, $addr", "", []>; def VST2q8 : VST2Q<0b0000, "vst2.8">; def VST2q16 : VST2Q<0b0100, "vst2.16">; @@ -442,11 +442,11 @@ def VST2q32 : VST2Q<0b1000, "vst2.32">; class VST3D<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b00,0b0100,op7_4, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src1,$src2,$src3\\}, $addr"), "", []>; + OpcodeStr, "\t\\{$src1,$src2,$src3\\}, $addr", "", []>; class VST3WB<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b00,0b0101,op7_4, (outs GPR:$wb), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src1,$src2,$src3\\}, $addr"), + OpcodeStr, "\t\\{$src1,$src2,$src3\\}, $addr", "$addr.addr = $wb", []>; def VST3d8 : VST3D<0b0000, "vst3.8">; @@ -455,7 +455,7 @@ def VST3d32 : VST3D<0b1000, "vst3.32">; def VST3d64 : NLdSt<0,0b00,0b0110,0b1100, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3), IIC_VST, - "vst1.64\t\\{$src1,$src2,$src3\\}, $addr", "", []>; + "vst1.64", "\t\\{$src1,$src2,$src3\\}, $addr", "", []>; // vst3 to double-spaced even registers. def VST3q8a : VST3WB<0b0000, "vst3.8">; @@ -472,13 +472,13 @@ class VST4D<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b00,0b0000,op7_4, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src1,$src2,$src3,$src4\\}, $addr"), + OpcodeStr, "\t\\{$src1,$src2,$src3,$src4\\}, $addr", "", []>; class VST4WB<bits<4> op7_4, string OpcodeStr> : NLdSt<0,0b00,0b0001,op7_4, (outs GPR:$wb), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src1,$src2,$src3,$src4\\}, $addr"), + OpcodeStr, "\t\\{$src1,$src2,$src3,$src4\\}, $addr", "$addr.addr = $wb", []>; def VST4d8 : VST4D<0b0000, "vst4.8">; @@ -487,7 +487,7 @@ def VST4d32 : VST4D<0b1000, "vst4.32">; def VST4d64 : NLdSt<0,0b00,0b0010,0b1100, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4), IIC_VST, - "vst1.64\t\\{$src1,$src2,$src3,$src4\\}, $addr", "", []>; + "vst1.64", "\t\\{$src1,$src2,$src3,$src4\\}, $addr", "", []>; // vst4 to double-spaced even registers. def VST4q8a : VST4WB<0b0000, "vst4.8">; @@ -507,7 +507,7 @@ class VST2LN<bits<4> op11_8, string OpcodeStr> : NLdStLN<1,0b00,op11_8, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, nohash_imm:$lane), IIC_VST, - !strconcat(OpcodeStr, "\t\\{$src1[$lane],$src2[$lane]\\}, $addr"), + OpcodeStr, "\t\\{$src1[$lane],$src2[$lane]\\}, $addr", "", []>; // vst2 to single-spaced registers. @@ -540,8 +540,8 @@ class VST3LN<bits<4> op11_8, string OpcodeStr> : NLdStLN<1,0b00,op11_8, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, nohash_imm:$lane), IIC_VST, - !strconcat(OpcodeStr, - "\t\\{$src1[$lane],$src2[$lane],$src3[$lane]\\}, $addr"), "", []>; + OpcodeStr, + "\t\\{$src1[$lane],$src2[$lane],$src3[$lane]\\}, $addr", "", []>; // vst3 to single-spaced registers. def VST3LNd8 : VST3LN<0b0010, "vst3.8"> { @@ -575,8 +575,8 @@ class VST4LN<bits<4> op11_8, string OpcodeStr> : NLdStLN<1,0b00,op11_8, (outs), (ins addrmode6:$addr, DPR:$src1, DPR:$src2, DPR:$src3, DPR:$src4, nohash_imm:$lane), IIC_VST, - !strconcat(OpcodeStr, - "\t\\{$src1[$lane],$src2[$lane],$src3[$lane],$src4[$lane]\\}, $addr"), + OpcodeStr, + "\t\\{$src1[$lane],$src2[$lane],$src3[$lane],$src4[$lane]\\}, $addr", "", []>; // vst4 to single-spaced registers. @@ -655,13 +655,13 @@ class N2VD<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, ValueType ResTy, ValueType OpTy, SDNode OpNode> : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst), - (ins DPR:$src), IIC_VUNAD, !strconcat(OpcodeStr, "\t$dst, $src"), "", + (ins DPR:$src), IIC_VUNAD, OpcodeStr, "\t$dst, $src", "", [(set DPR:$dst, (ResTy (OpNode (OpTy DPR:$src))))]>; class N2VQ<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, string OpcodeStr, ValueType ResTy, ValueType OpTy, SDNode OpNode> : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst), - (ins QPR:$src), IIC_VUNAQ, !strconcat(OpcodeStr, "\t$dst, $src"), "", + (ins QPR:$src), IIC_VUNAQ, OpcodeStr, "\t$dst, $src", "", [(set QPR:$dst, (ResTy (OpNode (OpTy QPR:$src))))]>; // Basic 2-register operations, scalar single-precision. @@ -670,7 +670,7 @@ class N2VDs<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, ValueType ResTy, ValueType OpTy, SDNode OpNode> : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR_VFP2:$dst), (ins DPR_VFP2:$src), - IIC_VUNAD, !strconcat(OpcodeStr, "\t$dst, $src"), "", []>; + IIC_VUNAD, OpcodeStr, "\t$dst, $src", "", []>; class N2VDsPat<SDNode OpNode, ValueType ResTy, ValueType OpTy, NeonI Inst> : NEONFPPat<(ResTy (OpNode SPR:$a)), @@ -684,14 +684,14 @@ class N2VDInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, InstrItinClass itin, string OpcodeStr, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR:$dst), - (ins DPR:$src), itin, !strconcat(OpcodeStr, "\t$dst, $src"), "", + (ins DPR:$src), itin, OpcodeStr, "\t$dst, $src", "", [(set DPR:$dst, (ResTy (IntOp (OpTy DPR:$src))))]>; class N2VQInt<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, bits<2> op17_16, bits<5> op11_7, bit op4, InstrItinClass itin, string OpcodeStr, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 1, op4, (outs QPR:$dst), - (ins QPR:$src), itin, !strconcat(OpcodeStr, "\t$dst, $src"), "", + (ins QPR:$src), itin, OpcodeStr, "\t$dst, $src", "", [(set QPR:$dst, (ResTy (IntOp (OpTy QPR:$src))))]>; // Basic 2-register intrinsics, scalar single-precision @@ -701,7 +701,7 @@ class N2VDInts<bits<2> op24_23, bits<2> op21_20, bits<2> op19_18, ValueType ResTy, ValueType OpTy, Intrinsic IntOp> : N2V<op24_23, op21_20, op19_18, op17_16, op11_7, 0, op4, (outs DPR_VFP2 |