Check in a patch that has already been code reviewed by Owen that I'd forgotten to...
authorJames Molloy <james.molloy@arm.com>
Wed, 28 Sep 2011 14:21:38 +0000 (14:21 +0000)
committerJames Molloy <james.molloy@arm.com>
Wed, 28 Sep 2011 14:21:38 +0000 (14:21 +0000)
Build on previous patches to successfully distinguish between an M-series and A/R-series MSR and MRS instruction. These take different mask names and have a *slightly* different opcode format.

Add decoder and disassembler tests.

Improvement on the previous patch - successfully distinguish between valid v6m and v7m masks (one is a subset of the other). The patch had to be edited slightly to apply to ToT.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140696 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARM.td
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/ARMSubtarget.h
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
test/MC/ARM/thumb2-mclass.s [new file with mode: 0644]
test/MC/Disassembler/ARM/thumb-MSR-MClass.txt [new file with mode: 0644]
test/MC/Disassembler/ARM/thumb-tests.txt

index 994271d678682812e12dd7b41068daace9156665..5c727ad6e343941a9071ac4b7febf64216bb29a8 100644 (file)
@@ -94,6 +94,10 @@ def FeatureDSPThumb2 : SubtargetFeature<"t2dsp", "Thumb2DSP", "true",
 def FeatureMP : SubtargetFeature<"mp", "HasMPExtension", "true",
                                  "Supports Multiprocessing extension">;
 
+// M-series ISA?
+def FeatureMClass : SubtargetFeature<"mclass", "IsMClass", "true",
+                                     "Is microcontroller profile ('M' series)">;
+
 // ARM ISAs.
 def HasV4TOps   : SubtargetFeature<"v4t", "HasV4TOps", "true",
                                    "Support ARM v4T instructions">;
@@ -185,7 +189,7 @@ def : Processor<"mpcore",           ARMV6Itineraries, [HasV6Ops, FeatureVFP2,
 
 // V6M Processors.
 def : Processor<"cortex-m0",        ARMV6Itineraries, [HasV6Ops, FeatureNoARM,
-                                                       FeatureDB]>;
+                                                       FeatureDB, FeatureMClass]>;
 
 // V6T2 Processors.
 def : Processor<"arm1156t2-s",      ARMV6Itineraries, [HasV6T2Ops,
@@ -208,14 +212,14 @@ def : Processor<"cortex-a9-mp",     CortexA9Itineraries,
 // V7M Processors.
 def : ProcNoItin<"cortex-m3",       [HasV7Ops,
                                      FeatureThumb2, FeatureNoARM, FeatureDB,
-                                     FeatureHWDiv]>;
+                                     FeatureHWDiv, FeatureMClass]>;
 
 // V7EM Processors.
 def : ProcNoItin<"cortex-m4",       [HasV7Ops,
                                      FeatureThumb2, FeatureNoARM, FeatureDB,
                                      FeatureHWDiv, FeatureDSPThumb2,
                                      FeatureT2XtPk, FeatureVFP2,
-                                     FeatureVFPOnlySP]>;
+                                     FeatureVFPOnlySP, FeatureMClass]>;
 
 //===----------------------------------------------------------------------===//
 // Register File Description
index e2a6fd7bcfea637cf5598e89aacf03fa75db079f..f05d3b1e0ad541494a054ea23b8ff838ac2a6cdf 100644 (file)
@@ -205,6 +205,10 @@ def IsThumb          : Predicate<"Subtarget->isThumb()">,
 def IsThumb1Only     : Predicate<"Subtarget->isThumb1Only()">;
 def IsThumb2         : Predicate<"Subtarget->isThumb2()">,
                                  AssemblerPredicate<"ModeThumb,FeatureThumb2">;
+def IsMClass         : Predicate<"Subtarget->isMClass()">,
+                                 AssemblerPredicate<"FeatureMClass">;
+def IsARClass        : Predicate<"!Subtarget->isMClass()">,
+                                 AssemblerPredicate<"!FeatureMClass">;
 def IsARM            : Predicate<"!Subtarget->isThumb()">,
                                  AssemblerPredicate<"!ModeThumb">;
 def IsDarwin         : Predicate<"Subtarget->isTargetDarwin()">;
