From eef6d78be1c3a685f277be3e89ff17f67ed65f49 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 17 Apr 2010 18:56:34 +0000 Subject: [PATCH] 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 --- include/llvm/MC/MCParser/AsmParser.h | 2 +- lib/Target/X86/AsmParser/X86AsmParser.cpp | 29 +++++++++++++---------- test/MC/AsmParser/X86/x86_operands.s | 4 +++- 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 a50abd6b61a..7a78906733a 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 #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 namespace llvm { class AsmCond; diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 47873d14a91..da013505dab 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 edddd1fc449..bf958d8478c 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 3750fdb2f1d..fc6e67b2e88 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