[llvm-commits] [llvm] r137779 - in /llvm/trunk: lib/Target/ARM/ARMBaseRegisterInfo.h lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h test/MC/ARM/thumb-diagnostics.s

Jim Grosbach grosbach at apple.com
Tue Aug 16 15:20:01 PDT 2011


Author: grosbach
Date: Tue Aug 16 17:20:01 2011
New Revision: 137779

URL: http://llvm.org/viewvc/llvm-project?rev=137779&view=rev
Log:
Thumb parsing diagnostics for low-reg requirements on ADD and MOV.

Modified:
    llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
    llvm/trunk/test/MC/ARM/thumb-diagnostics.s

Modified: llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h?rev=137779&r1=137778&r2=137779&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/ARMBaseRegisterInfo.h Tue Aug 16 17:20:01 2011
@@ -33,19 +33,6 @@
   };
 }
 
-/// isARMLowRegister - Returns true if the register is low register r0-r7.
-///
-static inline bool isARMLowRegister(unsigned Reg) {
-  using namespace ARM;
-  switch (Reg) {
-  case R0:  case R1:  case R2:  case R3:
-  case R4:  case R5:  case R6:  case R7:
-    return true;
-  default:
-    return false;
-  }
-}
-
 /// isARMArea1Register - Returns true if the register is a low register (r0-r7)
 /// or a stack/pc register that we should push/pop.
 static inline bool isARMArea1Register(unsigned Reg, bool isDarwin) {

Modified: llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp?rev=137779&r1=137778&r2=137779&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Aug 16 17:20:01 2011
@@ -81,6 +81,9 @@
   bool isThumbTwo() const {
     return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
   }
+  bool hasV6Ops() const {
+    return STI.getFeatureBits() & ARM::HasV6Ops;
+  }
   void SwitchMode() {
     unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
     setAvailableFeatures(FB);
@@ -152,7 +155,9 @@
 
 public:
   enum ARMMatchResultTy {
-    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY
+    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY,
+    Match_RequiresV6,
+    Match_RequiresThumb2
   };
 
   ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
@@ -2714,6 +2719,8 @@
       Mnemonic == "rsb" || Mnemonic == "rsc" || Mnemonic == "orn" ||
       Mnemonic == "sbc" || Mnemonic == "mla" || Mnemonic == "umull" ||
       Mnemonic == "eor" || Mnemonic == "smlal" ||
+      // FIXME: We need a better way. This really confused Thumb2
+      // parsing for 'mov'.
       (Mnemonic == "mov" && !isThumbOne())) {
     CanAcceptCarrySet = true;
   } else {
@@ -3022,7 +3029,8 @@
 unsigned ARMAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
   // 16-bit thumb arithmetic instructions either require or preclude the 'S'
   // suffix depending on whether they're in an IT block or not.
-  MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
+  unsigned Opc = Inst.getOpcode();
+  MCInstrDesc &MCID = getInstDesc(Opc);
   if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
     assert(MCID.hasOptionalDef() &&
            "optionally flag setting instruction missing optional def operand");
@@ -3044,6 +3052,17 @@
     if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
       return Match_RequiresITBlock;
   }
+  // Some high-register supporting Thumb1 encodings only allow both registers
+  // to be from r0-r7 when in Thumb2.
+  else if (Opc == ARM::tADDhirr && isThumbOne() &&
+           isARMLowRegister(Inst.getOperand(1).getReg()) &&
+           isARMLowRegister(Inst.getOperand(2).getReg()))
+    return Match_RequiresThumb2;
+  // Others only require ARMv6 or later.
+  else if (Opc == ARM::tMOVr && isThumbOne() &&
+           isARMLowRegister(Inst.getOperand(0).getReg()) &&
+           isARMLowRegister(Inst.getOperand(1).getReg()))
+    return Match_RequiresV6;
   return Match_Success;
 }
 
@@ -3090,6 +3109,10 @@
     return Error(IDLoc, "unable to convert operands to instruction");
   case Match_RequiresITBlock:
     return Error(IDLoc, "instruction only valid inside IT block");
+  case Match_RequiresV6:
+    return Error(IDLoc, "instruction variant requires ARMv6 or later");
+  case Match_RequiresThumb2:
+    return Error(IDLoc, "instruction variant requires Thumb2");
   }
 
   llvm_unreachable("Implement any new match types added!");

Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h?rev=137779&r1=137778&r2=137779&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h Tue Aug 16 17:20:01 2011
@@ -188,6 +188,19 @@
   }
 }
 
+/// isARMLowRegister - Returns true if the register is a low register (r0-r7).
+///
+static inline bool isARMLowRegister(unsigned Reg) {
+  using namespace ARM;
+  switch (Reg) {
+  case R0:  case R1:  case R2:  case R3:
+  case R4:  case R5:  case R6:  case R7:
+    return true;
+  default:
+    return false;
+  }
+}
+
 /// ARMII - This namespace holds all of the target specific flags that
 /// instruction info tracks.
 ///

Modified: llvm/trunk/test/MC/ARM/thumb-diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb-diagnostics.s?rev=137779&r1=137778&r2=137779&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb-diagnostics.s (original)
+++ llvm/trunk/test/MC/ARM/thumb-diagnostics.s Tue Aug 16 17:20:01 2011
@@ -8,3 +8,13 @@
 @ CHECK-ERRORS: error: invalid instruction
 @ CHECK-ERRORS:         add r1, r2, r3
 @ CHECK-ERRORS:         ^
+
+@ Instructions which require v6+ for both registers to be low regs.
+        add r2, r3
+        mov r2, r3
+@ CHECK-ERRORS: error: instruction variant requires Thumb2
+@ CHECK-ERRORS:         add r2, r3
+@ CHECK-ERRORS:         ^
+@ CHECK-ERRORS: error: instruction variant requires ARMv6 or later
+@ CHECK-ERRORS:         mov r2, r3
+@ CHECK-ERRORS:         ^





More information about the llvm-commits mailing list