index 6ce443894388d17cb3a87db4f6b1688b97c1604d..b8a8519b7a873b9208374481fc39d584acdb0978 100644 (file)
@@ -3540,30 +3540,55 @@ defm t2STC  : T2LdStCop<0b1111, 0, "stc">;
 // Move between special register and ARM core register -- for disassembly only
 //
 // Move to ARM core register from Special Register
-def t2MRS : T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr", []> {
+
+// A/R class MRS.
+//
+// A/R class can only move from CPSR or SPSR.
+def t2MRS_AR : T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, apsr", []>,
+               Requires<[IsThumb2,IsARClass]> {
   bits<4> Rd;
   let Inst{31-12} = 0b11110011111011111000;
   let Inst{11-8} = Rd;
   let Inst{7-0} = 0b0000;
 }
 
-def : t2InstAlias<"mrs${p} $Rd, cpsr", (t2MRS GPR:$Rd, pred:$p)>;
+def : t2InstAlias<"mrs${p} $Rd, cpsr", (t2MRS_AR GPR:$Rd, pred:$p)>;
 
-def t2MRSsys:T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr", []> {
+def t2MRSsys_AR: T2I<(outs GPR:$Rd), (ins), NoItinerary, "mrs", "\t$Rd, spsr", []>,
+                 Requires<[IsThumb2,IsARClass]> {
   bits<4> Rd;
   let Inst{31-12} = 0b11110011111111111000;
   let Inst{11-8} = Rd;
   let Inst{7-0} = 0b0000;
 }
 
+// M class MRS.
+//
+// This MRS has a mask field in bits 7-0 and can take more values than
+// the A/R class (a full msr_mask).
+def t2MRS_M : T2I<(outs rGPR:$Rd), (ins msr_mask:$mask), NoItinerary,
+                  "mrs", "\t$Rd, $mask", []>,
+              Requires<[IsThumb2,IsMClass]> {
+  bits<4> Rd;
+  bits<8> mask;
+  let Inst{31-12} = 0b11110011111011111000;
+  let Inst{11-8} = Rd;
+  let Inst{19-16} = 0b1111;
+  let Inst{7-0} = mask;
+}
+
+
 // Move from ARM core register to Special Register
 //
+// A/R class MSR.
+//
 // No need to have both system and application versions, the encodings are the
 // same and the assembly parser has no way to distinguish between them. The mask
 // operand contains the special register (R Bit) in bit 4 and bits 3-0 contains
 // the mask with the fields to be accessed in the special register.
