Added the ParseInstruction() hook for target specific assembler directives so
authorKevin Enderby <enderby@apple.com>
Thu, 10 Sep 2009 20:51:44 +0000 (20:51 +0000)
committerKevin Enderby <enderby@apple.com>
Thu, 10 Sep 2009 20:51:44 +0000 (20:51 +0000)
that things like .word can be parsed as target specific.  Moved parsing .word
out of AsmParser.cpp into X86AsmParser.cpp as it is 2 bytes on X86 and 4 bytes
for other targets that support the .word directive.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81461 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/TargetAsmParser.h
lib/Target/X86/AsmParser/X86AsmParser.cpp
tools/llvm-mc/AsmParser.cpp
tools/llvm-mc/llvm-mc.cpp

index 8b8b2106ee68747da6dfb342aca37e7aee4e5541..ef1fc49cefee5202dbd183b109215f6a910049eb 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef LLVM_TARGET_TARGETPARSER_H
 #define LLVM_TARGET_TARGETPARSER_H
 
+#include "llvm/MC/MCAsmLexer.h"
+
 namespace llvm {
 class MCAsmParser;
 class MCInst;
@@ -44,6 +46,18 @@ public:
   /// \param Inst [out] - On success, the parsed instruction.
   /// \return True on failure.
   virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst) = 0;
+
+  /// ParseDirective - Parse a target specific assembler directive
+  ///
+  /// The parser is positioned following the directive name.  The target
+  /// specific directive parser should parse the entire directive doing or
+  /// recording any target specific work, or return true and do nothing if the
+  /// directive is not target specific. If the directive is specific for
+  /// the target, the entire line is parsed up to and including the
+  /// end-of-statement token and false is returned.
+  ///
+  /// \param ID - the identifier token of the directive.
+  virtual bool ParseDirective(AsmToken DirectiveID) = 0;
 };
 
 } // End llvm namespace
index e5f23e018bf3db7e91f3de8f766067971956b291..aa04ba60d37778192919893cb34a099c0043f674 100644 (file)
@@ -12,6 +12,7 @@
 #include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCAsmLexer.h"
 #include "llvm/MC/MCAsmParser.h"
+#include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCExpr.h"
 #include "llvm/MC/MCInst.h"
 #include "llvm/Support/SourceMgr.h"
@@ -39,7 +40,9 @@ private:
   bool ParseOperand(X86Operand &Op);
 
   bool ParseMemOperand(X86Operand &Op);
-  
+
+  bool ParseDirectiveWord(unsigned Size, SMLoc L);
+
   /// @name Auto-generated Match Functions
   /// {  
 
@@ -57,6 +60,8 @@ public:
     : TargetAsmParser(T), Parser(_Parser) {}
 
   virtual bool ParseInstruction(const StringRef &Name, MCInst &Inst);
+
+  virtual bool ParseDirective(AsmToken DirectiveID);
 };
   
 } // end anonymous namespace
@@ -432,6 +437,38 @@ bool X86ATTAsmParser::ParseInstruction(const StringRef &Name, MCInst &Inst) {
   return true;
 }
 
+bool X86ATTAsmParser::ParseDirective(AsmToken DirectiveID) {
+  StringRef IDVal = DirectiveID.getIdentifier();
+  if (IDVal == ".word")
+    return ParseDirectiveWord(2, DirectiveID.getLoc());
+  return true;
+}
+
+/// ParseDirectiveWord
+///  ::= .word [ expression (, expression)* ]
+bool X86ATTAsmParser::ParseDirectiveWord(unsigned Size, SMLoc L) {
+  if (getLexer().isNot(AsmToken::EndOfStatement)) {
+    for (;;) {
+      const MCExpr *Value;
+      if (getParser().ParseExpression(Value))
+        return true;
+
+      getParser().getStreamer().EmitValue(Value, Size);
+
+      if (getLexer().is(AsmToken::EndOfStatement))
+        break;
+      
+      // FIXME: Improve diagnostic.
+      if (getLexer().isNot(AsmToken::Comma))
+        return Error(L, "unexpected token in directive");
+      getLexer().Lex();
+    }
+  }
+
+  getLexer().Lex();
+  return false;
+}
+
 // Force static initialization.
 extern "C" void LLVMInitializeX86AsmParser() {
   RegisterAsmParser<X86ATTAsmParser> X(TheX86_32Target);
index f51f43adc1226461f6557a1ec2bd3f5b5d07ddc2..b1e8e9ae404fa64de604157d105141057771f6ba 100644 (file)
@@ -591,10 +591,9 @@ bool AsmParser::ParseStatement() {
     if (IDVal == ".asciz")
       return ParseDirectiveAscii(true);
 
-    // FIXME: Target hooks for size? Also for "word", "hword".
     if (IDVal == ".byte")
       return ParseDirectiveValue(1);
-    if (IDVal == ".short" || IDVal == ".word")
+    if (IDVal == ".short")
       return ParseDirectiveValue(2);
     if (IDVal == ".long")
       return ParseDirectiveValue(4);
@@ -685,6 +684,10 @@ bool AsmParser::ParseStatement() {
     if (IDVal == ".loc")
       return ParseDirectiveLoc(IDLoc);
 
+    // Target hook for parsing target specific directives.
+    if (!getTargetParser().ParseDirective(ID))
+      return false;
+
     Warning(IDLoc, "ignoring directive for now");
     EatToEndOfStatement();
     return false;
index bf3c01794bca25a98f5c576d524a90e6bbee7ea8..e5d99be9e93f275846675d5ea83471d952c2deeb 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/MC/MCCodeEmitter.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCAsmLexer.h"
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/CodeGen/AsmPrinter.h"
 #include "llvm/Support/CommandLine.h"