Index: lib/Target/ARM/ARMISelDAGToDAG.cpp =================================================================== --- lib/Target/ARM/ARMISelDAGToDAG.cpp +++ lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "ARM.h" +#include "Utils/ARMBaseInfo.h" #include "ARMBaseInstrInfo.h" #include "ARMTargetMachine.h" #include "MCTargetDesc/ARMAddressingModes.h" @@ -3787,31 +3788,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 +3801,15 @@ .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)) - 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; - - // The _g and _nzcvqg versions are only valid if the DSP extension is - // available. - if (!Subtarget->hasDSP() && (Mask & 0x1)) +// 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) { + auto TheReg = ARMSysReg::lookupMClassSysRegByName(Reg); + const FeatureBitset &FeatureBits = Subtarget->getFeatureBits(); + if (!TheReg || !TheReg->hasRequiredFeatures(FeatureBits)) 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 (int)(TheReg->Encoding & 0xFFF); // SYSm value } static int getARClassRegisterMask(StringRef Reg, StringRef Flags) { @@ -4018,13 +3951,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 +4062,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 @@ -7,6 +7,8 @@ // //===----------------------------------------------------------------------===// +include "ARMSystemRegister.td" + //===----------------------------------------------------------------------===// // Declarations that describe the ARM register file //===----------------------------------------------------------------------===// Index: lib/Target/ARM/ARMSystemRegister.td =================================================================== --- /dev/null +++ lib/Target/ARM/ARMSystemRegister.td @@ -0,0 +1,108 @@ +//===-- ARMSystemRegister.td - ARM Register defs -------------*- tablegen -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +include "llvm/TableGen/SearchableTable.td" + +//===----------------------------------------------------------------------===// +// Declarations that describe the ARM system-registers +//===----------------------------------------------------------------------===// + +// M-Class System Registers. +// 'Mask' bits create unique keys for searches. +// [|i|e|x]apsr_nzcvq has alias [|i|e|x]apsr. +// +class MClassSysReg UniqMask1, + bits<1> UniqMask2, + bits<1> UniqMask3, + bits<12> Enc12, + string name> : SearchableTable { + let SearchableFields = ["Name", "M1Encoding12", "M2M3Encoding8", "Encoding"]; + string Name; + bits<13> M1Encoding12; + bits<10> M2M3Encoding8; + bits<12> Encoding; + + let Name = name; + let EnumValueField = "M1Encoding12"; + let EnumValueField = "M2M3Encoding8"; + let EnumValueField = "Encoding"; + + let M1Encoding12{12} = UniqMask1; + let M1Encoding12{11-00} = Enc12; + let Encoding = Enc12; + + let M2M3Encoding8{9} = UniqMask2; + let M2M3Encoding8{8} = UniqMask3; + let M2M3Encoding8{7-0} = Enc12{7-0}; + code Requires = [{ {} }]; +} + +let Requires = [{ {ARM::FeatureDSP} }] in { +// Mask1 Mask2 Mask3 Enc12, Name +def : MClassSysReg<0, 0, 0, 0x400, "apsr_g">; +def : MClassSysReg<0, 1, 1, 0xc00, "apsr_nzcvqg">; +def : MClassSysReg<0, 0, 0, 0x401, "iapsr_g">; +def : MClassSysReg<0, 1, 1, 0xc01, "iapsr_nzcvqg">; +def : MClassSysReg<0, 0, 0, 0x402, "eapsr_g">; +def : MClassSysReg<0, 1, 1, 0xc02, "eapsr_nzcvqg">; +def : MClassSysReg<0, 0, 0, 0x403, "xpsr_g">; +def : MClassSysReg<0, 1, 1, 0xc03, "xpsr_nzcvqg">; +} + +def : MClassSysReg<0, 0, 1, 0x800, "apsr">; +def : MClassSysReg<1, 1, 0, 0x800, "apsr_nzcvq">; +def : MClassSysReg<0, 0, 1, 0x801, "iapsr">; +def : MClassSysReg<1, 1, 0, 0x801, "iapsr_nzcvq">; +def : MClassSysReg<0, 0, 1, 0x802, "eapsr">; +def : MClassSysReg<1, 1, 0, 0x802, "eapsr_nzcvq">; +def : MClassSysReg<0, 0, 1, 0x803, "xpsr">; +def : MClassSysReg<1, 1, 0, 0x803, "xpsr_nzcvq">; + +def : MClassSysReg<0, 0, 1, 0x805, "ipsr">; +def : MClassSysReg<0, 0, 1, 0x806, "epsr">; +def : MClassSysReg<0, 0, 1, 0x807, "iepsr">; +def : MClassSysReg<0, 0, 1, 0x808, "msp">; +def : MClassSysReg<0, 0, 1, 0x809, "psp">; + +let Requires = [{ {ARM::HasV8MBaselineOps} }] in { +def : MClassSysReg<0, 0, 1, 0x80a, "msplim">; // exists only on v8M +def : MClassSysReg<0, 0, 1, 0x80b, "psplim">; // exists only on v8M +} + +def : MClassSysReg<0, 0, 1, 0x810, "primask">; // always implemented + +let Requires = [{ {ARM::HasV7Ops} }] in { +def : MClassSysReg<0, 0, 1, 0x811, "basepri">; // v7M, and v8MMainExt +def : MClassSysReg<0, 0, 1, 0x812, "basepri_max">; +def : MClassSysReg<0, 0, 1, 0x813, "faultmask">; +} + +def : MClassSysReg<0, 0, 1, 0x814, "control">; // always implemented + +let Requires = [{ {ARM::Feature8MSecExt} }] in { +def : MClassSysReg<0, 0, 1, 0x888, "msp_ns">; +def : MClassSysReg<0, 0, 1, 0x889, "psp_ns">; +} + +let Requires = [{ {ARM::Feature8MSecExt, ARM::HasV8MBaselineOps} }] in { +def : MClassSysReg<0, 0, 1, 0x88a, "msplim_ns">; // exists only on v8M +def : MClassSysReg<0, 0, 1, 0x88b, "psplim_ns">; // exists only on v8M +} + +def : MClassSysReg<0, 0, 1, 0x890, "primask_ns">; + +let Requires = [{ {ARM::Feature8MSecExt, ARM::HasV7Ops} }] in { +def : MClassSysReg<0, 0, 1, 0x891, "basepri_ns">; +def : MClassSysReg<0, 0, 1, 0x893, "faultmask_ns">; +} + +let Requires = [{ {ARM::Feature8MSecExt} }] in { +def : MClassSysReg<0, 0, 1, 0x894, "control_ns">; +def : MClassSysReg<0, 0, 1, 0x898, "sp_ns">; +} Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp =================================================================== --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -8,6 +8,7 @@ //===----------------------------------------------------------------------===// #include "ARMFeatures.h" +#include "Utils/ARMBaseInfo.h" #include "MCTargetDesc/ARMAddressingModes.h" #include "MCTargetDesc/ARMBaseInfo.h" #include "MCTargetDesc/ARMMCExpr.h" @@ -4089,81 +4090,14 @@ StringRef Mask = Tok.getString(); if (isMClass()) { - // See ARMv6-M 10.1.1 - std::string Name = Mask.lower(); - unsigned FlagsVal = StringSwitch(Name) - // Note: in the documentation: - // ARM deprecates using MSR APSR without a _ qualifier as an alias - // for MSR APSR_nzcvq. - // but we do make it an alias here. This is so to get the "mask encoding" - // bits correct on MSR APSR writes. - // - // FIXME: Note the 0xc00 "mask encoding" bits version of the registers - // 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) - .Default(~0U); - - if (FlagsVal == ~0U) + auto TheReg = ARMSysReg::lookupMClassSysRegByName(Mask.lower()); + if (!TheReg || !TheReg->hasRequiredFeatures(getSTI().getFeatureBits())) 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; - - if (!has8MSecExt() && (FlagsVal == 0x80a || FlagsVal == 0x80b || - (FlagsVal > 0x814 && FlagsVal < 0xc00))) - return MatchOperand_NoMatch; - - if (!hasV8MMainline() && (FlagsVal == 0x88a || FlagsVal == 0x88b || - (FlagsVal > 0x890 && FlagsVal <= 0x893))) - return MatchOperand_NoMatch; + unsigned SYSmvalue = TheReg->Encoding & 0xFFF; 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/AsmParser/LLVMBuild.txt =================================================================== --- lib/Target/ARM/AsmParser/LLVMBuild.txt +++ lib/Target/ARM/AsmParser/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = ARMAsmParser parent = ARM -required_libraries = ARMDesc ARMInfo MC MCParser Support +required_libraries = ARMDesc ARMInfo MC MCParser Support ARMUtils add_to_library_groups = ARM Index: lib/Target/ARM/CMakeLists.txt =================================================================== --- lib/Target/ARM/CMakeLists.txt +++ lib/Target/ARM/CMakeLists.txt @@ -15,6 +15,7 @@ tablegen(LLVM ARMGenCallingConv.inc -gen-callingconv) tablegen(LLVM ARMGenSubtargetInfo.inc -gen-subtarget) tablegen(LLVM ARMGenDisassemblerTables.inc -gen-disassembler) +tablegen(LLVM ARMGenSystemRegister.inc -gen-searchable-tables) add_public_tablegen_target(ARMCommonTableGen) # Add GlobalISel files if the user wants to build it. @@ -73,3 +74,4 @@ add_subdirectory(Disassembler) add_subdirectory(InstPrinter) add_subdirectory(MCTargetDesc) +add_subdirectory(Utils) Index: lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp =================================================================== --- lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -12,6 +12,9 @@ //===----------------------------------------------------------------------===// #include "ARMInstPrinter.h" +#include "Utils/ARMBaseInfo.h" +#include "ARMBaseRegisterInfo.h" +#include "ARMBaseRegisterInfo.h" #include "MCTargetDesc/ARMAddressingModes.h" #include "MCTargetDesc/ARMBaseInfo.h" #include "llvm/MC/MCAsmInfo.h" @@ -789,152 +792,48 @@ 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 SYSm = Op.getImm() & 0xFFF; // 12-bit SYSm unsigned Opcode = MI->getOpcode(); // For writes, handle extended mask bits if the DSP extension is present. if (Opcode == ARM::t2MSR_M && FeatureBits[ARM::FeatureDSP]) { - switch (SYSm) { - case 0x400: - O << "apsr_g"; - return; - case 0xc00: - O << "apsr_nzcvqg"; - return; - case 0x401: - O << "iapsr_g"; - return; - case 0xc01: - O << "iapsr_nzcvqg"; - return; - case 0x402: - O << "eapsr_g"; - return; - case 0xc02: - O << "eapsr_nzcvqg"; - return; - case 0x403: - O << "xpsr_g"; - return; - case 0xc03: - O << "xpsr_nzcvqg"; - return; + auto TheReg =ARMSysReg::lookupMClassSysRegBy12bitSYSmValue(SYSm); + if (TheReg->isInRequiredFeatures({ARM::FeatureDSP})) { + O << TheReg->Name; + return; } } // Handle the basic 8-bit mask. SYSm &= 0xff; - 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: - O << "apsr_nzcvq"; - return; - case 1: - O << "iapsr_nzcvq"; - return; - case 2: - O << "eapsr_nzcvq"; - return; - case 3: - O << "xpsr_nzcvq"; - return; + auto TheReg = ARMSysReg::lookupMClassSysRegAPSRNonDeprecated(SYSm); + if (TheReg) { + O << TheReg->Name; + return; } } - switch (SYSm) { - default: - llvm_unreachable("Unexpected mask value!"); - case 0: - O << "apsr"; - return; - case 1: - O << "iapsr"; - return; - case 2: - O << "eapsr"; - return; - case 3: - O << "xpsr"; - return; - case 5: - O << "ipsr"; - return; - case 6: - O << "epsr"; - return; - case 7: - O << "iepsr"; - return; - case 8: - O << "msp"; - return; - case 9: - O << "psp"; - return; - case 16: - O << "primask"; - return; - case 17: - O << "basepri"; - return; - case 18: - O << "basepri_max"; - return; - case 19: - O << "faultmask"; - return; - case 20: - O << "control"; - return; - case 10: - O << "msplim"; - return; - case 11: - O << "psplim"; - return; - case 0x88: - O << "msp_ns"; - return; - case 0x89: - O << "psp_ns"; - return; - case 0x8a: - O << "msplim_ns"; - return; - case 0x8b: - O << "psplim_ns"; - return; - case 0x90: - O << "primask_ns"; - return; - case 0x91: - O << "basepri_ns"; - return; - case 0x92: - O << "basepri_max_ns"; - return; - case 0x93: - O << "faultmask_ns"; - return; - case 0x94: - O << "control_ns"; - return; - case 0x98: - O << "sp_ns"; + auto TheReg = ARMSysReg::lookupMClassSysRegBy8bitSYSmValue(SYSm); + if (TheReg) { + O << TheReg->Name; return; } + + 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: lib/Target/ARM/InstPrinter/LLVMBuild.txt =================================================================== --- lib/Target/ARM/InstPrinter/LLVMBuild.txt +++ lib/Target/ARM/InstPrinter/LLVMBuild.txt @@ -19,5 +19,5 @@ type = Library name = ARMAsmPrinter parent = ARM -required_libraries = MC Support +required_libraries = MC Support ARMUtils add_to_library_groups = ARM Index: lib/Target/ARM/LLVMBuild.txt =================================================================== --- lib/Target/ARM/LLVMBuild.txt +++ lib/Target/ARM/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo +subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo Utils [component_0] type = TargetGroup @@ -31,5 +31,5 @@ type = Library name = ARMCodeGen parent = ARM -required_libraries = ARMAsmPrinter ARMDesc ARMInfo Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target GlobalISel +required_libraries = ARMAsmPrinter ARMDesc ARMInfo Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target GlobalISel ARMUtils add_to_library_groups = ARM Index: lib/Target/ARM/Utils/ARMBaseInfo.h =================================================================== --- /dev/null +++ lib/Target/ARM/Utils/ARMBaseInfo.h @@ -0,0 +1,64 @@ +//===-- ARMBaseInfo.h - Top level definitions for ARM ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file contains small standalone helper functions and enum definitions for +// the ARM target useful for the compiler back-end and the MC libraries. +// As such, it deliberately does not include references to LLVM core +// code gen types, passes, etc.. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H +#define LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H + +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/MC/SubtargetFeature.h" +#include "MCTargetDesc/ARMMCTargetDesc.h" + +namespace llvm { + +namespace ARMSysReg { + struct MClassSysReg { + const char *Name; + uint16_t M1Encoding12; + uint16_t M2M3Encoding8; + uint16_t Encoding; + FeatureBitset FeaturesRequired; + + // return true if FeaturesRequired are all present in ActiveFeatures + bool hasRequiredFeatures(FeatureBitset ActiveFeatures) const { + return (FeaturesRequired & ActiveFeatures) == FeaturesRequired; + } + + // returns true if TestFeatures are all present in FeaturesRequired + bool isInRequiredFeatures(FeatureBitset TestFeatures) const { + return (FeaturesRequired & TestFeatures) == TestFeatures; + } + }; + + #define GET_MCLASSSYSREG_DECL + #include "ARMGenSystemRegister.inc" + + // lookup system register using 12-bit SYSm value. + // Note: the search is uniqued using M1 mask + const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm); + + // returns APSR with _ qualifier. + // Note: ARMv7-M deprecates using MSR APSR without a _ qualifier + const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm); + + // lookup system registers using 8-bit SYSm value + const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm); + +} // end namespace ARMSysReg + +} // end namespace llvm + +#endif // LLVM_LIB_TARGET_ARM_UTILS_ARMBASEINFO_H Index: lib/Target/ARM/Utils/ARMBaseInfo.cpp =================================================================== --- /dev/null +++ lib/Target/ARM/Utils/ARMBaseInfo.cpp @@ -0,0 +1,44 @@ +//===-- ARMBaseInfo.cpp - ARM Base encoding information------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file provides basic encoding and assembly information for ARM. +// +//===----------------------------------------------------------------------===// +#include "ARMBaseInfo.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Regex.h" + +using namespace llvm; +namespace llvm { + namespace ARMSysReg { + +// lookup system register using 12-bit SYSm value. +// Note: the search is uniqued using M1 mask +const MClassSysReg *lookupMClassSysRegBy12bitSYSmValue(unsigned SYSm) { + return lookupMClassSysRegByM1Encoding12(SYSm); +} + +// returns APSR with _ qualifier. +// Note: ARMv7-M deprecates using MSR APSR without a _ qualifier +const MClassSysReg *lookupMClassSysRegAPSRNonDeprecated(unsigned SYSm) { + return lookupMClassSysRegByM2M3Encoding8((1<<9)|(SYSm & 0xFF)); +} + +// lookup system registers using 8-bit SYSm value +const MClassSysReg *lookupMClassSysRegBy8bitSYSmValue(unsigned SYSm) { + return ARMSysReg::lookupMClassSysRegByM2M3Encoding8((1<<8)|(SYSm & 0xFF)); +} + +#define GET_MCLASSSYSREG_IMPL +#include "ARMGenSystemRegister.inc" + + } +} Index: lib/Target/ARM/Utils/CMakeLists.txt =================================================================== --- /dev/null +++ lib/Target/ARM/Utils/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_library(LLVMARMUtils + ARMBaseInfo.cpp + ) Index: lib/Target/ARM/Utils/LLVMBuild.txt =================================================================== --- /dev/null +++ lib/Target/ARM/Utils/LLVMBuild.txt @@ -0,0 +1,24 @@ +;===- ./lib/Target/ARM/Utils/LLVMBuild.txt ----------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Library +name = ARMUtils +parent = ARM +required_libraries = Support +add_to_library_groups = ARM + 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