[llvm-commits] [llvm] r137746 - in /llvm/trunk: lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h test/MC/ARM/mode-switch.s test/MC/ARM/nop-thumb-padding.s test/MC/ARM/nop-thumb2-padding.s

Jim Grosbach grosbach at apple.com
Tue Aug 16 13:45:50 PDT 2011


Author: grosbach
Date: Tue Aug 16 15:45:50 2011
New Revision: 137746

URL: http://llvm.org/viewvc/llvm-project?rev=137746&view=rev
Log:
ARM thumb assembly parsing for arithmetic flag setting instructions.

Thumb one requires that many arithmetic instruction forms have an 'S'
suffix. For Thumb2, the whether the suffix is required or precluded depends
on whether the instruction is in an IT block. Use target parser predicates
to check for these sorts of context-sensitive constraints.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
    llvm/trunk/test/MC/ARM/mode-switch.s
    llvm/trunk/test/MC/ARM/nop-thumb-padding.s
    llvm/trunk/test/MC/ARM/nop-thumb2-padding.s

Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=137746&r1=137745&r2=137746&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Tue Aug 16 15:45:50 2011
@@ -236,6 +236,10 @@
   Domain D = d;
   bit isUnaryDataProc = 0;
   bit canXformTo16Bit = 0;
+  // The instruction is a 16-bit flag setting Thumb instruction. Used
+  // by the parser to determine whether to require the 'S' suffix on the
+  // mnemonic (when not in an IT block) or preclude it (when in an IT block).
+  bit thumbArithFlagSetting = 0;
 
   // If this is a pseudo instruction, mark it isCodeGenOnly.
   let isCodeGenOnly = !eq(!cast<string>(f), "Pseudo");
@@ -247,6 +251,7 @@
   let TSFlags{13}    = isUnaryDataProc;
   let TSFlags{14}    = canXformTo16Bit;
   let TSFlags{17-15} = D.Value;
+  let TSFlags{18}    = thumbArithFlagSetting;
 
   let Constraints = cstr;
   let Itinerary = itin;
@@ -895,6 +900,7 @@
   let InOperandList = !con(iops, (ins pred:$p));
   let AsmString = !strconcat(opc, "${s}${p}", asm);
   let Pattern = pattern;
+  let thumbArithFlagSetting = 1;
   list<Predicate> Predicates = [IsThumb, IsThumb1Only];
 }
 

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=137746&r1=137745&r2=137746&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Tue Aug 16 15:45:50 2011
@@ -78,6 +78,9 @@
   bool isThumbOne() const {
     return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2) == 0;
   }
+  bool isThumbTwo() const {
+    return isThumb() && (STI.getFeatureBits() & ARM::FeatureThumb2);
+  }
   void SwitchMode() {
     unsigned FB = ComputeAvailableFeatures(STI.ToggleFeature(ARM::ModeThumb));
     setAvailableFeatures(FB);
@@ -146,6 +149,10 @@
                           const SmallVectorImpl<MCParsedAsmOperand*> &Ops);
 
 public:
+  enum ARMMatchResultTy {
+    Match_RequiresITBlock = FIRST_TARGET_MATCH_RESULT_TY
+  };
+
   ARMAsmParser(MCSubtargetInfo &_STI, MCAsmParser &_Parser)
     : MCTargetAsmParser(), STI(_STI), Parser(_Parser) {
     MCAsmParserExtension::Initialize(_Parser);
@@ -160,6 +167,8 @@
                         SmallVectorImpl<MCParsedAsmOperand*> &Operands);
   bool ParseDirective(AsmToken DirectiveID);
 
+  unsigned checkTargetMatchPredicate(MCInst &Inst);
+
   bool MatchAndEmitInstruction(SMLoc IDLoc,
                                SmallVectorImpl<MCParsedAsmOperand*> &Operands,
                                MCStreamer &Out);
@@ -2975,6 +2984,44 @@
   }
 }
 
