[llvm-commits] [llvm] r73867 - in /llvm/trunk/tools/llvm-mc: AsmParser.cpp AsmParser.h

Chris Lattner sabre at nondot.org
Sun Jun 21 18:29:10 PDT 2009


Author: lattner
Date: Sun Jun 21 20:29:09 2009
New Revision: 73867

URL: http://llvm.org/viewvc/llvm-project?rev=73867&view=rev
Log:
start implementing some simple operand parsing.

Modified:
    llvm/trunk/tools/llvm-mc/AsmParser.cpp
    llvm/trunk/tools/llvm-mc/AsmParser.h

Modified: llvm/trunk/tools/llvm-mc/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/AsmParser.cpp?rev=73867&r1=73866&r2=73867&view=diff

==============================================================================
--- llvm/trunk/tools/llvm-mc/AsmParser.cpp (original)
+++ llvm/trunk/tools/llvm-mc/AsmParser.cpp Sun Jun 21 20:29:09 2009
@@ -26,7 +26,6 @@
   return true;
 }
 
-
 bool AsmParser::Run() {
   // Prime the lexer.
   Lexer.Lex();
@@ -38,10 +37,86 @@
   return false;
 }
 
+/// EatToEndOfStatement - Throw away the rest of the line for testing purposes.
+void AsmParser::EatToEndOfStatement() {
+  while (Lexer.isNot(asmtok::EndOfStatement) &&
+         Lexer.isNot(asmtok::Eof))
+    Lexer.Lex();
+  
+  // Eat EOL.
+  if (Lexer.is(asmtok::EndOfStatement))
+    Lexer.Lex();
+}
+
+struct AsmParser::X86Operand {
+  enum {
+    Register,
+    Immediate
+  } Kind;
+  
+  union {
+    struct {
+      unsigned RegNo;
+    } Reg;
+
+    struct {
+      // FIXME: Should be a general expression.
+      int64_t Val;
+    } Imm;
+  };
+  
+  static X86Operand CreateReg(unsigned RegNo) {
+    X86Operand Res;
+    Res.Kind = Register;
+    Res.Reg.RegNo = RegNo;
+    return Res;
+  }
+  static X86Operand CreateImm(int64_t Val) {
+    X86Operand Res;
+    Res.Kind = Immediate;
+    Res.Imm.Val = Val;
+    return Res;
+  }
+};
+
+bool AsmParser::ParseX86Operand(X86Operand &Op) {
+  switch (Lexer.getKind()) {
+  default:
+    return TokError("unknown token at start of instruction operand");
+  case asmtok::Register:
+    // FIXME: Decode reg #.
+    Op = X86Operand::CreateReg(0);
+    Lexer.Lex(); // Eat register.
+    return false;
+  case asmtok::Dollar:
+    // $42 -> immediate.
+    Lexer.Lex();
+    // FIXME: Parse an arbitrary expression here, like $(4+5)
+    if (Lexer.isNot(asmtok::IntVal))
+      return TokError("expected integer constant");
+    
+    Op = X86Operand::CreateReg(Lexer.getCurIntVal());
+    Lexer.Lex(); // Eat register.
+    return false;
+  case asmtok::Identifier:
+    // This is a label, this should be parsed as part of an expression, to
+    // handle things like LFOO+4
+    Op = X86Operand::CreateImm(0); // FIXME.
+    Lexer.Lex(); // Eat identifier.
+    return false;
+      
+  //case asmtok::Star:
+  // * %eax
+  // * <memaddress>
+  // Note that these are both "dereferenced".
+  }
+}
+
 
 /// ParseStatement:
 ///   ::= EndOfStatement
-///   ::= Label* Identifier Operands* EndOfStatement
+///   ::= Label* Directive ...Operands... EndOfStatement
+///   ::= Label* Identifier OperandList* EndOfStatement
 bool AsmParser::ParseStatement() {
   switch (Lexer.getKind()) {
   default:
@@ -55,7 +130,7 @@
   }
   
   // If we have an identifier, handle it as the key symbol.
-  //SMLoc IDLoc = Lexer.getLoc();
+  SMLoc IDLoc = Lexer.getLoc();
   std::string IDVal = Lexer.getCurStrVal();
   
   // Consume the identifier, see what is after it.
@@ -66,18 +141,44 @@
   }
   
   // Otherwise, we have a normal instruction or directive.  
-  if (IDVal[0] == '.')
-    outs() << "Found directive: " << IDVal << "\n";
-  else
-    outs() << "Found instruction: " << IDVal << "\n";
+  if (IDVal[0] == '.') {
+    Lexer.PrintMessage(IDLoc, "warning: ignoring directive for now");
+    EatToEndOfStatement();
+    return false;
+  }
 
-  // Skip to end of line for now.
-  while (Lexer.isNot(asmtok::EndOfStatement) &&
-         Lexer.isNot(asmtok::Eof))
-    Lexer.Lex();
+  // If it's an instruction, parse an operand list.
+  std::vector<X86Operand> Operands;
   
-  // Eat EOL.
-  if (Lexer.is(asmtok::EndOfStatement))
-    Lexer.Lex();
+  // Read the first operand, if present.  Note that we require a newline at the
+  // end of file, so we don't have to worry about Eof here.
+  if (Lexer.isNot(asmtok::EndOfStatement)) {
+    X86Operand Op;
+    if (ParseX86Operand(Op))
+      return true;
+    Operands.push_back(Op);
+  }
+
+  while (Lexer.is(asmtok::Comma)) {
+    Lexer.Lex();  // Eat the comma.
+    
+    // Parse and remember the operand.
+    X86Operand Op;
+    if (ParseX86Operand(Op))
+      return true;
+    Operands.push_back(Op);
+  }
+  
+  if (Lexer.isNot(asmtok::EndOfStatement))
+    return TokError("unexpected token in operand list");
+
+  // Eat the end of statement marker.
+  Lexer.Lex();
+  
+  // Instruction is good, process it.
+  outs() << "Found instruction: " << IDVal << " with " << Operands.size()
+         << " operands.\n";
+  
+  // Skip to end of line for now.
   return false;
 }

Modified: llvm/trunk/tools/llvm-mc/AsmParser.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mc/AsmParser.h?rev=73867&r1=73866&r2=73867&view=diff

==============================================================================
--- llvm/trunk/tools/llvm-mc/AsmParser.h (original)
+++ llvm/trunk/tools/llvm-mc/AsmParser.h Sun Jun 21 20:29:09 2009
@@ -17,9 +17,10 @@
 #include "AsmLexer.h"
 
 namespace llvm {
-
+  
 class AsmParser {
   AsmLexer Lexer;
+  struct X86Operand;
   
 public:
   AsmParser(SourceMgr &SM) : Lexer(SM) {}
@@ -32,6 +33,10 @@
   
   bool Error(SMLoc L, const char *Msg);
   bool TokError(const char *Msg);
+  
+  void EatToEndOfStatement();
+  
+  bool ParseX86Operand(X86Operand &Op);
 };
 
 } // end namespace llvm





More information about the llvm-commits mailing list