diff options
author | Diego Novillo <dnovillo@google.com> | 2015-05-26 17:45:38 +0000 |
---|---|---|
committer | Diego Novillo <dnovillo@google.com> | 2015-05-26 17:45:38 +0000 |
commit | bfecc06656d0f9fcdf22270b6c0aa15441d8d198 (patch) | |
tree | 889838a18c0693f03f95bd370126a062f2e18f49 /llvm/lib/Target/ARM | |
parent | 134ce5d1e48d496290fb25ce5fb3032e3e9b5f02 (diff) | |
download | bcm5719-llvm-bfecc06656d0f9fcdf22270b6c0aa15441d8d198.tar.gz bcm5719-llvm-bfecc06656d0f9fcdf22270b6c0aa15441d8d198.zip |
Revert "Re-commit changes in r237579 with fix for bug breaking windows builds."
This reverts commit r238201 to fix linking problems in x86 Linux
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20150525/278413.html
llvm-svn: 238223
Diffstat (limited to 'llvm/lib/Target/ARM')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 428 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelLowering.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 15 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrThumb2.td | 24 |
4 files changed, 16 insertions, 499 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index 629244d9e68..4405625e47c 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -15,7 +15,6 @@ #include "ARMBaseInstrInfo.h" #include "ARMTargetMachine.h" #include "MCTargetDesc/ARMAddressingModes.h" -#include "llvm/ADT/StringSwitch.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineInstrBuilder.h" @@ -252,9 +251,6 @@ private: // Select special operations if node forms integer ABS pattern SDNode *SelectABSOp(SDNode *N); - SDNode *SelectReadRegister(SDNode *N); - SDNode *SelectWriteRegister(SDNode *N); - SDNode *SelectInlineAsm(SDNode *N); SDNode *SelectConcatVector(SDNode *N); @@ -2461,18 +2457,6 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { switch (N->getOpcode()) { default: break; - case ISD::WRITE_REGISTER: { - SDNode *ResNode = SelectWriteRegister(N); - if (ResNode) - return ResNode; - break; - } - case ISD::READ_REGISTER: { - SDNode *ResNode = SelectReadRegister(N); - if (ResNode) - return ResNode; - break; - } case ISD::INLINEASM: { SDNode *ResNode = SelectInlineAsm(N); if (ResNode) @@ -3352,418 +3336,6 @@ SDNode *ARMDAGToDAGISel::Select(SDNode *N) { return SelectCode(N); } -// Inspect a register string of the form -// cp<coprocessor>:<opc1>:c<CRn>:c<CRm>:<opc2> (32bit) or -// cp<coprocessor>:<opc1>:c<CRm> (64bit) inspect the fields of the string -// and obtain the integer operands from them, adding these operands to the -// provided vector. -static void getIntOperandsFromRegisterString(StringRef RegString, - SelectionDAG *CurDAG, SDLoc DL, - std::vector<SDValue>& Ops) { - SmallVector<StringRef, 5> Fields; - RegString.split(Fields, ":"); - - if (Fields.size() > 1) { - bool AllIntFields = true; - - for (StringRef Field : Fields) { - // Need to trim out leading 'cp' characters and get the integer field. - unsigned IntField; - AllIntFields &= !Field.trim("CPcp").getAsInteger(10, IntField); - Ops.push_back(CurDAG->getTargetConstant(IntField, DL, MVT::i32)); - } - - assert(AllIntFields && - "Unexpected non-integer value in special register string."); - } -} - -// Maps a Banked Register string to its mask value. The mask value returned is -// for use in the MRSbanked / MSRbanked instruction nodes as the Banked Register -// mask operand, which expresses which register is to be used, e.g. r8, and in -// which mode it is to be used, e.g. usr. Returns -1 to signify that the string -// was invalid. -static inline int getBankedRegisterMask(StringRef RegString) { - return StringSwitch<int>(RegString.lower()) - .Case("r8_usr", 0x00) - .Case("r9_usr", 0x01) - .Case("r10_usr", 0x02) - .Case("r11_usr", 0x03) - .Case("r12_usr", 0x04) - .Case("sp_usr", 0x05) - .Case("lr_usr", 0x06) - .Case("r8_fiq", 0x08) - .Case("r9_fiq", 0x09) - .Case("r10_fiq", 0x0a) - .Case("r11_fiq", 0x0b) - .Case("r12_fiq", 0x0c) - .Case("sp_fiq", 0x0d) - .Case("lr_fiq", 0x0e) - .Case("lr_irq", 0x10) - .Case("sp_irq", 0x11) - .Case("lr_svc", 0x12) - .Case("sp_svc", 0x13) - .Case("lr_abt", 0x14) - .Case("sp_abt", 0x15) - .Case("lr_und", 0x16) - .Case("sp_und", 0x17) - .Case("lr_mon", 0x1c) - .Case("sp_mon", 0x1d) - .Case("elr_hyp", 0x1e) - .Case("sp_hyp", 0x1f) - .Case("spsr_fiq", 0x2e) - .Case("spsr_irq", 0x30) - .Case("spsr_svc", 0x32) - .Case("spsr_abt", 0x34) - .Case("spsr_und", 0x36) - .Case("spsr_mon", 0x3c) - .Case("spsr_hyp", 0x3e) - .Default(-1); -} - -// Maps a MClass special register string to its value for use in the -// t2MRS_M / t2MSR_M instruction nodes as the SYSm value operand. -// Returns -1 to signify that the string was invalid. -static inline int getMClassRegisterSYSmValueMask(StringRef RegString) { - return StringSwitch<int>(RegString.lower()) - .Case("apsr", 0x0) - .Case("iapsr", 0x1) - .Case("eapsr", 0x2) - .Case("xpsr", 0x3) - .Case("ipsr", 0x5) - .Case("epsr", 0x6) - .Case("iepsr", 0x7) - .Case("msp", 0x8) - .Case("psp", 0x9) - .Case("primask", 0x10) - .Case("basepri", 0x11) - .Case("basepri_max", 0x12) - .Case("faultmask", 0x13) - .Case("control", 0x14) - .Default(-1); -} - -// The flags here are common to those allowed for apsr in the A class cores and -// those allowed for the special registers in the M class cores. Returns a -// value representing which flags were present, -1 if invalid. -static inline int getMClassFlagsMask(StringRef Flags) { - if (Flags.empty()) - return 0x3; - - return StringSwitch<int>(Flags) - .Case("g", 0x1) - .Case("nzcvq", 0x2) - .Case("nzcvqg", 0x3) - .Default(-1); -} - -static int getMClassRegisterMask(StringRef Reg, StringRef Flags, bool IsRead, - const ARMSubtarget *Subtarget) { - // Ensure that the register (without flags) was a valid M Class special - // register. - int SYSmvalue = getMClassRegisterSYSmValueMask(Reg); - if (SYSmvalue == -1) - return -1; - - // basepri, basepri_max and faultmask are only valid for V7m. - if (!Subtarget->hasV7Ops() && SYSmvalue >= 0x11 && SYSmvalue <= 0x13) - return -1; - - // If it was a read then we won't be expecting flags and so at this point - // we can return the mask. - if (IsRead) { - assert (Flags.empty() && "Unexpected flags for reading M class register."); - return SYSmvalue; - } - - // We know we are now handling a write so need to get the mask for the flags. - int Mask = getMClassFlagsMask(Flags); - - // Only apsr, iapsr, eapsr, xpsr can have flags. The other register values - // shouldn't have flags present. - if ((SYSmvalue < 0x4 && Mask == -1) || (SYSmvalue > 0x4 && !Flags.empty())) - return -1; - - // The _g and _nzcvqg versions are only valid if the DSP extension is - // available. - if (!Subtarget->hasThumb2DSP() && (Mask & 0x2)) - return -1; - - // The register was valid so need to put the mask in the correct place - // (the flags need to be in bits 11-10) and combine with the SYSmvalue to - // construct the operand for the instruction node. - if (SYSmvalue < 0x4) - return SYSmvalue | Mask << 10; - - return SYSmvalue; -} - -static int getARClassRegisterMask(StringRef Reg, StringRef Flags) { - // The mask operand contains the special register (R Bit) in bit 4, whether - // the register is spsr (R bit is 1) or one of cpsr/apsr (R bit is 0), and - // bits 3-0 contains the fields to be accessed in the special register, set by - // the flags provided with the register. - int Mask = 0; - if (Reg == "apsr") { - // The flags permitted for apsr are the same flags that are allowed in - // M class registers. We get the flag value and then shift the flags into - // the correct place to combine with the mask. - Mask = getMClassFlagsMask(Flags); - if (Mask == -1) - return -1; - return Mask << 2; - } - - if (Reg != "cpsr" && Reg != "spsr") { - return -1; - } - - // This is the same as if the flags were "fc" - if (Flags.empty() || Flags == "all") - return Mask | 0x9; - - // Inspect the supplied flags string and set the bits in the mask for - // the relevant and valid flags allowed for cpsr and spsr. - for (char Flag : Flags) { - int FlagVal; - switch (Flag) { - case 'c': - FlagVal = 0x1; - break; - case 'x': - FlagVal = 0x2; - break; - case 's': - FlagVal = 0x4; - break; - case 'f': - FlagVal = 0x8; - break; - default: - FlagVal = 0; - } - - // This avoids allowing strings where the same flag bit appears twice. - if (!FlagVal || (Mask & FlagVal)) - return -1; - Mask |= FlagVal; - } - - // If the register is spsr then we need to set the R bit. - if (Reg == "spsr") - Mask |= 0x10; - - return Mask; -} - -// Lower the read_register intrinsic to ARM specific DAG nodes -// using the supplied metadata string to select the instruction node to use -// and the registers/masks to construct as operands for the node. -SDNode *ARMDAGToDAGISel::SelectReadRegister(SDNode *N){ - const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1)); - const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0)); - bool IsThumb2 = Subtarget->isThumb2(); - SDLoc DL(N); - - std::vector<SDValue> Ops; - getIntOperandsFromRegisterString(RegString->getString(), CurDAG, DL, Ops); - - if (!Ops.empty()) { - // If the special register string was constructed of fields (as defined - // in the ACLE) then need to lower to MRC node (32 bit) or - // MRRC node(64 bit), we can make the distinction based on the number of - // operands we have. - unsigned Opcode; - SmallVector<EVT, 3> ResTypes; - if (Ops.size() == 5){ - Opcode = IsThumb2 ? ARM::t2MRC : ARM::MRC; - ResTypes.append({ MVT::i32, MVT::Other }); - } else { - assert(Ops.size() == 3 && - "Invalid number of fields in special register string."); - Opcode = IsThumb2 ? ARM::t2MRRC : ARM::MRRC; - ResTypes.append({ MVT::i32, MVT::i32, MVT::Other }); - } - - Ops.push_back(getAL(CurDAG, DL)); - Ops.push_back(CurDAG->getRegister(0, MVT::i32)); - Ops.push_back(N->getOperand(0)); - return CurDAG->getMachineNode(Opcode, DL, ResTypes, Ops); - } - - std::string SpecialReg = RegString->getString().lower(); - - int BankedReg = getBankedRegisterMask(SpecialReg); - if (BankedReg != -1) { - Ops = { CurDAG->getTargetConstant(BankedReg, DL, MVT::i32), - getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), - N->getOperand(0) }; - return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSbanked : ARM::MRSbanked, - DL, MVT::i32, MVT::Other, Ops); - } - - // The VFP registers are read by creating SelectionDAG nodes with opcodes - // corresponding to the register that is being read from. So we switch on the - // string to find which opcode we need to use. - unsigned Opcode = StringSwitch<unsigned>(SpecialReg) - .Case("fpscr", ARM::VMRS) - .Case("fpexc", ARM::VMRS_FPEXC) - .Case("fpsid", ARM::VMRS_FPSID) - .Case("mvfr0", ARM::VMRS_MVFR0) - .Case("mvfr1", ARM::VMRS_MVFR1) - .Case("mvfr2", ARM::VMRS_MVFR2) - .Case("fpinst", ARM::VMRS_FPINST) - .Case("fpinst2", ARM::VMRS_FPINST2) - .Default(0); - - // If an opcode was found then we can lower the read to a VFP instruction. - if (Opcode) { - if (!Subtarget->hasVFP2()) - return nullptr; - if (Opcode == ARM::VMRS_MVFR2 && !Subtarget->hasFPARMv8()) - return nullptr; - - Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), - N->getOperand(0) }; - return CurDAG->getMachineNode(Opcode, DL, MVT::i32, MVT::Other, Ops); - } - - // If the target is M Class then need to validate that the register string - // is an acceptable value, so check that a mask can be constructed from the - // string. - if (Subtarget->isMClass()) { - int SYSmValue = getMClassRegisterMask(SpecialReg, "", true, Subtarget); - if (SYSmValue == -1) - return nullptr; - - SDValue Ops[] = { CurDAG->getTargetConstant(SYSmValue, DL, MVT::i32), - getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), - N->getOperand(0) }; - return CurDAG->getMachineNode(ARM::t2MRS_M, DL, MVT::i32, MVT::Other, Ops); - } - - // Here we know the target is not M Class so we need to check if it is one - // of the remaining possible values which are apsr, cpsr or spsr. - if (SpecialReg == "apsr" || SpecialReg == "cpsr") { - Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), - N->getOperand(0) }; - return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRS_AR : ARM::MRS, DL, - MVT::i32, MVT::Other, Ops); - } - - if (SpecialReg == "spsr") { - Ops = { getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), - N->getOperand(0) }; - return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MRSsys_AR : ARM::MRSsys, - DL, MVT::i32, MVT::Other, Ops); - } - - return nullptr; -} - -// Lower the write_register intrinsic to ARM specific DAG nodes -// using the supplied metadata string to select the instruction node to use -// and the registers/masks to use in the nodes -SDNode *ARMDAGToDAGISel::SelectWriteRegister(SDNode *N){ - const MDNodeSDNode *MD = dyn_cast<MDNodeSDNode>(N->getOperand(1)); - const MDString *RegString = dyn_cast<MDString>(MD->getMD()->getOperand(0)); - bool IsThumb2 = Subtarget->isThumb2(); - SDLoc DL(N); - - std::vector<SDValue> Ops; - getIntOperandsFromRegisterString(RegString->getString(), CurDAG, DL, Ops); - - if (!Ops.empty()) { - // If the special register string was constructed of fields (as defined - // in the ACLE) then need to lower to MCR node (32 bit) or - // MCRR node(64 bit), we can make the distinction based on the number of - // operands we have. - unsigned Opcode; - if (Ops.size() == 5) { - Opcode = IsThumb2 ? ARM::t2MCR : ARM::MCR; - Ops.insert(Ops.begin()+2, N->getOperand(2)); - } else { - assert(Ops.size() == 3 && - "Invalid number of fields in special register string."); - Opcode = IsThumb2 ? ARM::t2MCRR : ARM::MCRR; - SDValue WriteValue[] = { N->getOperand(2), N->getOperand(3) }; - Ops.insert(Ops.begin()+2, WriteValue, WriteValue+2); - } - - Ops.push_back(getAL(CurDAG, DL)); - Ops.push_back(CurDAG->getRegister(0, MVT::i32)); - Ops.push_back(N->getOperand(0)); - - return CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops); - } - - std::string SpecialReg = RegString->getString().lower(); - int BankedReg = getBankedRegisterMask(SpecialReg); - if (BankedReg != -1) { - Ops = { CurDAG->getTargetConstant(BankedReg, DL, MVT::i32), N->getOperand(2), - getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), - N->getOperand(0) }; - return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSRbanked : ARM::MSRbanked, - DL, MVT::Other, Ops); - } - - // The VFP registers are written to by creating SelectionDAG nodes with - // opcodes corresponding to the register that is being written. So we switch - // on the string to find which opcode we need to use. - unsigned Opcode = StringSwitch<unsigned>(SpecialReg) - .Case("fpscr", ARM::VMSR) - .Case("fpexc", ARM::VMSR_FPEXC) - .Case("fpsid", ARM::VMSR_FPSID) - .Case("fpinst", ARM::VMSR_FPINST) - .Case("fpinst2", ARM::VMSR_FPINST2) - .Default(0); - - if (Opcode) { - if (!Subtarget->hasVFP2()) - return nullptr; - Ops = { N->getOperand(2), getAL(CurDAG, DL), - CurDAG->getRegister(0, MVT::i32), N->getOperand(0) }; - return CurDAG->getMachineNode(Opcode, DL, MVT::Other, Ops); - } - - SmallVector<StringRef, 5> Fields; - StringRef(SpecialReg).split(Fields, "_", 1, false); - std::string Reg = Fields[0].str(); - StringRef Flags = Fields.size() == 2 ? Fields[1] : ""; - - // If the target was M Class then need to validate the special register value - // and retrieve the mask for use in the instruction node. - if (Subtarget->isMClass()) { - // basepri_max gets split so need to correct Reg and Flags. - if (SpecialReg == "basepri_max") { - Reg = SpecialReg; - Flags = ""; - } - int SYSmValue = getMClassRegisterMask(Reg, Flags, false, Subtarget); - if (SYSmValue == -1) - return nullptr; - - SDValue Ops[] = { CurDAG->getTargetConstant(SYSmValue, DL, MVT::i32), - N->getOperand(2), getAL(CurDAG, DL), - CurDAG->getRegister(0, MVT::i32), N->getOperand(0) }; - return CurDAG->getMachineNode(ARM::t2MSR_M, DL, MVT::Other, Ops); - } - - // We then check to see if a valid mask can be constructed for one of the - // register string values permitted for the A and R class cores. These values - // are apsr, spsr and cpsr; these are also valid on older cores. - int Mask = getARClassRegisterMask(Reg, Flags); - if (Mask != -1) { - Ops = { CurDAG->getTargetConstant(Mask, DL, MVT::i32), N->getOperand(2), - getAL(CurDAG, DL), CurDAG->getRegister(0, MVT::i32), - N->getOperand(0) }; - return CurDAG->getMachineNode(IsThumb2 ? ARM::t2MSR_AR : ARM::MSR, - DL, MVT::Other, Ops); - } - - return nullptr; -} - SDNode *ARMDAGToDAGISel::SelectInlineAsm(SDNode *N){ std::vector<SDValue> AsmNodeOperands; unsigned Flag, Kind; diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 6c39ea9c8da..629cc90d67d 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -426,9 +426,6 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM, setOperationAction(ISD::ConstantFP, MVT::f32, Custom); setOperationAction(ISD::ConstantFP, MVT::f64, Custom); - setOperationAction(ISD::READ_REGISTER, MVT::i64, Custom); - setOperationAction(ISD::WRITE_REGISTER, MVT::i64, Custom); - if (Subtarget->hasNEON()) { addDRTypeForNEON(MVT::v2f32); addDRTypeForNEON(MVT::v8i8); @@ -2381,24 +2378,6 @@ bool ARMTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { return !Subtarget->isThumb1Only(); } -// Trying to write a 64 bit value so need to split into two 32 bit values first, -// and pass the lower and high parts through. -static SDValue LowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) { - SDLoc DL(Op); - SDValue WriteValue = Op->getOperand(2); - - // This function is only supposed to be called for i64 type argument. - assert(WriteValue.getValueType() == MVT::i64 - && "LowerWRITE_REGISTER called for non-i64 type argument."); - - SDValue Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, WriteValue, - DAG.getConstant(0, DL, MVT::i32)); - SDValue Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, MVT::i32, WriteValue, - DAG.getConstant(1, DL, MVT::i32)); - SDValue Ops[] = { Op->getOperand(0), Op->getOperand(1), Lo, Hi }; - return DAG.getNode(ISD::WRITE_REGISTER, DL, MVT::Other, Ops); -} - // ConstantPool, JumpTable, GlobalAddress, and ExternalSymbol are lowered as // their target counterpart wrapped in the ARMISD::Wrapper node. Suppose N is // one of the above mentioned nodes. It has to be wrapped because otherwise @@ -4106,28 +4085,7 @@ unsigned ARMTargetLowering::getRegisterByName(const char* RegName, .Default(0); if (Reg) return Reg; - report_fatal_error(Twine("Invalid register name \"" - + StringRef(RegName) + "\".")); -} - -// Result is 64 bit value so split into two 32 bit values and return as a -// pair of values. -static void ExpandREAD_REGISTER(SDNode *N, SmallVectorImpl<SDValue> &Results, - SelectionDAG &DAG) { - SDLoc DL(N); - - // This function is only supposed to be called for i64 type destination. - assert(N->getValueType(0) == MVT::i64 - && "ExpandREAD_REGISTER called for non-i64 type result."); - - SDValue Read = DAG.getNode(ISD::READ_REGISTER, DL, - DAG.getVTList(MVT::i32, MVT::i32, MVT::Other), - N->getOperand(0), - N->getOperand(1)); - - Results.push_back(DAG.getNode(ISD::BUILD_PAIR, DL, MVT::i64, Read.getValue(0), - Read.getValue(1))); - Results.push_back(Read.getOperand(0)); + report_fatal_error("Invalid register name global variable"); } /// ExpandBITCAST - If the target supports VFP, this function is called to @@ -6397,7 +6355,6 @@ static void ReplaceREADCYCLECOUNTER(SDNode *N, SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { switch (Op.getOpcode()) { default: llvm_unreachable("Don't know how to custom lower this!"); - case ISD::WRITE_REGISTER: return LowerWRITE_REGISTER(Op, DAG); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); case ISD::GlobalAddress: @@ -6482,9 +6439,6 @@ void ARMTargetLowering::ReplaceNodeResults(SDNode *N, switch (N->getOpcode()) { default: llvm_unreachable("Don't know how to custom expand this!"); - case ISD::READ_REGISTER: - ExpandREAD_REGISTER(N, Results, DAG); - break; case ISD::BITCAST: Res = ExpandBITCAST(N, DAG); break; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index cdf4695e596..778fd17137f 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -5039,11 +5039,10 @@ def : ARMV5TPat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), (MRC2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2)>; -class MovRRCopro<string opc, bit direction, dag oops, dag iops, list<dag> - pattern = []> - : ABI<0b1100, oops, iops, NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", - pattern> { - +class MovRRCopro<string opc, bit direction, list<dag> pattern = []> + : ABI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, + GPRnopc:$Rt, GPRnopc:$Rt2, c_imm:$CRm), + NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { let Inst{23-21} = 0b010; let Inst{20} = direction; @@ -5061,13 +5060,9 @@ class MovRRCopro<string opc, bit direction, dag oops, dag iops, list<dag> } def MCRR : MovRRCopro<"mcrr", 0 /* from ARM core register to coprocessor */, - (outs), (ins p_imm:$cop, imm0_15:$opc1, GPRnopc:$Rt, - GPRnopc:$Rt2, c_imm:$CRm), [(int_arm_mcrr imm:$cop, imm:$opc1, GPRnopc:$Rt, GPRnopc:$Rt2, imm:$CRm)]>; -def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */, - (outs GPRnopc:$Rt, GPRnopc:$Rt2), - (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm), []>; +def MRRC : MovRRCopro<"mrrc", 1 /* from coprocessor to ARM core register */>; class MovRRCopro2<string opc, bit direction, list<dag> pattern = []> : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, diff --git a/llvm/lib/Target/ARM/ARMInstrThumb2.td b/llvm/lib/Target/ARM/ARMInstrThumb2.td index b2cf19d615e..814b524b2bc 100644 --- a/llvm/lib/Target/ARM/ARMInstrThumb2.td +++ b/llvm/lib/Target/ARM/ARMInstrThumb2.td @@ -4141,9 +4141,11 @@ class t2MovRCopro<bits<4> Op, string opc, bit direction, dag oops, dag iops, let Inst{19-16} = CRn; } -class t2MovRRCopro<bits<4> Op, string opc, bit direction, dag oops, dag iops, +class t2MovRRCopro<bits<4> Op, string opc, bit direction, list<dag> pattern = []> - : T2Cop<Op, oops, iops, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { + : T2Cop<Op, (outs), + (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, c_imm:$CRm), + opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", pattern> { let Inst{27-24} = 0b1100; let Inst{23-21} = 0b010; let Inst{20} = direction; @@ -4208,25 +4210,19 @@ def : T2v6Pat<(int_arm_mrc2 imm:$cop, imm:$opc1, imm:$CRn, imm:$CRm, imm:$opc2), /* from ARM core register to coprocessor */ -def t2MCRR : t2MovRRCopro<0b1110, "mcrr", 0, (outs), - (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, - c_imm:$CRm), +def t2MCRR : t2MovRRCopro<0b1110, "mcrr", 0, [(int_arm_mcrr imm:$cop, imm:$opc1, GPR:$Rt, GPR:$Rt2, imm:$CRm)]>; -def t2MCRR2 : t2MovRRCopro<0b1111, "mcrr2", 0, (outs), - (ins p_imm:$cop, imm0_15:$opc1, GPR:$Rt, GPR:$Rt2, - c_imm:$CRm), - [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, - GPR:$Rt2, imm:$CRm)]> { +def t2MCRR2 : t2MovRRCopro<0b1111, "mcrr2", 0, + [(int_arm_mcrr2 imm:$cop, imm:$opc1, GPR:$Rt, + GPR:$Rt2, imm:$CRm)]> { let Predicates = [IsThumb2, PreV8]; } /* from coprocessor to ARM core register */ -def t2MRRC : t2MovRRCopro<0b1110, "mrrc", 1, (outs GPR:$Rt, GPR:$Rt2), - (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm)>; +def t2MRRC : t2MovRRCopro<0b1110, "mrrc", 1>; -def t2MRRC2 : t2MovRRCopro<0b1111, "mrrc2", 1, (outs GPR:$Rt, GPR:$Rt2), - (ins p_imm:$cop, imm0_15:$opc1, c_imm:$CRm)> { +def t2MRRC2 : t2MovRRCopro<0b1111, "mrrc2", 1> { let Predicates = [IsThumb2, PreV8]; } |