From 837d08454e3e5beb8581951ac26b22fa07df3cd5 Mon Sep 17 00:00:00 2001 From: Bradley Smith Date: Fri, 15 Jan 2016 10:28:03 +0000 Subject: [PATCH] [ARM] Add new system registers to ARMv8-M Baseline/Mainline git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257884 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMISelDAGToDAG.cpp | 39 ++++- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 26 +++ lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 18 ++ lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp | 36 ++++ test/CodeGen/ARM/special-reg-v8m-base.ll | 142 ++++++++++++++++ test/CodeGen/ARM/special-reg-v8m-main.ll | 214 ++++++++++++++++++++++++ test/MC/ARM/thumbv8m.s | 36 ++++ test/MC/Disassembler/ARM/thumb2-v8m.txt | 25 +++ 8 files changed, 529 insertions(+), 7 deletions(-) create mode 100644 test/CodeGen/ARM/special-reg-v8m-base.ll create mode 100644 test/CodeGen/ARM/special-reg-v8m-main.ll create mode 100644 test/MC/Disassembler/ARM/thumb2-v8m.txt diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index 4cb80da4839..9ffed031059 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -3444,6 +3444,9 @@ static inline int getMClassRegisterSYSmValueMask(StringRef RegString) { .Case("basepri_max", 0x12) .Case("faultmask", 0x13) .Case("control", 0x14) + .Case("msplim", 0x0a) + .Case("psplim", 0x0b) + .Case("sp", 0x18) .Default(-1); } @@ -3473,11 +3476,27 @@ static int getMClassRegisterMask(StringRef Reg, StringRef Flags, bool IsRead, 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) { - assert (Flags.empty() && "Unexpected flags for reading M class register."); - return SYSmvalue; + 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. @@ -3636,7 +3655,13 @@ SDNode *ARMDAGToDAGISel::SelectReadRegister(SDNode *N){ // is an acceptable value, so check that a mask can be constructed from the // string. if (Subtarget->isMClass()) { - int SYSmValue = getMClassRegisterMask(SpecialReg, "", true, Subtarget); + StringRef Flags = "", Reg = SpecialReg; + if (Reg.endswith("_ns")) { + Flags = "ns"; + Reg = Reg.drop_back(3); + } + + int SYSmValue = getMClassRegisterMask(Reg, Flags, true, Subtarget); if (SYSmValue == -1) return nullptr; @@ -3730,10 +3755,10 @@ SDNode *ARMDAGToDAGISel::SelectWriteRegister(SDNode *N){ 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] : ""; + std::pair Fields; + Fields = StringRef(SpecialReg).rsplit('_'); + std::string Reg = Fields.first.str(); + StringRef Flags = Fields.second; // If the target was M Class then need to validate the special register value // and retrieve the mask for use in the instruction node. diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 277304d5634..fb72b20154f 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -272,6 +272,12 @@ class ARMAsmParser : public MCTargetAsmParser { bool hasV8MBaseline() const { return getSTI().getFeatureBits()[ARM::HasV8MBaselineOps]; } + bool hasV8MMainline() const { + return getSTI().getFeatureBits()[ARM::HasV8MMainlineOps]; + } + bool has8MSecExt() const { + return getSTI().getFeatureBits()[ARM::Feature8MSecExt]; + } bool hasARM() const { return !getSTI().getFeatureBits()[ARM::FeatureNoARM]; } @@ -3972,6 +3978,18 @@ ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) { .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) @@ -3986,6 +4004,14 @@ ARMAsmParser::parseMSRMaskOperand(OperandVector &Operands) { // 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; + Parser.Lex(); // Eat identifier token. Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S)); return MatchOperand_Success; diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index e63defed228..db255cf2233 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -4096,6 +4096,24 @@ static DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val, // Values basepri, basepri_max and faultmask are only valid for v7m. return MCDisassembler::Fail; break; + case 0x8a: // msplim_ns + case 0x8b: // psplim_ns + case 0x91: // basepri_ns + case 0x92: // basepri_max_ns + case 0x93: // faultmask_ns + if (!(FeatureBits[ARM::HasV8MMainlineOps])) + return MCDisassembler::Fail; + // fall through + case 10: // msplim + case 11: // psplim + case 0x88: // msp_ns + case 0x89: // psp_ns + case 0x90: // primask_ns + case 0x94: // control_ns + case 0x98: // sp_ns + if (!(FeatureBits[ARM::Feature8MSecExt])) + return MCDisassembler::Fail; + break; default: return MCDisassembler::Fail; } diff --git a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp index 33fc85af9b1..a18c24c1107 100644 --- a/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp +++ b/lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp @@ -901,6 +901,42 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum, 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"; + return; } } diff --git a/test/CodeGen/ARM/special-reg-v8m-base.ll b/test/CodeGen/ARM/special-reg-v8m-base.ll new file mode 100644 index 00000000000..20284daa046 --- /dev/null +++ b/test/CodeGen/ARM/special-reg-v8m-base.ll @@ -0,0 +1,142 @@ +; RUN: not llc < %s -mtriple=thumb-none-eabi -mcpu=cortex-m4 2>&1 | FileCheck %s --check-prefix=V7M +; RUN: llc < %s -mtriple=thumbv8m.base-none-eabi 2>&1 | FileCheck %s + +; V7M: LLVM ERROR: Invalid register name "sp_ns". + +define i32 @read_mclass_registers() nounwind { +entry: + ; CHECK-LABEL: read_mclass_registers: + ; CHECK: mrs r0, apsr + ; CHECK: mrs r1, iapsr + ; CHECK: mrs r1, eapsr + ; CHECK: mrs r1, xpsr + ; CHECK: mrs r1, ipsr + ; CHECK: mrs r1, epsr + ; CHECK: mrs r1, iepsr + ; CHECK: mrs r1, msp + ; CHECK: mrs r1, psp + ; CHECK: mrs r1, primask + ; CHECK: mrs r1, control + ; CHECK: mrs r1, msplim + ; CHECK: mrs r1, psplim + ; CHECK: mrs r1, msp_ns + ; CHECK: mrs r1, psp_ns + ; CHECK: mrs r1, primask_ns + ; CHECK: mrs r1, control_ns + ; CHECK: mrs r1, sp_ns + + %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 !25) + %add10 = add i32 %add9, %10 + %11 = call i32 @llvm.read_register.i32(metadata !26) + %add11 = add i32 %add10, %11 + %12 = call i32 @llvm.read_register.i32(metadata !27) + %add12 = add i32 %add11, %12 + %13 = call i32 @llvm.read_register.i32(metadata !28) + %add13 = add i32 %add12, %13 + %14 = call i32 @llvm.read_register.i32(metadata !29) + %add14 = add i32 %add13, %14 + %15 = call i32 @llvm.read_register.i32(metadata !32) + %add15 = add i32 %add14, %15 + %16 = call i32 @llvm.read_register.i32(metadata !35) + %add16 = add i32 %add15, %16 + %17 = call i32 @llvm.read_register.i32(metadata !36) + %add17 = add i32 %add16, %17 + ret i32 %add10 +} + +define void @write_mclass_registers(i32 %x) nounwind { +entry: + ; CHECK-LABEL: write_mclass_registers: + ; CHECK: msr apsr, r0 + ; CHECK: msr apsr, r0 + ; CHECK: msr iapsr, r0 + ; CHECK: msr iapsr, r0 + ; CHECK: msr eapsr, r0 + ; CHECK: msr eapsr, r0 + ; CHECK: msr xpsr, r0 + ; CHECK: msr xpsr, r0 + ; CHECK: msr ipsr, r0 + ; CHECK: msr epsr, r0 + ; CHECK: msr iepsr, r0 + ; CHECK: msr msp, r0 + ; CHECK: msr psp, r0 + ; CHECK: msr primask, r0 + ; CHECK: msr control, r0 + ; CHECK: msr msplim, r0 + ; CHECK: msr psplim, r0 + ; CHECK: msr msp_ns, r0 + ; CHECK: msr psp_ns, r0 + ; CHECK: msr primask_ns, r0 + ; CHECK: msr control_ns, r0 + ; CHECK: msr sp_ns, 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 !4, i32 %x) + call void @llvm.write_register.i32(metadata !5, 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 !12, i32 %x) + call void @llvm.write_register.i32(metadata !13, 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 !25, i32 %x) + call void @llvm.write_register.i32(metadata !26, i32 %x) + call void @llvm.write_register.i32(metadata !27, i32 %x) + call void @llvm.write_register.i32(metadata !28, i32 %x) + call void @llvm.write_register.i32(metadata !29, i32 %x) + call void @llvm.write_register.i32(metadata !32, i32 %x) + call void @llvm.write_register.i32(metadata !35, i32 %x) + call void @llvm.write_register.i32(metadata !36, 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"} +!4 = !{!"iapsr"} +!5 = !{!"iapsr_nzcvq"} +!8 = !{!"eapsr"} +!9 = !{!"eapsr_nzcvq"} +!12 = !{!"xpsr"} +!13 = !{!"xpsr_nzcvq"} +!16 = !{!"ipsr"} +!17 = !{!"epsr"} +!18 = !{!"iepsr"} +!19 = !{!"msp"} +!20 = !{!"psp"} +!21 = !{!"primask"} +!25 = !{!"control"} +!26 = !{!"msplim"} +!27 = !{!"psplim"} +!28 = !{!"msp_ns"} +!29 = !{!"psp_ns"} +!32 = !{!"primask_ns"} +!35 = !{!"control_ns"} +!36 = !{!"sp_ns"} + diff --git a/test/CodeGen/ARM/special-reg-v8m-main.ll b/test/CodeGen/ARM/special-reg-v8m-main.ll new file mode 100644 index 00000000000..cde296c6b21 --- /dev/null +++ b/test/CodeGen/ARM/special-reg-v8m-main.ll @@ -0,0 +1,214 @@ +; 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". + +define i32 @read_mclass_registers() nounwind { +entry: + ; MAINLINE-LABEL: read_mclass_registers: + ; MAINLINE: mrs r0, apsr + ; MAINLINE: mrs r1, iapsr + ; MAINLINE: mrs r1, eapsr + ; MAINLINE: mrs r1, xpsr + ; MAINLINE: mrs r1, ipsr + ; MAINLINE: mrs r1, epsr + ; MAINLINE: mrs r1, iepsr + ; MAINLINE: mrs r1, msp + ; MAINLINE: mrs r1, psp + ; MAINLINE: mrs r1, primask + ; MAINLINE: mrs r1, basepri + ; MAINLINE: mrs r1, basepri_max + ; MAINLINE: mrs r1, faultmask + ; MAINLINE: mrs r1, control + ; MAINLINE: mrs r1, msplim + ; MAINLINE: mrs r1, psplim + ; MAINLINE: mrs r1, msp_ns + ; MAINLINE: mrs r1, psp_ns + ; MAINLINE: mrs r1, msplim_ns + ; MAINLINE: mrs r1, psplim_ns + ; MAINLINE: mrs r1, primask_ns + ; MAINLINE: mrs r1, basepri_ns + ; 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) + %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 + %14 = call i32 @llvm.read_register.i32(metadata !26) + %add14 = add i32 %add13, %14 + %15 = call i32 @llvm.read_register.i32(metadata !27) + %add15 = add i32 %add14, %15 + %16 = call i32 @llvm.read_register.i32(metadata !28) + %add16 = add i32 %add15, %16 + %17 = call i32 @llvm.read_register.i32(metadata !29) + %add17 = add i32 %add16, %17 + %18 = call i32 @llvm.read_register.i32(metadata !30) + %add18 = add i32 %add17, %18 + %19 = call i32 @llvm.read_register.i32(metadata !31) + %add19 = add i32 %add18, %19 + %20 = call i32 @llvm.read_register.i32(metadata !32) + %add20 = add i32 %add19, %20 + %21 = call i32 @llvm.read_register.i32(metadata !33) + %add21 = add i32 %add20, %21 + %22 = call i32 @llvm.read_register.i32(metadata !34) + %add22 = add i32 %add21, %22 + %23 = call i32 @llvm.read_register.i32(metadata !35) + %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 +} + +define void @write_mclass_registers(i32 %x) nounwind { +entry: + ; MAINLINE-LABEL: write_mclass_registers: + ; MAINLINE: msr apsr_nzcvqg, r0 + ; MAINLINE: msr apsr_nzcvq, r0 + ; MAINLINE: msr apsr_g, r0 + ; MAINLINE: msr apsr_nzcvqg, r0 + ; MAINLINE: msr iapsr_nzcvqg, r0 + ; MAINLINE: msr iapsr_nzcvq, r0 + ; MAINLINE: msr iapsr_g, r0 + ; MAINLINE: msr iapsr_nzcvqg, r0 + ; MAINLINE: msr eapsr_nzcvqg, r0 + ; MAINLINE: msr eapsr_nzcvq, r0 + ; MAINLINE: msr eapsr_g, r0 + ; MAINLINE: msr eapsr_nzcvqg, r0 + ; MAINLINE: msr xpsr_nzcvqg, r0 + ; MAINLINE: msr xpsr_nzcvq, r0 + ; MAINLINE: msr xpsr_g, r0 + ; MAINLINE: msr xpsr_nzcvqg, r0 + ; MAINLINE: msr ipsr, r0 + ; MAINLINE: msr epsr, r0 + ; MAINLINE: msr iepsr, r0 + ; MAINLINE: msr msp, r0 + ; MAINLINE: msr psp, r0 + ; MAINLINE: msr primask, r0 + ; MAINLINE: msr basepri, r0 + ; MAINLINE: msr basepri_max, r0 + ; MAINLINE: msr faultmask, r0 + ; MAINLINE: msr control, r0 + ; MAINLINE: msr msplim, r0 + ; MAINLINE: msr psplim, r0 + ; MAINLINE: msr msp_ns, r0 + ; MAINLINE: msr psp_ns, r0 + ; MAINLINE: msr msplim_ns, r0 + ; MAINLINE: msr psplim_ns, r0 + ; MAINLINE: msr primask_ns, r0 + ; MAINLINE: msr basepri_ns, r0 + ; 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) + 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) + call void @llvm.write_register.i32(metadata !26, i32 %x) + call void @llvm.write_register.i32(metadata !27, i32 %x) + call void @llvm.write_register.i32(metadata !28, i32 %x) + call void @llvm.write_register.i32(metadata !29, i32 %x) + call void @llvm.write_register.i32(metadata !30, i32 %x) + call void @llvm.write_register.i32(metadata !31, i32 %x) + call void @llvm.write_register.i32(metadata !32, i32 %x) + call void @llvm.write_register.i32(metadata !33, i32 %x) + 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 +} + +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"} +!26 = !{!"msplim"} +!27 = !{!"psplim"} +!28 = !{!"msp_ns"} +!29 = !{!"psp_ns"} +!30 = !{!"msplim_ns"} +!31 = !{!"psplim_ns"} +!32 = !{!"primask_ns"} +!33 = !{!"basepri_ns"} +!34 = !{!"faultmask_ns"} +!35 = !{!"control_ns"} +!36 = !{!"sp_ns"} +!37 = !{!"basepri_max_ns"} + diff --git a/test/MC/ARM/thumbv8m.s b/test/MC/ARM/thumbv8m.s index e1bf9ce11e0..883503a4101 100644 --- a/test/MC/ARM/thumbv8m.s +++ b/test/MC/ARM/thumbv8m.s @@ -163,6 +163,42 @@ vlldm r5 // CHECK-MAINLINE: vlstm r10 @ encoding: [0x2a,0xec,0x00,0x0a] vlstm r10 +// New SYSm's + +MRS r1, MSP_NS +// CHECK: mrs r1, msp_ns @ encoding: [0xef,0xf3,0x88,0x81] +MSR PSP_NS, r2 +// CHECK: msr psp_ns, r2 @ encoding: [0x82,0xf3,0x89,0x88] +MRS r3, PRIMASK_NS +// CHECK: mrs r3, primask_ns @ encoding: [0xef,0xf3,0x90,0x83] +MSR CONTROL_NS, r4 +// CHECK: msr control_ns, r4 @ encoding: [0x84,0xf3,0x94,0x88] +MRS r5, SP_NS +// CHECK: mrs r5, sp_ns @ encoding: [0xef,0xf3,0x98,0x85] +MRS r6,MSPLIM +// CHECK: mrs r6, msplim @ encoding: [0xef,0xf3,0x0a,0x86] +MRS r7,PSPLIM +// CHECK: mrs r7, psplim @ encoding: [0xef,0xf3,0x0b,0x87] +MSR MSPLIM,r8 +// CHECK: msr msplim, r8 @ encoding: [0x88,0xf3,0x0a,0x88] +MSR PSPLIM,r9 +// 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 +MSR PSPLIM_NS, r11 +// CHECK-MAINLINE: msr psplim_ns, r11 @ encoding: [0x8b,0xf3,0x8b,0x88] +// UNDEF-BASELINE: error: invalid operand for instruction +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 // Invalid operand tests // UNDEF: error: invalid operand for instruction diff --git a/test/MC/Disassembler/ARM/thumb2-v8m.txt b/test/MC/Disassembler/ARM/thumb2-v8m.txt new file mode 100644 index 00000000000..007d7dc46ba --- /dev/null +++ b/test/MC/Disassembler/ARM/thumb2-v8m.txt @@ -0,0 +1,25 @@ +# RUN: llvm-mc -triple=thumbv8m.base -disassemble < %s 2>%t | FileCheck %s +# RUN: FileCheck < %t %s --check-prefix=CHECK-STDERR +# RUN: llvm-mc -triple=thumbv8m.main -disassemble < %s | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-MAINLINE + +0xef 0xf3 0x0a 0x83 +# CHECK: mrs r3, msplim +0xef 0xf3 0x0b 0x84 +# CHECK: mrs r4, psplim +0x8b 0xf3 0x0a 0x88 +# CHECK: msr msplim, r11 +0x8c 0xf3 0x0b 0x88 +# CHECK: msr psplim, r12 + +0xef 0xf3 0x90 0x86 +# CHECK: mrs r6, primask_ns +0x88 0xf3 0x98 0x88 +# CHECK: msr sp_ns, r8 + +0xef 0xf3 0x8a 0x85 +# CHECK-STDERR: warning: invalid instruction encoding +# CHECK-MAINLINE: mrs r5, msplim_ns +0x87 0xf3 0x93 0x88 +# CHECK-STDERR: warning: invalid instruction encoding +# CHECK-MAINLINE: msr faultmask_ns, r7 + -- 2.11.0