[llvm-commits] [llvm] r135776 - in /llvm/trunk: lib/Target/ARM/ARMInstrFormats.td lib/Target/ARM/AsmParser/ARMAsmParser.cpp test/MC/ARM/basic-arm-instructions.s test/MC/ARM/diagnostics.s

Jim Grosbach grosbach at apple.com
Fri Jul 22 10:44:50 PDT 2011


Author: grosbach
Date: Fri Jul 22 12:44:50 2011
New Revision: 135776

URL: http://llvm.org/viewvc/llvm-project?rev=135776&view=rev
Log:
ARM assembly parsing and encoding for SETEND instruction.

Add parsing and diagnostics for malformed inputs. Tests for diagnostics and
for correct encodings.

Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
    llvm/trunk/test/MC/ARM/basic-arm-instructions.s
    llvm/trunk/test/MC/ARM/diagnostics.s

Modified: llvm/trunk/lib/Target/ARM/ARMInstrFormats.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrFormats.td?rev=135776&r1=135775&r2=135776&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrFormats.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrFormats.td Fri Jul 22 12:44:50 2011
@@ -193,8 +193,13 @@
 
 // ARM special operands for disassembly only.
 //
+def SetEndAsmOperand : AsmOperandClass {
+  let Name = "SetEndImm";
+  let ParserMethod = "parseSetEndImm";
+}
 def setend_op : Operand<i32> {
   let PrintMethod = "printSetendOperand";
+  let ParserMatchClass = SetEndAsmOperand;
 }
 
 def msr_mask : Operand<i32> {

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=135776&r1=135775&r2=135776&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Fri Jul 22 12:44:50 2011
@@ -126,6 +126,7 @@
   OperandMatchResultTy parsePKHASRImm(SmallVectorImpl<MCParsedAsmOperand*> &O) {
     return parsePKHImm(O, "asr", 1, 32);
   }
+  OperandMatchResultTy parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*>&);
 
   // Asm Match Converter Methods
   bool CvtLdWriteBackRegAddrMode2(MCInst &Inst, unsigned Opcode,
@@ -476,6 +477,14 @@
     int64_t Value = CE->getValue();
     return ARM_AM::getT2SOImmVal(Value) != -1;
   }
+  bool isSetEndImm() const {
+    if (Kind != Immediate)
+      return false;
+    const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(getImm());
+    if (!CE) return false;
+    int64_t Value = CE->getValue();
+    return Value == 1 || Value == 0;
+  }
   bool isReg() const { return Kind == Register; }
   bool isRegList() const { return Kind == RegisterList; }
   bool isDPRRegList() const { return Kind == DPRRegisterList; }
@@ -715,6 +724,11 @@
     addExpr(Inst, getImm());
   }
 
+  void addSetEndImmOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    addExpr(Inst, getImm());
+  }
+
   void addMemBarrierOptOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateImm(unsigned(getMemBarrierOpt())));
@@ -1644,6 +1658,30 @@
   return MatchOperand_Success;
 }
 
+ARMAsmParser::OperandMatchResultTy ARMAsmParser::
+parseSetEndImm(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  const AsmToken &Tok = Parser.getTok();
+  SMLoc S = Tok.getLoc();
+  if (Tok.isNot(AsmToken::Identifier)) {
+    Error(Tok.getLoc(), "'be' or 'le' operand expected");
+    return MatchOperand_ParseFail;
+  }
+  int Val = StringSwitch<int>(Tok.getString())
+    .Case("be", 1)
+    .Case("le", 0)
+    .Default(-1);
+  Parser.Lex(); // Eat the token.
+
+  if (Val == -1) {
+    Error(Tok.getLoc(), "'be' or 'le' operand expected");
+    return MatchOperand_ParseFail;
+  }
+  Operands.push_back(ARMOperand::CreateImm(MCConstantExpr::Create(Val,
+                                                                  getContext()),
+                                           S, Parser.getTok().getLoc()));
+  return MatchOperand_Success;
+}
+
 /// CvtLdWriteBackRegAddrMode2 - Convert parsed operands to MCInst.
 /// Needed here because the Asm Gen Matcher can't handle properly tied operands
 /// when they refer multiple MIOperands inside a single one.
