[llvm-commits] [llvm] r125052 - in /llvm/trunk/lib/Target/ARM: ARMInstrInfo.td AsmParser/ARMAsmParser.cpp

Bruno Cardoso Lopes bruno.cardoso at gmail.com
Mon Feb 7 13:41:26 PST 2011


Author: bruno
Date: Mon Feb  7 15:41:25 2011
New Revision: 125052

URL: http://llvm.org/viewvc/llvm-project?rev=125052&view=rev
Log:
Remove the MCR asm parser hack and start using the custom target specific asm
parsing of operands introduced in r125030. As a small note, besides using a more
generic approach we can also have more descriptive output when debugging
llvm-mc, example:

mcr  p7, #1, r5, c1, c1, #4

note: parsed instruction:
  ['mcr', <ARMCC::al>,
          <coprocessor number: 7>,
          1,
          <register 73>,
          <coprocessor register: 1>,
          <coprocessor register: 1>,
          4]


Modified:
    llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
    llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp

Modified: llvm/trunk/lib/Target/ARM/ARMInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/ARMInstrInfo.td?rev=125052&r1=125051&r2=125052&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/ARMInstrInfo.td (original)
+++ llvm/trunk/lib/Target/ARM/ARMInstrInfo.td Mon Feb  7 15:41:25 2011
@@ -588,12 +588,26 @@
   let PrintMethod = "printNoHashImmediate";
 }
 
+def CoprocNumAsmOperand : AsmOperandClass {
+  let Name = "CoprocNum";
+  let SuperClasses = [];
+  let ParserMethod = "ParseCoprocNumOperand";
+}
+
+def CoprocRegAsmOperand : AsmOperandClass {
+  let Name = "CoprocReg";
+  let SuperClasses = [];
+  let ParserMethod = "ParseCoprocRegOperand";
+}
+
 def p_imm : Operand<i32> {
   let PrintMethod = "printPImmediate";
+  let ParserMatchClass = CoprocNumAsmOperand;
 }
 
 def c_imm : Operand<i32> {
   let PrintMethod = "printCImmediate";
+  let ParserMatchClass = CoprocRegAsmOperand;
 }
 
 //===----------------------------------------------------------------------===//

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=125052&r1=125051&r2=125052&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/ARM/AsmParser/ARMAsmParser.cpp Mon Feb  7 15:41:25 2011
@@ -54,11 +54,12 @@
 
   int TryParseRegister();
   virtual bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
-  bool TryParseCoprocessorOperandName(SmallVectorImpl<MCParsedAsmOperand*>&);
   bool TryParseRegisterWithWriteBack(SmallVectorImpl<MCParsedAsmOperand*> &);
+  bool ParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*>&);
+  bool ParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*>&);
   bool ParseRegisterList(SmallVectorImpl<MCParsedAsmOperand*> &);
   bool ParseMemory(SmallVectorImpl<MCParsedAsmOperand*> &);
-  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, bool hasCoprocOp);
+  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &, StringRef Mnemonic);
   bool ParsePrefix(ARMMCExpr::VariantKind &RefKind);
   const MCExpr *ApplyPrefixToExpr(const MCExpr *E,
                                   MCSymbolRefExpr::VariantKind Variant);
@@ -115,6 +116,8 @@
   enum KindTy {
     CondCode,
     CCOut,
+    CoprocNum,
+    CoprocReg,
     Immediate,
     Memory,
     Register,
@@ -133,6 +136,10 @@
     } CC;
 
     struct {
+      unsigned Val;
+    } Cop;
+
+    struct {
       const char *Data;
       unsigned Length;
     } Tok;
@@ -185,6 +192,10 @@
     case SPRRegisterList:
       Registers = o.Registers;
       break;
+    case CoprocNum:
+    case CoprocReg:
+      Cop = o.Cop;
+      break;
     case Immediate:
       Imm = o.Imm;
       break;
@@ -204,6 +215,11 @@
     return CC.Val;
   }
 
