teach the x86 asm parser how to handle segment prefixes
authorChris Lattner <sabre@nondot.org>
Sat, 17 Apr 2010 18:56:34 +0000 (18:56 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 17 Apr 2010 18:56:34 +0000 (18:56 +0000)
in memory operands.  rdar://7874844

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

include/llvm/MC/MCParser/AsmParser.h
lib/Target/X86/AsmParser/X86AsmParser.cpp
test/MC/AsmParser/X86/x86_operands.s
test/Makefile

index a50abd6b61a227a69ef37063a6c8f00942b49bdc..7a78906733afa1659344f4e5f1aaa887a018830d 100644 (file)
@@ -14,7 +14,6 @@
 #ifndef ASMPARSER_H
 #define ASMPARSER_H
 
-#include <vector>
 #include "llvm/MC/MCParser/AsmLexer.h"
 #include "llvm/MC/MCParser/AsmCond.h"
 #include "llvm/MC/MCParser/MCAsmParser.h"
@@ -22,6 +21,7 @@
 #include "llvm/MC/MCStreamer.h"
 #include "llvm/MC/MCAsmInfo.h"
 #include "llvm/ADT/StringMap.h"
+#include <vector>
 
 namespace llvm {
 class AsmCond;
index 47873d14a9114b613b147750c597544feedab08f..da013505dabd7c369a5e35886a5366c58d6c2010 100644 (file)
@@ -44,7 +44,7 @@ private:
   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
 
   X86Operand *ParseOperand();
-  X86Operand *ParseMemOperand();
+  X86Operand *ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
 
   bool ParseDirectiveWord(unsigned Size, SMLoc L);
 
@@ -368,14 +368,22 @@ bool X86ATTAsmParser::ParseRegister(unsigned &RegNo,
 X86Operand *X86ATTAsmParser::ParseOperand() {
   switch (getLexer().getKind()) {
   default:
-    return ParseMemOperand();
+    // Parse a memory operand with no segment register.
+    return ParseMemOperand(0, Parser.getTok().getLoc());
   case AsmToken::Percent: {
-    // FIXME: if a segment register, this could either be just the seg reg, or
-    // the start of a memory operand.
+    // Read the register.
     unsigned RegNo;
     SMLoc Start, End;
     if (ParseRegister(RegNo, Start, End)) return 0;
-    return X86Operand::CreateReg(RegNo, Start, End);
+    
+    // If this is a segment register followed by a ':', then this is the start
+    // of a memory reference, otherwise this is a normal register reference.
+    if (getLexer().isNot(AsmToken::Colon))
+      return X86Operand::CreateReg(RegNo, Start, End);
+    
+    
+    getParser().Lex(); // Eat the colon.
+    return ParseMemOperand(RegNo, Start);
   }
   case AsmToken::Dollar: {
     // $42 -> immediate.
@@ -389,13 +397,10 @@ X86Operand *X86ATTAsmParser::ParseOperand() {
   }
 }
 
-/// ParseMemOperand: segment: disp(basereg, indexreg, scale)
-X86Operand *X86ATTAsmParser::ParseMemOperand() {
-  SMLoc MemStart = Parser.getTok().getLoc();
-  
-  // FIXME: If SegReg ':'  (e.g. %gs:), eat and remember.
-  unsigned SegReg = 0;
-  
+/// ParseMemOperand: segment: disp(basereg, indexreg, scale).  The '%ds:' prefix
+/// has already been parsed if present.
+X86Operand *X86ATTAsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
   // We have to disambiguate a parenthesized expression "(4+5)" from the start
   // of a memory operand with a missing displacement "(%ebx)" or "(,%eax)".  The
   // only way to do this without lookahead is to eat the '(' and see what is
index edddd1fc44920116efdcd57bebb7a123937674ef..bf958d8478ca3354b443c7c7274330b04c236736 100644 (file)
@@ -55,4 +55,6 @@
 # CHECK: call *4(%eax)
         call *4(%eax)
 
-        
+# CHECK: movl  %gs:8, %eax
+movl %gs:8, %eax
+
index 3750fdb2f1d093e7c31057abd4c3f01a0d94b640..fc6e67b2e88f278cfe2c0047183b4a0efc5fabec 100644 (file)
@@ -28,7 +28,7 @@ endif
 
 ifdef VERBOSE
 RUNTESTFLAGS := $(VERBOSE)
-LIT_ARGS := -v
+LIT_ARGS := -v -j16
 else
 LIT_ARGS := -s -v
 endif