@@ -2197,6 +2235,7 @@
       Mnemonic == "mcrr2" || Mnemonic == "cbz" || Mnemonic == "cdp2" ||
       Mnemonic == "trap" || Mnemonic == "mrc2" || Mnemonic == "mrrc2" ||
       Mnemonic == "dsb" || Mnemonic == "isb" || Mnemonic == "clrex" ||
+      Mnemonic == "setend" ||
       Mnemonic.startswith("cps") || (Mnemonic == "movs" && isThumb())) {
     CanAcceptPredicationCode = false;
   } else {
@@ -2221,7 +2260,7 @@
   unsigned ProcessorIMod;
   bool CarrySetting;
   Mnemonic = SplitMnemonic(Mnemonic, PredicationCode, CarrySetting,
-                       ProcessorIMod);
+                           ProcessorIMod);
 
   Operands.push_back(ARMOperand::CreateToken(Mnemonic, NameLoc));
 
@@ -2245,6 +2284,13 @@
     return Error(NameLoc, "instruction '" + Mnemonic +
                  "' can not set flags, but 's' suffix specified");
   }
+  // If we had a predication code on an instruction that can't do that, issue an
+  // error.
+  if (!CanAcceptPredicationCode && PredicationCode != ARMCC::AL) {
+    Parser.EatToEndOfStatement();
+    return Error(NameLoc, "instruction '" + Mnemonic +
+                 "' is not predicable, but condition code specified");
+  }
 
   // Add the carry setting operand, if necessary.
   //
@@ -2259,11 +2305,6 @@
   if (CanAcceptPredicationCode) {
     Operands.push_back(ARMOperand::CreateCondCode(
                          ARMCC::CondCodes(PredicationCode), NameLoc));
-  } else {
-    // This mnemonic can't ever accept a predication code, but the user wrote
-    // one (or misspelled another mnemonic).
-
-    // FIXME: Issue a nice error.
   }
 
   // Add the processor imod operand, if necessary.

Modified: llvm/trunk/test/MC/ARM/basic-arm-instructions.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/basic-arm-instructions.s?rev=135776&r1=135775&r2=135776&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/basic-arm-instructions.s (original)
+++ llvm/trunk/test/MC/ARM/basic-arm-instructions.s Fri Jul 22 12:44:50 2011
@@ -1304,6 +1304,16 @@
 
 
 @------------------------------------------------------------------------------
+@ SETEND
+ at ------------------------------------------------------------------------------
+        setend be
+        setend le
+
+	sel	r9, r2, r1              @ encoding: [0xb1,0x9f,0x82,0xe6]
+	selne	r9, r2, r1              @ encoding: [0xb1,0x9f,0x82,0x16]
+
+
+ at ------------------------------------------------------------------------------
 @ STM*
 @------------------------------------------------------------------------------
         stm       r2, {r1,r3-r6,sp}

Modified: llvm/trunk/test/MC/ARM/diagnostics.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/diagnostics.s?rev=135776&r1=135775&r2=135776&view=diff
==============================================================================
--- llvm/trunk/test/MC/ARM/diagnostics.s (original)
+++ llvm/trunk/test/MC/ARM/diagnostics.s Fri Jul 22 12:44:50 2011
@@ -144,3 +144,19 @@
 @ CHECK: error: asr operand expected.
 @ CHECK:         pkhtb r2, r2, r3, lsl #3
 @ CHECK:                           ^
+
+
+        @ bad values for SETEND
+        setendne be
+        setend me
+        setend 1
+
+@ CHECK: error: instruction 'setend' is not predicable, but condition code specified
+@ CHECK:         setendne be
+@ CHECK:         ^
+@ CHECK: error: 'be' or 'le' operand expected
+@ CHECK:         setend me
+@ CHECK:                  ^
+@ CHECK: error: 'be' or 'le' operand expected
+@ CHECK:         setend 1
+@ CHECK:                ^





More information about the llvm-commits mailing list