+  unsigned getCoproc() const {
+    assert((Kind == CoprocNum || Kind == CoprocReg) && "Invalid access!");
+    return Cop.Val;
+  }
+
   StringRef getToken() const {
     assert(Kind == Token && "Invalid access!");
     return StringRef(Tok.Data, Tok.Length);
@@ -259,6 +275,8 @@
 
   /// @}
 
+  bool isCoprocNum() const { return Kind == CoprocNum; }
+  bool isCoprocReg() const { return Kind == CoprocReg; }
   bool isCondCode() const { return Kind == CondCode; }
   bool isCCOut() const { return Kind == CCOut; }
   bool isImm() const { return Kind == Immediate; }
@@ -314,6 +332,16 @@
     Inst.addOperand(MCOperand::CreateReg(RegNum));
   }
 
+  void addCoprocNumOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
+  }
+
+  void addCoprocRegOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 1 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateImm(getCoproc()));
+  }
+
   void addCCOutOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateReg(getReg()));
@@ -391,6 +419,22 @@
     return Op;
   }
 
+  static ARMOperand *CreateCoprocNum(unsigned CopVal, SMLoc S) {
+    ARMOperand *Op = new ARMOperand(CoprocNum);
+    Op->Cop.Val = CopVal;
+    Op->StartLoc = S;
+    Op->EndLoc = S;
+    return Op;
+  }
+
+  static ARMOperand *CreateCoprocReg(unsigned CopVal, SMLoc S) {
+    ARMOperand *Op = new ARMOperand(CoprocReg);
+    Op->Cop.Val = CopVal;
+    Op->StartLoc = S;
+    Op->EndLoc = S;
+    return Op;
+  }
+
   static ARMOperand *CreateCCOut(unsigned RegNum, SMLoc S) {
     ARMOperand *Op = new ARMOperand(CCOut);
     Op->Reg.RegNum = RegNum;
@@ -492,6 +536,12 @@
   case CCOut:
     OS << "<ccout " << getReg() << ">";
     break;
+  case CoprocNum:
+    OS << "<coprocessor number: " << getCoproc() << ">";
+    break;
+  case CoprocReg:
+    OS << "<coprocessor register: " << getCoproc() << ">";
+    break;
   case Immediate:
     getImm()->print(OS);
     break;
@@ -609,13 +659,16 @@
   return false;
 }
 