+// FIXME: We would really prefer to have MCInstrInfo (the wrapper around
+// the ARMInsts array) instead. Getting that here requires awkward
+// API changes, though. Better way?
+namespace llvm {
+extern MCInstrDesc ARMInsts[];
+}
+static MCInstrDesc &getInstDesc(unsigned Opcode) {
+  return ARMInsts[Opcode];
+}
+
+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());
+  if (MCID.TSFlags & ARMII::ThumbArithFlagSetting) {
+    assert(MCID.hasOptionalDef() &&
+           "optionally flag setting instruction missing optional def operand");
+    assert(MCID.NumOperands == Inst.getNumOperands() &&
+           "operand count mismatch!");
+    // Find the optional-def operand (cc_out).
+    unsigned OpNo;
+    for (OpNo = 0;
+         !MCID.OpInfo[OpNo].isOptionalDef() && OpNo < MCID.NumOperands;
+         ++OpNo)
+      ;
+    // If we're parsing Thumb1, reject it completely.
+    if (isThumbOne() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
+      return Match_MnemonicFail;
+    // If we're parsing Thumb2, which form is legal depends on whether we're
+    // in an IT block.
+    // FIXME: We don't yet do IT blocks, so just always consider it to be
+    // that we aren't in one until we do.
+    if (isThumbTwo() && Inst.getOperand(OpNo).getReg() != ARM::CPSR)
+      return Match_RequiresITBlock;
+  }
+  return Match_Success;
+}
+
 bool ARMAsmParser::
 MatchAndEmitInstruction(SMLoc IDLoc,
                         SmallVectorImpl<MCParsedAsmOperand*> &Operands,
@@ -3013,9 +3060,11 @@
     return Error(ErrorLoc, "invalid operand for instruction");
   }
   case Match_MnemonicFail:
-    return Error(IDLoc, "unrecognized instruction mnemonic");
+    return Error(IDLoc, "invalid instruction");
   case Match_ConversionFail:
     return Error(IDLoc, "unable to convert operands to instruction");
+  case Match_RequiresITBlock:
+    return Error(IDLoc, "instruction only valid inside IT block");
   }
 
   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=137746&r1=137745&r2=137746&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h Tue Aug 16 15:45:50 2011
@@ -384,6 +384,12 @@
     // a 16-bit Thumb instruction if certain conditions are met.
     Xform16Bit    = 1 << 14,
 
+    // ThumbArithFlagSetting - The instruction is a 16-bit flag setting Thumb
+    // instruction. Used by the parser to determine whether to require the 'S'
+    // suffix on the mnemonic (when not in an IT block) or preclude it (when
+    // in an IT block).
+    ThumbArithFlagSetting = 1 << 18,
+
     //===------------------------------------------------------------------===//
     // Code domain.
     DomainShift   = 15,

Modified: llvm/trunk/test/MC/ARM/mode-switch.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/mode-switch.s?rev=137746&r1=137745&r2=137746&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/mode-switch.s (original)
+++ llvm/trunk/test/MC/ARM/mode-switch.s Tue Aug 16 15:45:50 2011
@@ -4,14 +4,14 @@
 
 .code 16
 
-@ CHECK:	add.w	r0, r0, r1              @ encoding: [0x00,0xeb,0x01,0x00]
+@ CHECK: add.w	r0, r0, r1              @ encoding: [0x00,0xeb,0x01,0x00]
 	add.w	r0, r0, r1
 
 .code 32
-@ CHECK:	add	r0, r0, r1              @ encoding: [0x01,0x00,0x80,0xe0]
+@ CHECK: add	r0, r0, r1              @ encoding: [0x01,0x00,0x80,0xe0]
 	add	r0, r0, r1
 
 .code 16
-@ CHECK:	add	r0, r0, r1              @ encoding: [0x40,0x18]
-        
-        add     r0, r0, r1
+@ CHECK: adds	r0, r0, r1              @ encoding: [0x40,0x18]
+
+        adds    r0, r0, r1

Modified: llvm/trunk/test/MC/ARM/nop-thumb-padding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/nop-thumb-padding.s?rev=137746&r1=137745&r2=137746&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/nop-thumb-padding.s (original)
+++ llvm/trunk/test/MC/ARM/nop-thumb-padding.s Tue Aug 16 15:45:50 2011
@@ -5,8 +5,8 @@
 .thumb_func x
 .code 16
 x:
-      add r0, r1, r2
+      adds r0, r1, r2
       .align 4
-      add r0, r1, r2
+      adds r0, r1, r2
 
 @ CHECK: ('_section_data', '8818c046 c046c046 c046c046 c046c046 8818')

Modified: llvm/trunk/test/MC/ARM/nop-thumb2-padding.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/nop-thumb2-padding.s?rev=137746&r1=137745&r2=137746&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/nop-thumb2-padding.s (original)
+++ llvm/trunk/test/MC/ARM/nop-thumb2-padding.s Tue Aug 16 15:45:50 2011
@@ -5,8 +5,8 @@
 .thumb_func x
 .code 16
 x:
-      add r0, r1, r2
+      adds r0, r1, r2
       .align 4
-      add r0, r1, r2
+      adds r0, r1, r2
 
 @ CHECK: ('_section_data', '881800bf 00bf00bf 00bf00bf 00bf00bf 8818')





More information about the llvm-commits mailing list