Index: lib/Target/ARM/ARMISelDAGToDAG.cpp =================================================================== --- lib/Target/ARM/ARMISelDAGToDAG.cpp +++ lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -3787,31 +3787,6 @@ .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) - .Case("msplim", 0x0a) - .Case("psplim", 0x0b) - .Case("sp", 0x18) - .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. @@ -3825,58 +3800,90 @@ .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 (Subtarget->has8MSecExt() && Flags.lower() == "ns") { - Flags = ""; - SYSmvalue |= 0x80; - } - - if (!Subtarget->has8MSecExt() && - (SYSmvalue == 0xa || SYSmvalue == 0xb || SYSmvalue > 0x14)) - return -1; - - if (!Subtarget->hasV8MMainlineOps() && - (SYSmvalue == 0x8a || SYSmvalue == 0x8b || SYSmvalue == 0x91 || - SYSmvalue == 0x93)) +// Maps MClass special registers 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 int getMClassRegisterMask(StringRef Reg, const ARMSubtarget *Subtarget) { + int RegNo = StringSwitch(Reg.lower()) + .Case("apsr_g", ARM::SYS_REG_APSR_G) + .Case("apsr", ARM::SYS_REG_APSR) + .Case("apsr_nzcvq", ARM::SYS_REG_APSR_NZCVQ) + .Case("apsr_nzcvqg", ARM::SYS_REG_APSR_NZCVQG) + + .Case("iapsr_g", ARM::SYS_REG_IAPSR_G) + .Case("iapsr", ARM::SYS_REG_IAPSR) + .Case("iapsr_nzcvq", ARM::SYS_REG_IAPSR_NZCVQ) + .Case("iapsr_nzcvqg", ARM::SYS_REG_IAPSR_NZCVQG) + + .Case("eapsr_g", ARM::SYS_REG_EAPSR_G) + .Case("eapsr", ARM::SYS_REG_EAPSR) + .Case("eapsr_nzcvq", ARM::SYS_REG_EAPSR_NZCVQ) + .Case("eapsr_nzcvqg", ARM::SYS_REG_EAPSR_NZCVQG) + + .Case("xpsr_g", ARM::SYS_REG_XPSR_G) + .Case("xpsr", ARM::SYS_REG_XPSR) + .Case("xpsr_nzcvq", ARM::SYS_REG_XPSR_NZCVQ) + .Case("xpsr_nzcvqg", ARM::SYS_REG_XPSR_NZCVQG) + + .Case("ipsr", ARM::SYS_REG_IPSR) + .Case("epsr", ARM::SYS_REG_EPSR) + .Case("iepsr", ARM::SYS_REG_IEPSR) + + .Case("msp", ARM::SYS_REG_MSP) + .Case("psp", ARM::SYS_REG_PSP) + .Case("msplim", ARM::SYS_REG_MSPLIM) + .Case("psplim", ARM::SYS_REG_PSPLIM) + .Case("primask", ARM::SYS_REG_PRIMASK) + .Case("basepri", ARM::SYS_REG_BASEPRI) + .Case("basepri_max", ARM::SYS_REG_BASEPRI_MAX) + .Case("faultmask", ARM::SYS_REG_FAULTMASK) + .Case("control", ARM::SYS_REG_CONTROL) + + .Case("msp_ns", ARM::SYS_REG_MSP_NS) + .Case("psp_ns", ARM::SYS_REG_PSP_NS) + .Case("msplim_ns", ARM::SYS_REG_MSPLIM_NS) + .Case("psplim_ns", ARM::SYS_REG_PSPLIM_NS) + .Case("primask_ns", ARM::SYS_REG_PRIMASK_NS) + .Case("basepri_ns", ARM::SYS_REG_BASEPRI_NS) + .Case("faultmask_ns", ARM::SYS_REG_FAULTMASK_NS) + .Case("control_ns", ARM::SYS_REG_CONTROL_NS) + .Case("sp_ns", ARM::SYS_REG_SP_NS) + .Default(-1); + + if (RegNo == -1) 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) { - if (Flags.empty()) - return SYSmvalue; - else - return -1; - } - - // 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; + const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo(); + int HWReqAndSYSmvalue = TRI->getEncodingValue(RegNo); + int SYSmvalue = HWReqAndSYSmvalue & 0xFFF; + int HWReq = HWReqAndSYSmvalue >> 12; + + switch (RegNo) { + case ARM::SYS_REG_APSR_G: + case ARM::SYS_REG_APSR_NZCVQG: + case ARM::SYS_REG_IAPSR_G: + case ARM::SYS_REG_IAPSR_NZCVQG: + case ARM::SYS_REG_EAPSR_G: + case ARM::SYS_REG_EAPSR_NZCVQG: + case ARM::SYS_REG_XPSR_G: + case ARM::SYS_REG_XPSR_NZCVQG: + if ( !Subtarget->hasDSP()) + return -1; + default : ; // proceeed + } + + enum { + NeedsV7M = 0x1, + NeedsV8M = 0x2, + NeedsSecExt = 0x4 + }; - // The _g and _nzcvqg versions are only valid if the DSP extension is - // available. - if (!Subtarget->hasDSP() && (Mask & 0x1)) - return -1; + if (((HWReq & NeedsV7M) && !Subtarget->hasV7Ops()) || + ((HWReq & NeedsV8M) && !Subtarget->hasV8MBaselineOps()) || + ((HWReq & NeedsSecExt) && !Subtarget->has8MSecExt())) + 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. - return SYSmvalue | Mask << 10; + return SYSmvalue; } static int getARClassRegisterMask(StringRef Reg, StringRef Flags) { @@ -4018,13 +4025,7 @@ // is an acceptable value, so check that a mask can be constructed from the // string. if (Subtarget->isMClass()) { - StringRef Flags = "", Reg = SpecialReg; - if (Reg.endswith("_ns")) { - Flags = "ns"; - Reg = Reg.drop_back(3); - } - - int SYSmValue = getMClassRegisterMask(Reg, Flags, true, Subtarget); + int SYSmValue = getMClassRegisterMask(SpecialReg, Subtarget); if (SYSmValue == -1) return false; @@ -4135,12 +4136,7 @@ // 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); + int SYSmValue = getMClassRegisterMask(SpecialReg, Subtarget); if (SYSmValue == -1) return false; Index: lib/Target/ARM/ARMRegisterInfo.td =================================================================== --- lib/Target/ARM/ARMRegisterInfo.td +++ lib/Target/ARM/ARMRegisterInfo.td @@ -179,6 +179,67 @@ def FPINST : ARMReg<9, "fpinst">; def FPINST2 : ARMReg<10, "fpinst2">; + +// System Registers. +class ARMSysReg HWReq, bits<12> Enc, string n> : Register { + let HWEncoding{15-12} = HWReq; + let HWEncoding{11-00} = Enc; + let Namespace = "ARM"; +} + +// Some registers are implemented only with specific PE capabilities. +// These are encoded in HWReq as: +// - [NeedsSecExt:NeedsV8M:NeedsV7M] +def SYS_REG_APSR_G : ARMSysReg<0, 0x400, "sys_reg_apsr_g">; +def SYS_REG_APSR : ARMSysReg<0, 0x800, "sys_reg_apsr">; // alias for APSR_NZCVQ +def SYS_REG_APSR_NZCVQ : ARMSysReg<0, 0x800, "sys_reg_apsr_nzcvq">; +def SYS_REG_APSR_NZCVQG : ARMSysReg<0, 0xc00, "sys_reg_apsr_nzcvqg">; + + +def SYS_REG_IAPSR_G : ARMSysReg<0x0, 0x401, "sys_reg_iapsr_g">; +def SYS_REG_IAPSR : ARMSysReg<0x0, 0x801, "sys_reg_iapsr">; +def SYS_REG_IAPSR_NZCVQ : ARMSysReg<0x0, 0x801, "sys_reg_iapsr_nzcvq">; +def SYS_REG_IAPSR_NZCVQG : ARMSysReg<0x0, 0xc01, "sys_reg_iapsr_nzcvqg">; + +def SYS_REG_EAPSR_G : ARMSysReg<0x0, 0x402, "sys_reg_eapsr_g">; +def SYS_REG_EAPSR : ARMSysReg<0x0, 0x802, "sys_reg_eapsr">; +def SYS_REG_EAPSR_NZCVQ : ARMSysReg<0x0, 0x802, "sys_reg_eapsr_nzcvq">; +def SYS_REG_EAPSR_NZCVQG : ARMSysReg<0x0, 0xc02, "sys_reg_eapsr_nzcvqg">; + +def SYS_REG_XPSR_G : ARMSysReg<0x0, 0x403, "sys_reg_xpsr_g">; +def SYS_REG_XPSR : ARMSysReg<0x0, 0x803, "sys_reg_xpsr">; +def SYS_REG_XPSR_NZCVQ : ARMSysReg<0x0, 0x803, "sys_reg_xpsr_nzcvq">; +def SYS_REG_XPSR_NZCVQG : ARMSysReg<0x0, 0xc03, "sys_reg_xpsr_nzcvqg">; + +def SYS_REG_IPSR : ARMSysReg<0x0, 0x805, "sys_reg_ipsr">; +def SYS_REG_EPSR : ARMSysReg<0x0, 0x806, "sys_reg_epsr">; +def SYS_REG_IEPSR : ARMSysReg<0x0, 0x807, "sys_reg_iepsr">; + +def SYS_REG_MSP : ARMSysReg<0x0, 0x808, "sys_reg_msp">; +def SYS_REG_PSP : ARMSysReg<0x0, 0x809, "sys_reg_psp">; + +def SYS_REG_MSPLIM : ARMSysReg<0x2, 0x80a, "sys_reg_msplim">; // exists only on v8M +def SYS_REG_PSPLIM : ARMSysReg<0x2, 0x80b, "sys_reg_psplim">; // exists only on v8M + +def SYS_REG_PRIMASK : ARMSysReg<0x0, 0x810, "sys_reg_primask">; // always implemented + +def SYS_REG_BASEPRI : ARMSysReg<0x1, 0x811, "sys_reg_basepri">; // exists only on v7M, and v8M MainExt +def SYS_REG_BASEPRI_MAX : ARMSysReg<0x1, 0x812, "sys_reg_basepri_max">; // exists only on v7M, and v8M MainExt + +def SYS_REG_FAULTMASK : ARMSysReg<0x1, 0x813, "sys_reg_faultmask">; // exists only on v7M, and v8M MainExt + +def SYS_REG_CONTROL : ARMSysReg<0x0, 0x814, "sys_reg_control">; + +def SYS_REG_MSP_NS : ARMSysReg<0x4, 0x888, "sys_reg_msp_ns">; // exists only with security-extension +def SYS_REG_PSP_NS : ARMSysReg<0x4, 0x889, "sys_reg_psp_ns">; +def SYS_REG_MSPLIM_NS : ARMSysReg<0x6, 0x88a, "sys_reg_msplim_ns">; +def SYS_REG_PSPLIM_NS : ARMSysReg<0x6, 0x88b, "sys_reg_psplim_ns">; +def SYS_REG_PRIMASK_NS : ARMSysReg<0x4, 0x890, "sys_reg_primask_ns">; +def SYS_REG_BASEPRI_NS : ARMSysReg<0x5, 0x891, "sys_reg_basepri_ns">; +def SYS_REG_FAULTMASK_NS : ARMSysReg<0x5, 0x893, "sys_reg_faultmask_ns">; +def SYS_REG_CONTROL_NS : ARMSysReg<0x4, 0x894, "sys_reg_control_ns">; +def SYS_REG_SP_NS : ARMSysReg<0x4, 0x898, "sys_reg_sp_ns">; + // Register classes. // // pc == Program Counter Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -4091,7 +4091,7 @@ if (isMClass()) { // See ARMv6-M 10.1.1 std::string Name = Mask.lower(); - unsigned FlagsVal = StringSwitch(Name) + unsigned RegNo = StringSwitch(Name) // Note: in the documentation: // ARM deprecates using MSR APSR without a _ qualifier as an alias // for MSR APSR_nzcvq. @@ -4102,68 +4102,91 @@ // should really only be allowed when writing a special register. Note // they get dropped in the MRS instruction reading a special register as // the SYSm field is only 8 bits. - .Case("apsr", 0x800) - .Case("apsr_nzcvq", 0x800) - .Case("apsr_g", 0x400) - .Case("apsr_nzcvqg", 0xc00) - .Case("iapsr", 0x801) - .Case("iapsr_nzcvq", 0x801) - .Case("iapsr_g", 0x401) - .Case("iapsr_nzcvqg", 0xc01) - .Case("eapsr", 0x802) - .Case("eapsr_nzcvq", 0x802) - .Case("eapsr_g", 0x402) - .Case("eapsr_nzcvqg", 0xc02) - .Case("xpsr", 0x803) - .Case("xpsr_nzcvq", 0x803) - .Case("xpsr_g", 0x403) - .Case("xpsr_nzcvqg", 0xc03) - .Case("ipsr", 0x805) - .Case("epsr", 0x806) - .Case("iepsr", 0x807) - .Case("msp", 0x808) - .Case("psp", 0x809) - .Case("primask", 0x810) - .Case("basepri", 0x811) - .Case("basepri_max", 0x812) - .Case("faultmask", 0x813) - .Case("control", 0x814) - .Case("msplim", 0x80a) - .Case("psplim", 0x80b) - .Case("msp_ns", 0x888) - .Case("psp_ns", 0x889) - .Case("msplim_ns", 0x88a) - .Case("psplim_ns", 0x88b) - .Case("primask_ns", 0x890) - .Case("basepri_ns", 0x891) - .Case("basepri_max_ns", 0x892) - .Case("faultmask_ns", 0x893) - .Case("control_ns", 0x894) - .Case("sp_ns", 0x898) + .Case("apsr_g", ARM::SYS_REG_APSR_G) + .Case("apsr", ARM::SYS_REG_APSR_NZCVQ) + .Case("apsr_nzcvq", ARM::SYS_REG_APSR_NZCVQ) + .Case("apsr_nzcvqg", ARM::SYS_REG_APSR_NZCVQG) + + .Case("iapsr_g", ARM::SYS_REG_IAPSR_G) + .Case("iapsr", ARM::SYS_REG_IAPSR_NZCVQ) + .Case("iapsr_nzcvq", ARM::SYS_REG_IAPSR_NZCVQ) + .Case("iapsr_nzcvqg", ARM::SYS_REG_IAPSR_NZCVQG) + + .Case("eapsr_g", ARM::SYS_REG_EAPSR_G) + .Case("eapsr", ARM::SYS_REG_EAPSR_NZCVQ) + .Case("eapsr_nzcvq", ARM::SYS_REG_EAPSR_NZCVQ) + .Case("eapsr_nzcvqg", ARM::SYS_REG_EAPSR_NZCVQG) + + .Case("xpsr_g", ARM::SYS_REG_XPSR_G) + .Case("xpsr", ARM::SYS_REG_XPSR_NZCVQ) + .Case("xpsr_nzcvq", ARM::SYS_REG_XPSR_NZCVQ) + .Case("xpsr_nzcvqg", ARM::SYS_REG_XPSR_NZCVQG) + + .Case("ipsr", ARM::SYS_REG_IPSR) + .Case("epsr", ARM::SYS_REG_EPSR) + .Case("iepsr", ARM::SYS_REG_IEPSR) + + .Case("msp", ARM::SYS_REG_MSP) + .Case("psp", ARM::SYS_REG_PSP) + + .Case("msplim", ARM::SYS_REG_MSPLIM) + .Case("psplim", ARM::SYS_REG_PSPLIM) + + .Case("primask", ARM::SYS_REG_PRIMASK) + + .Case("basepri", ARM::SYS_REG_BASEPRI) + .Case("basepri_max", ARM::SYS_REG_BASEPRI_MAX) + + .Case("faultmask", ARM::SYS_REG_FAULTMASK) + .Case("control", ARM::SYS_REG_CONTROL) + + .Case("msp_ns", ARM::SYS_REG_MSP_NS) + .Case("psp_ns", ARM::SYS_REG_PSP_NS) + .Case("msplim_ns", ARM::SYS_REG_MSPLIM_NS) + .Case("psplim_ns", ARM::SYS_REG_PSPLIM_NS) + .Case("primask_ns", ARM::SYS_REG_PRIMASK_NS) + .Case("basepri_ns", ARM::SYS_REG_BASEPRI_NS) + .Case("faultmask_ns", ARM::SYS_REG_FAULTMASK_NS) + .Case("control_ns", ARM::SYS_REG_CONTROL_NS) + .Case("sp_ns", ARM::SYS_REG_SP_NS) .Default(~0U); - if (FlagsVal == ~0U) + if (RegNo == ~0U) return MatchOperand_NoMatch; - if (!hasDSP() && (FlagsVal & 0x400)) - // The _g and _nzcvqg versions are only valid if the DSP extension is - // available. - return MatchOperand_NoMatch; - - if (!hasV7Ops() && FlagsVal >= 0x811 && FlagsVal <= 0x813) - // basepri, basepri_max and faultmask only valid for V7m. - return MatchOperand_NoMatch; + const MCRegisterInfo *MRI = getContext().getRegisterInfo(); + unsigned HWReqAndSYSmvalue = MRI->getEncodingValue(RegNo); + unsigned SYSmvalue = HWReqAndSYSmvalue & 0xFFF; + unsigned HWReq = HWReqAndSYSmvalue >> 12; + + // The _g and _nzcvqg versions are only valid if the DSP is present + switch (RegNo) { + case ARM::SYS_REG_APSR_G: + case ARM::SYS_REG_APSR_NZCVQG: + case ARM::SYS_REG_IAPSR_G: + case ARM::SYS_REG_IAPSR_NZCVQG: + case ARM::SYS_REG_EAPSR_G: + case ARM::SYS_REG_EAPSR_NZCVQG: + case ARM::SYS_REG_XPSR_G: + case ARM::SYS_REG_XPSR_NZCVQG: + if (!hasDSP()) + return MatchOperand_NoMatch; + default : ; // proceeed + } - if (!has8MSecExt() && (FlagsVal == 0x80a || FlagsVal == 0x80b || - (FlagsVal > 0x814 && FlagsVal < 0xc00))) - return MatchOperand_NoMatch; + enum { + NeedsV7M = 0x1, + NeedsV8M = 0x2, + NeedsSecExt = 0x4 + }; - if (!hasV8MMainline() && (FlagsVal == 0x88a || FlagsVal == 0x88b || - (FlagsVal > 0x890 && FlagsVal <= 0x893))) - return MatchOperand_NoMatch; + if (((HWReq & NeedsV7M) && !hasV7Ops()) || + ((HWReq & NeedsV8M) && !hasV8MBaseline()) || + ((HWReq & NeedsSecExt) && !has8MSecExt())) + return MatchOperand_NoMatch; Parser.Lex(); // Eat identifier token. - Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); + Operands.push_back(ARMOperand::CreateMSRMask(SYSmvalue, S)); return MatchOperand_Success; } Index: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp =================================================================== --- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -789,39 +789,42 @@ const MCSubtargetInfo &STI, raw_ostream &O) { const MCOperand &Op = MI->getOperand(OpNum); - unsigned SpecRegRBit = Op.getImm() >> 4; - unsigned Mask = Op.getImm() & 0xf; const FeatureBitset &FeatureBits = STI.getFeatureBits(); if (FeatureBits[ARM::FeatureMClass]) { unsigned SYSm = Op.getImm(); unsigned Opcode = MI->getOpcode(); + auto extractSysm = [=](unsigned Reg) { + return (unsigned)(MRI.getEncodingValue(Reg) & 0xFFF); }; + auto extractSysmB = [=](unsigned Reg) { + return (unsigned)(MRI.getEncodingValue(Reg) & 0xFF); }; + // For writes, handle extended mask bits if the DSP extension is present. if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) { - switch (SYSm) { - case 0x400: + + if (SYSm == extractSysm(ARM::SYS_REG_APSR_G)) { O << "apsr_g"; return; - case 0xc00: + } else if (SYSm == extractSysm(ARM::SYS_REG_APSR_NZCVQG)) { O << "apsr_nzcvqg"; return; - case 0x401: + } else if (SYSm == extractSysm(ARM::SYS_REG_IAPSR_G)) { O << "iapsr_g"; return; - case 0xc01: + } else if (SYSm == extractSysm(ARM::SYS_REG_IAPSR_NZCVQG)) { O << "iapsr_nzcvqg"; return; - case 0x402: + } else if (SYSm == extractSysm(ARM::SYS_REG_EAPSR_G)) { O << "eapsr_g"; return; - case 0xc02: + } else if (SYSm == extractSysm(ARM::SYS_REG_EAPSR_NZCVQG)) { O << "eapsr_nzcvqg"; return; - case 0x403: + } else if (SYSm == extractSysm(ARM::SYS_REG_XPSR_G)) { O << "xpsr_g"; return; - case 0xc03: + } else if (SYSm == extractSysm(ARM::SYS_REG_XPSR_NZCVQG)) { O << "xpsr_nzcvqg"; return; } @@ -833,108 +836,81 @@ if (Opcode == ARM::t2MSR_M && FeatureBits [ARM::HasV7Ops]) { // ARMv7-M deprecates using MSR APSR without a _ qualifier as an // alias for MSR APSR_nzcvq. - switch (SYSm) { - case 0: + if (SYSm == extractSysmB(ARM::SYS_REG_APSR_NZCVQ)) { O << "apsr_nzcvq"; return; - case 1: + } else if (SYSm == extractSysmB(ARM::SYS_REG_IAPSR_NZCVQ)) { O << "iapsr_nzcvq"; return; - case 2: + } else if (SYSm == extractSysmB(ARM::SYS_REG_EAPSR_NZCVQ)) { O << "eapsr_nzcvq"; return; - case 3: + } else if (SYSm == extractSysmB(ARM::SYS_REG_XPSR_NZCVQ)) { O << "xpsr_nzcvq"; return; } } - switch (SYSm) { - default: - llvm_unreachable("Unexpected mask value!"); - case 0: + if (SYSm == extractSysmB(ARM::SYS_REG_APSR)) { O << "apsr"; - return; - case 1: + } else if (SYSm == extractSysmB(ARM::SYS_REG_IAPSR)) { O << "iapsr"; - return; - case 2: + } else if (SYSm == extractSysmB(ARM::SYS_REG_EAPSR)) { O << "eapsr"; - return; - case 3: + } else if (SYSm == extractSysmB(ARM::SYS_REG_XPSR)) { O << "xpsr"; - return; - case 5: + } else if (SYSm == extractSysmB(ARM::SYS_REG_IPSR)) { O << "ipsr"; - return; - case 6: + } else if (SYSm == extractSysmB(ARM::SYS_REG_EPSR)) { O << "epsr"; - return; - case 7: + } else if (SYSm == extractSysmB(ARM::SYS_REG_IEPSR)) { O << "iepsr"; - return; - case 8: + } else if (SYSm == extractSysmB(ARM::SYS_REG_MSP)) { O << "msp"; - return; - case 9: + } else if (SYSm == extractSysmB(ARM::SYS_REG_PSP)) { O << "psp"; - return; - case 16: + } else if (SYSm == extractSysmB(ARM::SYS_REG_MSPLIM)) { + O << "msplim"; + } else if (SYSm == extractSysmB(ARM::SYS_REG_PSPLIM)) { + O << "psplim"; + } else if (SYSm == extractSysmB(ARM::SYS_REG_PRIMASK)) { O << "primask"; - return; - case 17: + } else if (SYSm == extractSysmB(ARM::SYS_REG_BASEPRI)) { O << "basepri"; - return; - case 18: + } else if (SYSm == extractSysmB(ARM::SYS_REG_BASEPRI_MAX)) { O << "basepri_max"; - return; - case 19: + } else if (SYSm == extractSysmB(ARM::SYS_REG_FAULTMASK)) { O << "faultmask"; - return; - case 20: + } else if (SYSm == extractSysmB(ARM::SYS_REG_CONTROL)) { O << "control"; - return; - case 10: - O << "msplim"; - return; - case 11: - O << "psplim"; - return; - case 0x88: + } else if (SYSm == extractSysmB(ARM::SYS_REG_MSP_NS)) { O << "msp_ns"; - return; - case 0x89: + } else if (SYSm == extractSysmB(ARM::SYS_REG_PSP_NS)) { O << "psp_ns"; - return; - case 0x8a: + } else if (SYSm == extractSysmB(ARM::SYS_REG_MSPLIM_NS)) { O << "msplim_ns"; - return; - case 0x8b: + } else if (SYSm == extractSysmB(ARM::SYS_REG_PSPLIM_NS)) { O << "psplim_ns"; - return; - case 0x90: + } else if (SYSm == extractSysmB(ARM::SYS_REG_PRIMASK_NS)) { O << "primask_ns"; - return; - case 0x91: + } else if (SYSm == extractSysmB(ARM::SYS_REG_BASEPRI_NS)) { O << "basepri_ns"; - return; - case 0x92: - O << "basepri_max_ns"; - return; - case 0x93: + } else if (SYSm == extractSysmB(ARM::SYS_REG_FAULTMASK_NS)) { O << "faultmask_ns"; - return; - case 0x94: + } else if (SYSm == extractSysmB(ARM::SYS_REG_CONTROL_NS)) { O << "control_ns"; - return; - case 0x98: + } else if (SYSm == extractSysmB(ARM::SYS_REG_SP_NS)) { O << "sp_ns"; - return; - } + } else + llvm_unreachable("Unexpected mask value!"); + return; } // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively. + unsigned SpecRegRBit = Op.getImm() >> 4; + unsigned Mask = Op.getImm() & 0xf; + if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) { O << "APSR_"; switch (Mask) { Index: test/CodeGen/ARM/special-reg-v8m-main.ll =================================================================== --- test/CodeGen/ARM/special-reg-v8m-main.ll +++ test/CodeGen/ARM/special-reg-v8m-main.ll @@ -1,7 +1,7 @@ ; RUN: not llc < %s -mtriple=thumbv8m.base-none-eabi 2>&1 | FileCheck %s --check-prefix=BASELINE ; RUN: llc < %s -mtriple=thumbv8m.main-none-eabi -mattr=+dsp 2>&1 | FileCheck %s --check-prefix=MAINLINE -; BASELINE: LLVM ERROR: Invalid register name "basepri_max_ns". +; BASELINE: LLVM ERROR: Invalid register name "faultmask_ns". define i32 @read_mclass_registers() nounwind { entry: @@ -31,7 +31,6 @@ ; MAINLINE: mrs r1, faultmask_ns ; MAINLINE: mrs r1, control_ns ; MAINLINE: mrs r1, sp_ns - ; MAINLINE: mrs r1, basepri_max_ns %0 = call i32 @llvm.read_register.i32(metadata !0) %1 = call i32 @llvm.read_register.i32(metadata !4) @@ -82,9 +81,7 @@ %add23 = add i32 %add22, %23 %24 = call i32 @llvm.read_register.i32(metadata !36) %add24 = add i32 %add23, %24 - %25 = call i32 @llvm.read_register.i32(metadata !37) - %add25 = add i32 %add24, %25 - ret i32 %add25 + ret i32 %add24 } define void @write_mclass_registers(i32 %x) nounwind { @@ -127,7 +124,6 @@ ; MAINLINE: msr faultmask_ns, r0 ; MAINLINE: msr control_ns, r0 ; MAINLINE: msr sp_ns, r0 - ; MAINLINE: msr basepri_max_ns, r0 call void @llvm.write_register.i32(metadata !0, i32 %x) call void @llvm.write_register.i32(metadata !1, i32 %x) @@ -166,7 +162,6 @@ call void @llvm.write_register.i32(metadata !34, i32 %x) call void @llvm.write_register.i32(metadata !35, i32 %x) call void @llvm.write_register.i32(metadata !36, i32 %x) - call void @llvm.write_register.i32(metadata !37, i32 %x) ret void } @@ -210,5 +205,4 @@ !34 = !{!"faultmask_ns"} !35 = !{!"control_ns"} !36 = !{!"sp_ns"} -!37 = !{!"basepri_max_ns"} Index: test/MC/ARM/thumbv8m.s =================================================================== --- test/MC/ARM/thumbv8m.s +++ test/MC/ARM/thumbv8m.s @@ -215,17 +215,12 @@ // CHECK: msr psplim, r9 @ encoding: [0x89,0xf3,0x0b,0x88] MRS r10, MSPLIM_NS -// CHECK-MAINLINE: mrs r10, msplim_ns @ encoding: [0xef,0xf3,0x8a,0x8a] -// UNDEF-BASELINE: error: invalid operand for instruction +// CHECK: mrs r10, msplim_ns @ encoding: [0xef,0xf3,0x8a,0x8a] MSR PSPLIM_NS, r11 -// CHECK-MAINLINE: msr psplim_ns, r11 @ encoding: [0x8b,0xf3,0x8b,0x88] -// UNDEF-BASELINE: error: invalid operand for instruction +// CHECK: msr psplim_ns, r11 @ encoding: [0x8b,0xf3,0x8b,0x88] MRS r12, BASEPRI_NS // CHECK-MAINLINE: mrs r12, basepri_ns @ encoding: [0xef,0xf3,0x91,0x8c] // UNDEF-BASELINE: error: invalid operand for instruction -MRS r12, BASEPRI_MAX_NS -// CHECK-MAINLINE: mrs r12, basepri_max_ns @ encoding: [0xef,0xf3,0x92,0x8c] -// UNDEF-BASELINE: error: invalid operand for instruction MSR FAULTMASK_NS, r14 // CHECK-MAINLINE: msr faultmask_ns, lr @ encoding: [0x8e,0xf3,0x93,0x88] // UNDEF-BASELINE: error: invalid operand for instruction