-def t2MSR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
-                NoItinerary, "msr", "\t$mask, $Rn", []> {
+def t2MSR_AR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
+                   NoItinerary, "msr", "\t$mask, $Rn", []>,
+               Requires<[IsThumb2,IsARClass]> {
   bits<5> mask;
   bits<4> Rn;
   let Inst{31-21} = 0b11110011100;
@@ -3574,6 +3599,22 @@ def t2MSR : T2I<(outs), (ins msr_mask:$mask, rGPR:$Rn),
   let Inst{7-0}   = 0;
 }
 
+// M class MSR.
+//
+// Move from ARM core register to Special Register
+def t2MSR_M : T2I<(outs), (ins msr_mask:$SYSm, rGPR:$Rn),
+                  NoItinerary, "msr", "\t$SYSm, $Rn", []>,
+              Requires<[IsThumb2,IsMClass]> {
+  bits<8> SYSm;
+  bits<4> Rn;
+  let Inst{31-21} = 0b11110011100;
+  let Inst{20}    = 0b0;
+  let Inst{19-16} = Rn;
+  let Inst{15-12} = 0b1000;
+  let Inst{7-0}  = SYSm;
+}
+
+
 //===----------------------------------------------------------------------===//
 // Move between coprocessor and ARM core register
 //
index f01d1d41cfdcfea67da407d5501c473469c526b0..82e542281e265908a0b20a293d80e119a505b409 100644 (file)
@@ -55,6 +55,7 @@ ARMSubtarget::ARMSubtarget(const std::string &TT, const std::string &CPU,
   , InThumbMode(false)
   , InNaClMode(false)
   , HasThumb2(false)
+  , IsMClass(false)
   , NoARM(false)
   , PostRAScheduler(false)
   , IsR9Reserved(ReserveR9)
index 76a502caa9a874c757b91cff6fbcca2827406208..47e076a7f11d93f6a29d8de215e53fa5b58a655d 100644 (file)
@@ -76,6 +76,10 @@ protected:
   /// HasThumb2 - True if Thumb2 instructions are supported.
   bool HasThumb2;
 
+  /// IsMClass - True if the subtarget belongs to the 'M' profile of CPUs - 
+  /// v6m, v7m for example.
+  bool IsMClass;
+
   /// NoARM - True if subtarget does not support ARM mode execution.
   bool NoARM;
 
@@ -224,6 +228,8 @@ protected:
   bool isThumb1Only() const { return InThumbMode && !HasThumb2; }
   bool isThumb2() const { return InThumbMode && HasThumb2; }
   bool hasThumb2() const { return HasThumb2; }
+  bool isMClass() const { return IsMClass; }
+  bool isARClass() const { return !IsMClass; }
 
   bool isR9Reserved() const { return IsR9Reserved; }
 
index 543340f8e45516d6b99115e09fba0a40735bcc05..9d28a1cd09263560631fab13aa37217bd4045111 100644 (file)
@@ -114,10 +114,16 @@ class ARMAsmParser : public MCTargetAsmParser {
   bool hasV6Ops() const {
     return STI.getFeatureBits() & ARM::HasV6Ops;
   }
+  bool hasV7Ops() const {
+    return STI.getFeatureBits() & ARM::HasV7Ops;
+  }
   void SwitchMode() {
     unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
     setAvailableFeatures(FB);
   }
+  bool isMClass() const {
+    return STI.getFeatureBits() & ARM::FeatureMClass;
+  }
 
   /// @name Auto-generated Match Functions
   /// {
@@ -2076,6 +2082,37 @@ parseMSRMaskOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
   StringRef Mask = Tok.getString();
 
+  if (isMClass()) {
+    // See ARMv6-M 10.1.1
+    unsigned FlagsVal = StringSwitch<unsigned>(Mask)
+      .Case("apsr", 0)
+      .Case("iapsr", 1)
+      .Case("eapsr", 2)
+      .Case("xpsr", 3)
+      .Case("ipsr", 5)
+      .Case("epsr", 6)
+      .Case("iepsr", 7)
+      .Case("msp", 8)
+      .Case("psp", 9)
+      .Case("primask", 16)
+      .Case("basepri", 17)
+      .Case("basepri_max", 18)
+      .Case("faultmask", 19)
+      .Case("control", 20)
+      .Default(~0U);
+    
+    if (FlagsVal == ~0U)
+      return MatchOperand_NoMatch;
+
+    if (!hasV7Ops() && FlagsVal >= 17 && FlagsVal <= 19)
+      // basepri, basepri_max and faultmask only valid for V7m.
+      return MatchOperand_NoMatch;
+    
+    Parser.Lex(); // Eat identifier token.
+    Operands.push_back(ARMOperand::CreateMSRMask(FlagsVal, S));
+    return MatchOperand_Success;
+  }
+
   // Split spec_reg from flag, example: CPSR_sxf => "CPSR" and "sxf"
   size_t Start = 0, Next = Mask.find('_');
   StringRef Flags = "";
index 49775f5c797c25372d8477abcab6876b4d45f526..bcf91c73ed12b071a6abcbd226997bbfa3018d2e 100644 (file)
@@ -621,6 +621,26 @@ void ARMInstPrinter::printMSRMaskOperand(const MCInst *MI, unsigned OpNum,
   unsigned SpecRegRBit = Op.getImm() >> 4;
   unsigned Mask = Op.getImm() & 0xf;
 
+  if (getAvailableFeatures() & ARM::FeatureMClass) {
+    switch (Op.getImm()) {
+    default: assert(0 && "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;
+    }
+  }
+
   // As special cases, CPSR_f, CPSR_s and CPSR_fs prefer printing as
   // APSR_nzcvq, APSR_g and APSRnzcvqg, respectively.
   if (!SpecRegRBit && (Mask == 8 || Mask == 4 || Mask == 12)) {
index 23f7f145610f54525dca2798361d90e6cfebae4a..5c582ca37faec72cebebb7444aa6ea5b06198826 100644 (file)
@@ -56,18 +56,21 @@ std::string ARM_MC::ParseARMTriple(StringRef TT) {
     unsigned SubVer = TT[Idx];
     if (SubVer >= '7' && SubVer <= '9') {
       if (Len >= Idx+2 && TT[Idx+1] == 'm') {
-        // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv
-        ARMArchFeature = "+v7,+noarm,+db,+hwdiv";
+        // v7m: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureMClass
+        ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+mclass";
       } else if (Len >= Idx+3 && TT[Idx+1] == 'e'&& TT[Idx+2] == 'm') {
         // v7em: FeatureNoARM, FeatureDB, FeatureHWDiv, FeatureDSPThumb2,
-        //       FeatureT2XtPk
-        ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk";
+        //       FeatureT2XtPk, FeatureMClass
+        ARMArchFeature = "+v7,+noarm,+db,+hwdiv,+t2dsp,t2xtpk,+mclass";
       } else
         // v7a: FeatureNEON, FeatureDB, FeatureDSPThumb2, FeatureT2XtPk
         ARMArchFeature = "+v7,+neon,+db,+t2dsp,+t2xtpk";
     } else if (SubVer == '6') {
       if (Len >= Idx+3 && TT[Idx+1] == 't' && TT[Idx+2] == '2')
         ARMArchFeature = "+v6t2";
+      else if (Len >= Idx+2 && TT[Idx+1] == 'm')
+        // v6m: FeatureNoARM, FeatureMClass
+        ARMArchFeature = "+v6t2,+noarm,+mclass";
       else
         ARMArchFeature = "+v6";
     } else if (SubVer == '5') {
diff --git a/test/MC/ARM/thumb2-mclass.s b/test/MC/ARM/thumb2-mclass.s
new file mode 100644 (file)
index 0000000..10460f9
--- /dev/null
@@ -0,0 +1,74 @@
+@ RUN: llvm-mc -triple=thumbv7m-apple-darwin -show-encoding < %s | FileCheck %s
+  .syntax unified
+  .globl _func
+
+@ Check that the assembler can handle the documented syntax from the ARM ARM.
+@ These tests test instruction encodings specific to v7m & v7m (FeatureMClass).
+
+@------------------------------------------------------------------------------
+@ MRS
+@------------------------------------------------------------------------------
+
+        mrs  r0, apsr
+        mrs  r0, iapsr
+        mrs  r0, eapsr
+        mrs  r0, xpsr
+        mrs  r0, ipsr
+        mrs  r0, epsr
+        mrs  r0, iepsr
+        mrs  r0, msp
+        mrs  r0, psp
+        mrs  r0, primask
+        mrs  r0, basepri
+        mrs  r0, basepri_max
+        mrs  r0, faultmask
+        mrs  r0, control
+
+@ CHECK: mrs   r0, apsr                @ encoding: [0xef,0xf3,0x00,0x80]
+@ CHECK: mrs   r0, iapsr               @ encoding: [0xef,0xf3,0x01,0x80]
+@ CHECK: mrs   r0, eapsr               @ encoding: [0xef,0xf3,0x02,0x80]
+@ CHECK: mrs   r0, xpsr                @ encoding: [0xef,0xf3,0x03,0x80]
+@ CHECK: mrs   r0, ipsr                @ encoding: [0xef,0xf3,0x05,0x80]
+@ CHECK: mrs   r0, epsr                @ encoding: [0xef,0xf3,0x06,0x80]
+@ CHECK: mrs   r0, iepsr               @ encoding: [0xef,0xf3,0x07,0x80]
+@ CHECK: mrs   r0, msp                 @ encoding: [0xef,0xf3,0x08,0x80]
+@ CHECK: mrs   r0, psp                 @ encoding: [0xef,0xf3,0x09,0x80]
+@ CHECK: mrs   r0, primask             @ encoding: [0xef,0xf3,0x10,0x80]
+@ CHECK: mrs   r0, basepri             @ encoding: [0xef,0xf3,0x11,0x80]
+@ CHECK: mrs   r0, basepri_max         @ encoding: [0xef,0xf3,0x12,0x80]
+@ CHECK: mrs   r0, faultmask           @ encoding: [0xef,0xf3,0x13,0x80]
+@ CHECK: mrs   r0, control             @ encoding: [0xef,0xf3,0x14,0x80]
+
+@------------------------------------------------------------------------------
+@ MSR
+@------------------------------------------------------------------------------
+
+        msr  apsr, r0
+        msr  iapsr, r0
+        msr  eapsr, r0
+        msr  xpsr, r0
+        msr  ipsr, r0
+        msr  epsr, r0
+        msr  iepsr, r0
+        msr  msp, r0
+        msr  psp, r0
+        msr  primask, r0
+        msr  basepri, r0
+        msr  basepri_max, r0
+        msr  faultmask, r0
+        msr  control, r0
+
+@ CHECK: msr   apsr, r0                @ encoding: [0x80,0xf3,0x00,0x80]
+@ CHECK: msr   iapsr, r0               @ encoding: [0x80,0xf3,0x01,0x80]
+@ CHECK: msr   eapsr, r0               @ encoding: [0x80,0xf3,0x02,0x80]
+@ CHECK: msr   xpsr, r0                @ encoding: [0x80,0xf3,0x03,0x80]
+@ CHECK: msr   ipsr, r0                @ encoding: [0x80,0xf3,0x05,0x80]
+@ CHECK: msr   epsr, r0                @ encoding: [0x80,0xf3,0x06,0x80]
+@ CHECK: msr   iepsr, r0               @ encoding: [0x80,0xf3,0x07,0x80]
+@ CHECK: msr   msp, r0                 @ encoding: [0x80,0xf3,0x08,0x80]
+@ CHECK: msr   psp, r0                 @ encoding: [0x80,0xf3,0x09,0x80]
+@ CHECK: msr   primask, r0             @ encoding: [0x80,0xf3,0x10,0x80]
+@ CHECK: msr   basepri, r0             @ encoding: [0x80,0xf3,0x11,0x80]
+@ CHECK: msr   basepri_max, r0         @ encoding: [0x80,0xf3,0x12,0x80]
+@ CHECK: msr   faultmask, r0           @ encoding: [0x80,0xf3,0x13,0x80]
+@ CHECK: msr   control, r0             @ encoding: [0x80,0xf3,0x14,0x80]
diff --git a/test/MC/Disassembler/ARM/thumb-MSR-MClass.txt b/test/MC/Disassembler/ARM/thumb-MSR-MClass.txt
new file mode 100644 (file)
index 0000000..497cb9a
--- /dev/null
@@ -0,0 +1,7 @@
+# RUN: llvm-mc --disassemble %s -triple=thumbv7-apple-darwin9 -mcpu cortex-m3 | FileCheck %s
+
+# CHECK: msr    primask, r0
+0x80 0xf3 0x10 0x80
+
+# CHECK: mrs    r0, primask
+0xef 0xf3 0x10 0x80
index 06cf6636e864c48eb435d723fc9986ce297f2209..c8b7e117de112f76e27560136f669f5861ae52a9 100644 (file)
 
 # CHECK: pldw  [r11, r12, lsl #2]
 0x3b 0xf8 0x2c 0xf0
+
+# CHECK: msr    CPSR_fc, r0
+0x80 0xf3 0x00 0x89
+
+# CHECK: mrs    r0, apsr
+0xef 0xf3 0x00 0x80