From 9c24c958f1564ed6787d074dec033024c340c36f Mon Sep 17 00:00:00 2001 From: Diego Novillo Date: Tue, 26 May 2015 17:45:38 +0000 Subject: [PATCH] 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238223 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64ISelDAGToDAG.cpp | 127 ------ lib/Target/AArch64/AArch64ISelLowering.cpp | 3 +- lib/Target/ARM/ARMISelDAGToDAG.cpp | 428 ------------------ lib/Target/ARM/ARMISelLowering.cpp | 48 +- lib/Target/ARM/ARMInstrInfo.td | 15 +- lib/Target/ARM/ARMInstrThumb2.td | 24 +- test/CodeGen/AArch64/arm64-named-reg-alloc.ll | 2 +- .../AArch64/arm64-named-reg-notareg.ll | 2 +- test/CodeGen/AArch64/special-reg.ll | 48 -- test/CodeGen/ARM/named-reg-alloc.ll | 2 +- test/CodeGen/ARM/named-reg-notareg.ll | 2 +- test/CodeGen/ARM/special-reg-acore.ll | 78 ---- test/CodeGen/ARM/special-reg-mcore.ll | 143 ------ test/CodeGen/ARM/special-reg.ll | 78 ---- 14 files changed, 21 insertions(+), 979 deletions(-) delete mode 100644 test/CodeGen/AArch64/special-reg.ll delete mode 100644 test/CodeGen/ARM/special-reg-acore.ll delete mode 100644 test/CodeGen/ARM/special-reg-mcore.ll delete mode 100644 test/CodeGen/ARM/special-reg.ll diff --git a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp index 1ea4abcf05f..78a2021f79a 100644 --- a/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp +++ b/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp @@ -156,9 +156,6 @@ public: SDNode *SelectLIBM(SDNode *N); - SDNode *SelectReadRegister(SDNode *N); - SDNode *SelectWriteRegister(SDNode *N); - // Include the pieces autogenerated from the target description. #include "AArch64GenDAGISel.inc" @@ -2117,120 +2114,6 @@ AArch64DAGToDAGISel::SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos, return true; } -// Inspects a register string of the form o0:op1:CRn:CRm:op2 gets the fields -// of the string and obtains the integer values from them and combines these -// into a single value to be used in the MRS/MSR instruction. -static int getIntOperandFromRegisterString(StringRef RegString) { - SmallVector Fields; - RegString.split(Fields, ":"); - - if (Fields.size() == 1) - return -1; - - assert(Fields.size() == 5 - && "Invalid number of fields in read register string"); - - SmallVector Ops; - bool AllIntFields = true; - - for (StringRef Field : Fields) { - unsigned IntField; - AllIntFields &= !Field.getAsInteger(10, IntField); - Ops.push_back(IntField); - } - - assert(AllIntFields && - "Unexpected non-integer value in special register string."); - - // Need to combine the integer fields of the string into a single value - // based on the bit encoding of MRS/MSR instruction. - return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) | - (Ops[3] << 3) | (Ops[4]); -} - -// Lower the read_register intrinsic to an MRS instruction node if the special -// register string argument is either of the form detailed in the ALCE (the -// form described in getIntOperandsFromRegsterString) or is a named register -// known by the MRS SysReg mapper. -SDNode *AArch64DAGToDAGISel::SelectReadRegister(SDNode *N) { - const MDNodeSDNode *MD = dyn_cast(N->getOperand(1)); - const MDString *RegString = dyn_cast(MD->getMD()->getOperand(0)); - SDLoc DL(N); - - int Reg = getIntOperandFromRegisterString(RegString->getString()); - if (Reg != -1) - return CurDAG->getMachineNode(AArch64::MRS, DL, N->getSimpleValueType(0), - MVT::Other, - CurDAG->getTargetConstant(Reg, DL, MVT::i32), - N->getOperand(0)); - - // Use the sysreg mapper to map the remaining possible strings to the - // value for the register to be used for the instruction operand. - AArch64SysReg::MRSMapper mapper; - bool IsValidSpecialReg; - Reg = mapper.fromString(RegString->getString(), - Subtarget->getFeatureBits(), - IsValidSpecialReg); - if (IsValidSpecialReg) - return CurDAG->getMachineNode(AArch64::MRS, DL, N->getSimpleValueType(0), - MVT::Other, - CurDAG->getTargetConstant(Reg, DL, MVT::i32), - N->getOperand(0)); - - return nullptr; -} - -// Lower the write_register intrinsic to an MSR instruction node if the special -// register string argument is either of the form detailed in the ALCE (the -// form described in getIntOperandsFromRegsterString) or is a named register -// known by the MSR SysReg mapper. -SDNode *AArch64DAGToDAGISel::SelectWriteRegister(SDNode *N) { - const MDNodeSDNode *MD = dyn_cast(N->getOperand(1)); - const MDString *RegString = dyn_cast(MD->getMD()->getOperand(0)); - SDLoc DL(N); - - int Reg = getIntOperandFromRegisterString(RegString->getString()); - if (Reg != -1) - return CurDAG->getMachineNode(AArch64::MSR, DL, MVT::Other, - CurDAG->getTargetConstant(Reg, DL, MVT::i32), - N->getOperand(2), N->getOperand(0)); - - // Check if the register was one of those allowed as the pstatefield value in - // the MSR (immediate) instruction. To accept the values allowed in the - // pstatefield for the MSR (immediate) instruction, we also require that an - // immediate value has been provided as an argument, we know that this is - // the case as it has been ensured by semantic checking. - AArch64PState::PStateMapper PMapper; - bool IsValidSpecialReg; - Reg = PMapper.fromString(RegString->getString(), - Subtarget->getFeatureBits(), - IsValidSpecialReg); - if (IsValidSpecialReg) { - assert (isa(N->getOperand(2)) - && "Expected a constant integer expression."); - uint64_t Immed = cast(N->getOperand(2))->getZExtValue(); - return CurDAG->getMachineNode(AArch64::MSRpstate, DL, MVT::Other, - CurDAG->getTargetConstant(Reg, DL, MVT::i32), - CurDAG->getTargetConstant(Immed, DL, MVT::i16), - N->getOperand(0)); - } - - // Use the sysreg mapper to attempt to map the remaining possible strings - // to the value for the register to be used for the MSR (register) - // instruction operand. - AArch64SysReg::MSRMapper Mapper; - Reg = Mapper.fromString(RegString->getString(), - Subtarget->getFeatureBits(), - IsValidSpecialReg); - - if (IsValidSpecialReg) - return CurDAG->getMachineNode(AArch64::MSR, DL, MVT::Other, - CurDAG->getTargetConstant(Reg, DL, MVT::i32), - N->getOperand(2), N->getOperand(0)); - - return nullptr; -} - SDNode *AArch64DAGToDAGISel::Select(SDNode *Node) { // Dump information about the Node being selected DEBUG(errs() << "Selecting: "); @@ -2252,16 +2135,6 @@ SDNode *AArch64DAGToDAGISel::Select(SDNode *Node) { default: break; - case ISD::READ_REGISTER: - if (SDNode *Res = SelectReadRegister(Node)) - return Res; - break; - - case ISD::WRITE_REGISTER: - if (SDNode *Res = SelectWriteRegister(Node)) - return Res; - break; - case ISD::ADD: if (SDNode *I = SelectMLAV64LaneV128(Node)) return I; diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index bbd3f53e79c..e6108c3e95e 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -4065,8 +4065,7 @@ unsigned AArch64TargetLowering::getRegisterByName(const char* RegName, .Default(0); if (Reg) return Reg; - report_fatal_error(Twine("Invalid register name \"" - + StringRef(RegName) + "\".")); + report_fatal_error("Invalid register name global variable"); } SDValue AArch64TargetLowering::LowerRETURNADDR(SDValue Op, diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 629244d9e68..4405625e47c 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/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::c:c: (32bit) or -// cp::c (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& Ops) { - SmallVector 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(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(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(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(N->getOperand(1)); - const MDString *RegString = dyn_cast(MD->getMD()->getOperand(0)); - bool IsThumb2 = Subtarget->isThumb2(); - SDLoc DL(N); - - std::vector 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 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(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(N->getOperand(1)); - const MDString *RegString = dyn_cast(MD->getMD()->getOperand(0)); - bool IsThumb2 = Subtarget->isThumb2(); - SDLoc DL(N); - - std::vector 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(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 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 AsmNodeOperands; unsigned Flag, Kind; diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index 6c39ea9c8da..629cc90d67d 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/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 &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/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index cdf4695e596..778fd17137f 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/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 - pattern = []> - : ABI<0b1100, oops, iops, NoItinerary, opc, "\t$cop, $opc1, $Rt, $Rt2, $CRm", - pattern> { - +class MovRRCopro 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 } 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 pattern = []> : ABXI<0b1100, (outs), (ins p_imm:$cop, imm0_15:$opc1, diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index b2cf19d615e..814b524b2bc 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -4141,9 +4141,11 @@ class t2MovRCopro Op, string opc, bit direction, dag oops, dag iops, let Inst{19-16} = CRn; } -class t2MovRRCopro Op, string opc, bit direction, dag oops, dag iops, +class t2MovRRCopro Op, string opc, bit direction, list pattern = []> - : T2Cop { + : T2Cop { 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]; } diff --git a/test/CodeGen/AArch64/arm64-named-reg-alloc.ll b/test/CodeGen/AArch64/arm64-named-reg-alloc.ll index 5d48c17e128..0c564544a53 100644 --- a/test/CodeGen/AArch64/arm64-named-reg-alloc.ll +++ b/test/CodeGen/AArch64/arm64-named-reg-alloc.ll @@ -4,7 +4,7 @@ define i32 @get_stack() nounwind { entry: ; FIXME: Include an allocatable-specific error message -; CHECK: Invalid register name "x5". +; CHECK: Invalid register name global variable %sp = call i32 @llvm.read_register.i32(metadata !0) ret i32 %sp } diff --git a/test/CodeGen/AArch64/arm64-named-reg-notareg.ll b/test/CodeGen/AArch64/arm64-named-reg-notareg.ll index 8a5fd6f1ac8..759bc15807b 100644 --- a/test/CodeGen/AArch64/arm64-named-reg-notareg.ll +++ b/test/CodeGen/AArch64/arm64-named-reg-notareg.ll @@ -3,7 +3,7 @@ define i32 @get_stack() nounwind { entry: -; CHECK: Invalid register name "notareg". +; CHECK: Invalid register name global variable %sp = call i32 @llvm.read_register.i32(metadata !0) ret i32 %sp } diff --git a/test/CodeGen/AArch64/special-reg.ll b/test/CodeGen/AArch64/special-reg.ll deleted file mode 100644 index 91c32158d42..00000000000 --- a/test/CodeGen/AArch64/special-reg.ll +++ /dev/null @@ -1,48 +0,0 @@ -; RUN: llc < %s -mtriple=aarch64-none-eabi -mcpu=cortex-a57 2>&1 | FileCheck %s - -define i64 @read_encoded_register() nounwind { -entry: -; CHECK-LABEL: read_encoded_register: -; CHECK: mrs x0, S1_2_C3_C4_5 - %reg = call i64 @llvm.read_register.i64(metadata !0) - ret i64 %reg -} - -define i64 @read_daif() nounwind { -entry: -; CHECK-LABEL: read_daif: -; CHECK: mrs x0, DAIF - %reg = call i64 @llvm.read_register.i64(metadata !1) - ret i64 %reg -} - -define void @write_encoded_register(i64 %x) nounwind { -entry: -; CHECK-LABEL: write_encoded_register: -; CHECK: msr S1_2_C3_C4_5, x0 - call void @llvm.write_register.i64(metadata !0, i64 %x) - ret void -} - -define void @write_daif(i64 %x) nounwind { -entry: -; CHECK-LABEL: write_daif: -; CHECK: msr DAIF, x0 - call void @llvm.write_register.i64(metadata !1, i64 %x) - ret void -} - -define void @write_daifset() nounwind { -entry: -; CHECK-LABEL: write_daifset: -; CHECK: msr DAIFSET, #2 - call void @llvm.write_register.i64(metadata !2, i64 2) - ret void -} - -declare i64 @llvm.read_register.i64(metadata) nounwind -declare void @llvm.write_register.i64(metadata, i64) nounwind - -!0 = !{!"1:2:3:4:5"} -!1 = !{!"daif"} -!2 = !{!"daifset"} diff --git a/test/CodeGen/ARM/named-reg-alloc.ll b/test/CodeGen/ARM/named-reg-alloc.ll index d41fa64882c..380cf39734f 100644 --- a/test/CodeGen/ARM/named-reg-alloc.ll +++ b/test/CodeGen/ARM/named-reg-alloc.ll @@ -4,7 +4,7 @@ define i32 @get_stack() nounwind { entry: ; FIXME: Include an allocatable-specific error message -; CHECK: Invalid register name "r5". +; CHECK: Invalid register name global variable %sp = call i32 @llvm.read_register.i32(metadata !0) ret i32 %sp } diff --git a/test/CodeGen/ARM/named-reg-notareg.ll b/test/CodeGen/ARM/named-reg-notareg.ll index 45cb38f30f3..3ac03f4fdaa 100644 --- a/test/CodeGen/ARM/named-reg-notareg.ll +++ b/test/CodeGen/ARM/named-reg-notareg.ll @@ -3,7 +3,7 @@ define i32 @get_stack() nounwind { entry: -; CHECK: Invalid register name "notareg". +; CHECK: Invalid register name global variable %sp = call i32 @llvm.read_register.i32(metadata !0) ret i32 %sp } diff --git a/test/CodeGen/ARM/special-reg-acore.ll b/test/CodeGen/ARM/special-reg-acore.ll deleted file mode 100644 index 3d65ff44bfb..00000000000 --- a/test/CodeGen/ARM/special-reg-acore.ll +++ /dev/null @@ -1,78 +0,0 @@ -; RUN: llc < %s -mtriple=arm-none-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s --check-prefix=ACORE -; RUN: not llc < %s -mtriple=thumb-none-eabi -mcpu=cortex-m4 2>&1 | FileCheck %s --check-prefix=MCORE - -; MCORE: LLVM ERROR: Invalid register name "cpsr". - -define i32 @read_cpsr() nounwind { - ; ACORE-LABEL: read_cpsr: - ; ACORE: mrs r0, apsr - %reg = call i32 @llvm.read_register.i32(metadata !1) - ret i32 %reg -} - -define i32 @read_aclass_registers() nounwind { -entry: - ; ACORE-LABEL: read_aclass_registers: - ; ACORE: mrs r0, apsr - ; ACORE: mrs r1, spsr - - %0 = call i32 @llvm.read_register.i32(metadata !0) - %1 = call i32 @llvm.read_register.i32(metadata !1) - %add1 = add i32 %1, %0 - %2 = call i32 @llvm.read_register.i32(metadata !2) - %add2 = add i32 %add1, %2 - ret i32 %add2 -} - -define void @write_aclass_registers(i32 %x) nounwind { -entry: - ; ACORE-LABEL: write_aclass_registers: - ; ACORE: msr APSR_nzcvq, r0 - ; ACORE: msr APSR_g, r0 - ; ACORE: msr APSR_nzcvqg, r0 - ; ACORE: msr CPSR_c, r0 - ; ACORE: msr CPSR_x, r0 - ; ACORE: msr APSR_g, r0 - ; ACORE: msr APSR_nzcvq, r0 - ; ACORE: msr CPSR_fsxc, r0 - ; ACORE: msr SPSR_c, r0 - ; ACORE: msr SPSR_x, r0 - ; ACORE: msr SPSR_s, r0 - ; ACORE: msr SPSR_f, r0 - ; ACORE: msr SPSR_fsxc, r0 - - call void @llvm.write_register.i32(metadata !3, i32 %x) - call void @llvm.write_register.i32(metadata !4, i32 %x) - call void @llvm.write_register.i32(metadata !5, i32 %x) - call void @llvm.write_register.i32(metadata !6, i32 %x) - call void @llvm.write_register.i32(metadata !7, i32 %x) - call void @llvm.write_register.i32(metadata !8, i32 %x) - call void @llvm.write_register.i32(metadata !9, i32 %x) - call void @llvm.write_register.i32(metadata !10, i32 %x) - call void @llvm.write_register.i32(metadata !11, i32 %x) - call void @llvm.write_register.i32(metadata !12, i32 %x) - call void @llvm.write_register.i32(metadata !13, i32 %x) - call void @llvm.write_register.i32(metadata !14, i32 %x) - call void @llvm.write_register.i32(metadata !15, i32 %x) - ret void -} - -declare i32 @llvm.read_register.i32(metadata) nounwind -declare void @llvm.write_register.i32(metadata, i32) nounwind - -!0 = !{!"apsr"} -!1 = !{!"cpsr"} -!2 = !{!"spsr"} -!3 = !{!"apsr_nzcvq"} -!4 = !{!"apsr_g"} -!5 = !{!"apsr_nzcvqg"} -!6 = !{!"cpsr_c"} -!7 = !{!"cpsr_x"} -!8 = !{!"cpsr_s"} -!9 = !{!"cpsr_f"} -!10 = !{!"cpsr_cxsf"} -!11 = !{!"spsr_c"} -!12 = !{!"spsr_x"} -!13 = !{!"spsr_s"} -!14 = !{!"spsr_f"} -!15 = !{!"spsr_cxsf"} diff --git a/test/CodeGen/ARM/special-reg-mcore.ll b/test/CodeGen/ARM/special-reg-mcore.ll deleted file mode 100644 index 686da0f6b83..00000000000 --- a/test/CodeGen/ARM/special-reg-mcore.ll +++ /dev/null @@ -1,143 +0,0 @@ -; RUN: llc < %s -mtriple=thumb-none-eabi -mcpu=cortex-m4 2>&1 | FileCheck %s --check-prefix=MCORE -; RUN: not llc < %s -mtriple=thumb-none-eabi -mcpu=cortex-m3 2>&1 | FileCheck %s --check-prefix=M3CORE -; RUN: not llc < %s -mtriple=arm-none-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s --check-prefix=ACORE - -; ACORE: LLVM ERROR: Invalid register name "control". -; M3CORE: LLVM ERROR: Invalid register name "control". - -define i32 @read_mclass_registers() nounwind { -entry: - ; MCORE-LABEL: read_mclass_registers: - ; MCORE: mrs r0, apsr - ; MCORE: mrs r1, iapsr - ; MCORE: mrs r1, eapsr - ; MCORE: mrs r1, xpsr - ; MCORE: mrs r1, ipsr - ; MCORE: mrs r1, epsr - ; MCORE: mrs r1, iepsr - ; MCORE: mrs r1, msp - ; MCORE: mrs r1, psp - ; MCORE: mrs r1, primask - ; MCORE: mrs r1, basepri - ; MCORE: mrs r1, basepri_max - ; MCORE: mrs r1, faultmask - ; MCORE: mrs r1, control - - %0 = call i32 @llvm.read_register.i32(metadata !0) - %1 = call i32 @llvm.read_register.i32(metadata !4) - %add1 = add i32 %1, %0 - %2 = call i32 @llvm.read_register.i32(metadata !8) - %add2 = add i32 %add1, %2 - %3 = call i32 @llvm.read_register.i32(metadata !12) - %add3 = add i32 %add2, %3 - %4 = call i32 @llvm.read_register.i32(metadata !16) - %add4 = add i32 %add3, %4 - %5 = call i32 @llvm.read_register.i32(metadata !17) - %add5 = add i32 %add4, %5 - %6 = call i32 @llvm.read_register.i32(metadata !18) - %add6 = add i32 %add5, %6 - %7 = call i32 @llvm.read_register.i32(metadata !19) - %add7 = add i32 %add6, %7 - %8 = call i32 @llvm.read_register.i32(metadata !20) - %add8 = add i32 %add7, %8 - %9 = call i32 @llvm.read_register.i32(metadata !21) - %add9 = add i32 %add8, %9 - %10 = call i32 @llvm.read_register.i32(metadata !22) - %add10 = add i32 %add9, %10 - %11 = call i32 @llvm.read_register.i32(metadata !23) - %add11 = add i32 %add10, %11 - %12 = call i32 @llvm.read_register.i32(metadata !24) - %add12 = add i32 %add11, %12 - %13 = call i32 @llvm.read_register.i32(metadata !25) - %add13 = add i32 %add12, %13 - ret i32 %add13 -} - -define void @write_mclass_registers(i32 %x) nounwind { -entry: - ; MCORE-LABEL: write_mclass_registers: - ; MCORE: msr apsr_nzcvqg, r0 - ; MCORE: msr apsr_nzcvq, r0 - ; MCORE: msr apsr_g, r0 - ; MCORE: msr apsr_nzcvqg, r0 - ; MCORE: msr iapsr_nzcvqg, r0 - ; MCORE: msr iapsr_nzcvq, r0 - ; MCORE: msr iapsr_g, r0 - ; MCORE: msr iapsr_nzcvqg, r0 - ; MCORE: msr eapsr_nzcvqg, r0 - ; MCORE: msr eapsr_nzcvq, r0 - ; MCORE: msr eapsr_g, r0 - ; MCORE: msr eapsr_nzcvqg, r0 - ; MCORE: msr xpsr_nzcvqg, r0 - ; MCORE: msr xpsr_nzcvq, r0 - ; MCORE: msr xpsr_g, r0 - ; MCORE: msr xpsr_nzcvqg, r0 - ; MCORE: msr ipsr, r0 - ; MCORE: msr epsr, r0 - ; MCORE: msr iepsr, r0 - ; MCORE: msr msp, r0 - ; MCORE: msr psp, r0 - ; MCORE: msr primask, r0 - ; MCORE: msr basepri, r0 - ; MCORE: msr basepri_max, r0 - ; MCORE: msr faultmask, r0 - ; MCORE: msr control, r0 - - call void @llvm.write_register.i32(metadata !0, i32 %x) - call void @llvm.write_register.i32(metadata !1, i32 %x) - call void @llvm.write_register.i32(metadata !2, i32 %x) - call void @llvm.write_register.i32(metadata !3, i32 %x) - call void @llvm.write_register.i32(metadata !4, i32 %x) - call void @llvm.write_register.i32(metadata !5, i32 %x) - call void @llvm.write_register.i32(metadata !6, i32 %x) - call void @llvm.write_register.i32(metadata !7, i32 %x) - call void @llvm.write_register.i32(metadata !8, i32 %x) - call void @llvm.write_register.i32(metadata !9, i32 %x) - call void @llvm.write_register.i32(metadata !10, i32 %x) - call void @llvm.write_register.i32(metadata !11, i32 %x) - call void @llvm.write_register.i32(metadata !12, i32 %x) - call void @llvm.write_register.i32(metadata !13, i32 %x) - call void @llvm.write_register.i32(metadata !14, i32 %x) - call void @llvm.write_register.i32(metadata !15, i32 %x) - call void @llvm.write_register.i32(metadata !16, i32 %x) - call void @llvm.write_register.i32(metadata !17, i32 %x) - call void @llvm.write_register.i32(metadata !18, i32 %x) - call void @llvm.write_register.i32(metadata !19, i32 %x) - call void @llvm.write_register.i32(metadata !20, i32 %x) - call void @llvm.write_register.i32(metadata !21, i32 %x) - call void @llvm.write_register.i32(metadata !22, i32 %x) - call void @llvm.write_register.i32(metadata !23, i32 %x) - call void @llvm.write_register.i32(metadata !24, i32 %x) - call void @llvm.write_register.i32(metadata !25, i32 %x) - ret void -} - -declare i32 @llvm.read_register.i32(metadata) nounwind -declare void @llvm.write_register.i32(metadata, i32) nounwind - -!0 = !{!"apsr"} -!1 = !{!"apsr_nzcvq"} -!2 = !{!"apsr_g"} -!3 = !{!"apsr_nzcvqg"} -!4 = !{!"iapsr"} -!5 = !{!"iapsr_nzcvq"} -!6 = !{!"iapsr_g"} -!7 = !{!"iapsr_nzcvqg"} -!8 = !{!"eapsr"} -!9 = !{!"eapsr_nzcvq"} -!10 = !{!"eapsr_g"} -!11 = !{!"eapsr_nzcvqg"} -!12 = !{!"xpsr"} -!13 = !{!"xpsr_nzcvq"} -!14 = !{!"xpsr_g"} -!15 = !{!"xpsr_nzcvqg"} -!16 = !{!"ipsr"} -!17 = !{!"epsr"} -!18 = !{!"iepsr"} -!19 = !{!"msp"} -!20 = !{!"psp"} -!21 = !{!"primask"} -!22 = !{!"basepri"} -!23 = !{!"basepri_max"} -!24 = !{!"faultmask"} -!25 = !{!"control"} diff --git a/test/CodeGen/ARM/special-reg.ll b/test/CodeGen/ARM/special-reg.ll deleted file mode 100644 index 7ccb490f5d4..00000000000 --- a/test/CodeGen/ARM/special-reg.ll +++ /dev/null @@ -1,78 +0,0 @@ -; RUN: llc < %s -mtriple=arm-none-eabi -mcpu=cortex-a8 2>&1 | FileCheck %s --check-prefix=ARM --check-prefix=ACORE -; RUN: llc < %s -mtriple=thumb-none-eabi -mcpu=cortex-m4 2>&1 | FileCheck %s --check-prefix=ARM --check-prefix=MCORE - -define i32 @read_i32_encoded_register() nounwind { -entry: -; ARM-LABEL: read_i32_encoded_register: -; ARM: mrc p1, #2, r0, c3, c4, #5 - %reg = call i32 @llvm.read_register.i32(metadata !0) - ret i32 %reg -} - -define i64 @read_i64_encoded_register() nounwind { -entry: -; ARM-LABEL: read_i64_encoded_register: -; ARM: mrrc p1, #2, r0, r1, c3 - %reg = call i64 @llvm.read_register.i64(metadata !1) - ret i64 %reg -} - -define i32 @read_apsr() nounwind { -entry: -; ARM-LABEL: read_apsr: -; ARM: mrs r0, apsr - %reg = call i32 @llvm.read_register.i32(metadata !2) - ret i32 %reg -} - -define i32 @read_fpscr() nounwind { -entry: -; ARM-LABEL: read_fpscr: -; ARM: vmrs r0, fpscr - %reg = call i32 @llvm.read_register.i32(metadata !3) - ret i32 %reg -} - -define void @write_i32_encoded_register(i32 %x) nounwind { -entry: -; ARM-LABEL: write_i32_encoded_register: -; ARM: mcr p1, #2, r0, c3, c4, #5 - call void @llvm.write_register.i32(metadata !0, i32 %x) - ret void -} - -define void @write_i64_encoded_register(i64 %x) nounwind { -entry: -; ARM-LABEL: write_i64_encoded_register: -; ARM: mcrr p1, #2, r0, r1, c3 - call void @llvm.write_register.i64(metadata !1, i64 %x) - ret void -} - -define void @write_apsr(i32 %x) nounwind { -entry: -; ARM-LABEL: write_apsr: -; ACORE: msr APSR_nzcvq, r0 -; MCORE: msr apsr_nzcvq, r0 - call void @llvm.write_register.i32(metadata !4, i32 %x) - ret void -} - -define void @write_fpscr(i32 %x) nounwind { -entry: -; ARM-LABEL: write_fpscr: -; ARM: vmsr fpscr, r0 - call void @llvm.write_register.i32(metadata !3, i32 %x) - ret void -} - -declare i32 @llvm.read_register.i32(metadata) nounwind -declare i64 @llvm.read_register.i64(metadata) nounwind -declare void @llvm.write_register.i32(metadata, i32) nounwind -declare void @llvm.write_register.i64(metadata, i64) nounwind - -!0 = !{!"cp1:2:c3:c4:5"} -!1 = !{!"cp1:2:c3"} -!2 = !{!"apsr"} -!3 = !{!"fpscr"} -!4 = !{!"apsr_nzcvq"} -- 2.34.1