diff options
author | Chris Lattner <sabre@nondot.org> | 2010-04-17 18:56:34 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-04-17 18:56:34 +0000 |
commit | eef6d78be1c3a685f277be3e89ff17f67ed65f49 (patch) | |
tree | 4ea90a963db29bfa1027bfe973718d4a08ed4d90 | |
parent | 7834facff938cccce294e5c4065202d922411a5d (diff) |
teach the x86 asm parser how to handle segment prefixes
in memory operands. rdar://7874844
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101661 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/MC/MCParser/AsmParser.h | 2 | ||||
-rw-r--r-- | lib/Target/X86/AsmParser/X86AsmParser.cpp | 29 | ||||
-rw-r--r-- | test/MC/AsmParser/X86/x86_operands.s | 4 | ||||
-rw-r--r-- | test/Makefile | 2 |
4 files changed, 22 insertions, 15 deletions
diff --git a/include/llvm/MC/MCParser/AsmParser.h b/include/llvm/MC/MCParser/AsmParser.h index a50abd6b61..7a78906733 100644 --- a/include/llvm/MC/MCParser/AsmParser.h +++ b/include/llvm/MC/MCParser/AsmParser.h @@ -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; diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 47873d14a9..da013505da 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -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 diff --git a/test/MC/AsmParser/X86/x86_operands.s b/test/MC/AsmParser/X86/x86_operands.s index edddd1fc44..bf958d8478 100644 --- a/test/MC/AsmParser/X86/x86_operands.s +++ b/test/MC/AsmParser/X86/x86_operands.s @@ -55,4 +55,6 @@ # CHECK: call *4(%eax) call *4(%eax) - +# CHECK: movl %gs:8, %eax +movl %gs:8, %eax + diff --git a/test/Makefile b/test/Makefile index 3750fdb2f1..fc6e67b2e8 100644 --- a/test/Makefile +++ b/test/Makefile @@ -28,7 +28,7 @@ endif ifdef VERBOSE RUNTESTFLAGS := $(VERBOSE) -LIT_ARGS := -v +LIT_ARGS := -v -j16 else LIT_ARGS := -s -v endif |