-static int MatchCoprocessorOperandName(StringRef Name) {
+/// MatchCoprocessorOperandName - Try to parse an coprocessor related
+/// instruction with a symbolic operand name. Example: "p1", "p7", "c3",
+/// "c5", ...
+static int MatchCoprocessorOperandName(StringRef Name, char CoprocOp) {
   // Use the same layout as the tablegen'erated register name matcher. Ugly,
   // but efficient.
   switch (Name.size()) {
   default: break;
   case 2:
-    if (Name[0] != 'p' && Name[0] != 'c')
+    if (Name[0] != CoprocOp)
       return -1;
     switch (Name[1]) {
     default:  return -1;
@@ -632,7 +685,7 @@
     }
     break;
   case 3:
-    if ((Name[0] != 'p' && Name[0] != 'c') || Name[1] != '1')
+    if (Name[0] != CoprocOp || Name[1] != '1')
       return -1;
     switch (Name[2]) {
     default:  return -1;
@@ -650,24 +703,39 @@
   return -1;
 }
 
-/// TryParseCoprocessorOperandName - Try to parse an coprocessor related
-/// instruction with a symbolic operand name.  The token must be an Identifier
-/// when called, and if it is a coprocessor related operand name, the token is
-/// eaten and the operand is added to the operand list. Example: operands like
-/// "p1", "p7", "c3", "c5", ...
+/// ParseCoprocNumOperand - Try to parse an coprocessor number operand. The
+/// token must be an Identifier when called, and if it is a coprocessor
+/// number, the token is eaten and the operand is added to the operand list.
 bool ARMAsmParser::
-TryParseCoprocessorOperandName(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+ParseCoprocNumOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
   SMLoc S = Parser.getTok().getLoc();
   const AsmToken &Tok = Parser.getTok();
   assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
 
-  int Num = MatchCoprocessorOperandName(Tok.getString());
+  int Num = MatchCoprocessorOperandName(Tok.getString(), 'p');
   if (Num == -1)
     return true;
 
   Parser.Lex(); // Eat identifier token.
-  Operands.push_back(ARMOperand::CreateImm(
-       MCConstantExpr::Create(Num, getContext()), S, Parser.getTok().getLoc()));
+  Operands.push_back(ARMOperand::CreateCoprocNum(Num, S));
+  return false;
+}
+
+/// ParseCoprocRegOperand - Try to parse an coprocessor register operand. The
+/// token must be an Identifier when called, and if it is a coprocessor
+/// number, the token is eaten and the operand is added to the operand list.
+bool ARMAsmParser::
+ParseCoprocRegOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
+  SMLoc S = Parser.getTok().getLoc();
+  const AsmToken &Tok = Parser.getTok();
+  assert(Tok.is(AsmToken::Identifier) && "Token is not an Identifier");
+
+  int Reg = MatchCoprocessorOperandName(Tok.getString(), 'c');
+  if (Reg == -1)
+    return true;
+
+  Parser.Lex(); // Eat identifier token.
+  Operands.push_back(ARMOperand::CreateCoprocReg(Reg, S));
   return false;
 }
 
@@ -974,8 +1042,15 @@
 /// Parse a arm instruction operand.  For now this parses the operand regardless
 /// of the mnemonic.
 bool ARMAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
-                                bool hasCoprocOp){
+                                StringRef Mnemonic) {
   SMLoc S, E;
+
+  // Check if the current operand has a custom associated parser, if so, try to
+  // custom parse the operand, or fallback to the general approach.
+  MatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
+  if (ResTy == Match_Success)
+    return false;
+
   switch (getLexer().getKind()) {
   default:
     Error(Parser.getTok().getLoc(), "unexpected token in operand");
@@ -983,8 +1058,6 @@
   case AsmToken::Identifier:
     if (!TryParseRegisterWithWriteBack(Operands))
       return false;
-    if (hasCoprocOp && !TryParseCoprocessorOperandName(Operands))
-      return false;
 
     // Fall though for the Identifier case that is not a register or a
     // special name.
@@ -1273,22 +1346,10 @@
     Operands.push_back(ARMOperand::CreateToken(Head, NameLoc));
   }
 
-  // Enable the parsing of instructions containing coprocessor related
-  // asm syntax, such as coprocessor names "p7, p15, ..." and coprocessor
-  // registers "c1, c3, ..."
-  // FIXME: we probably want AsmOperandClass and ParserMatchClass declarations
-  // in the .td file rather than hacking the ASMParser for every symbolic
-  // operand type.
-  bool hasCoprocOp = (Head == "mcr"  || Head == "mcr2" ||
-                      Head == "mcrr" || Head == "mcrr2" ||
-                      Head == "mrc"  || Head == "mrc2" ||
-                      Head == "mrrc" || Head == "mrrc2" ||
-                      Head == "cdp"  || Head == "cdp2");
-
   // Read the remaining operands.
   if (getLexer().isNot(AsmToken::EndOfStatement)) {
     // Read the first operand.
-    if (ParseOperand(Operands, hasCoprocOp)) {
+    if (ParseOperand(Operands, Head)) {
       Parser.EatToEndOfStatement();
       return true;
     }
@@ -1297,7 +1358,7 @@
       Parser.Lex();  // Eat the comma.
 
       // Parse and remember the operand.
-      if (ParseOperand(Operands, hasCoprocOp)) {
+      if (ParseOperand(Operands, Head)) {
         Parser.EatToEndOfStatement();
         return true;
       }





More information about the llvm-commits mailing list