diff options
author | Daniel Dunbar <daniel@zuster.org> | 2009-07-02 02:26:39 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2009-07-02 02:26:39 +0000 |
commit | 5470e12c6221b40102e56ab3f280685e605475b7 (patch) | |
tree | 9945362e5dd62c02985a30d0bae878ec4e5232ef | |
parent | 3d62a412fbe517fbbbf5661ef1a748a39f382aa3 (diff) | |
download | external_llvm-5470e12c6221b40102e56ab3f280685e605475b7.zip external_llvm-5470e12c6221b40102e56ab3f280685e605475b7.tar.gz external_llvm-5470e12c6221b40102e56ab3f280685e605475b7.tar.bz2 |
llvm-mc/x86: Fix various nit-picky bugs in displacement parsing.
- Test case to follow.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74687 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | tools/llvm-mc/MC-X86Specific.cpp | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/tools/llvm-mc/MC-X86Specific.cpp b/tools/llvm-mc/MC-X86Specific.cpp index a186618..fec13ce 100644 --- a/tools/llvm-mc/MC-X86Specific.cpp +++ b/tools/llvm-mc/MC-X86Specific.cpp @@ -14,6 +14,7 @@ #include "AsmParser.h" #include "llvm/MC/MCInst.h" +#include "llvm/Support/SourceMgr.h" using namespace llvm; /// X86Operand - Instances of this class represent one X86 machine instruction. @@ -178,26 +179,48 @@ bool AsmParser::ParseX86MemOperand(X86Operand &Op) { } if (Lexer.is(asmtok::Comma)) { - Lexer.Lex(); // eat the comma. - + Lexer.Lex(); // Eat the comma. + + // Following the comma we should have either an index register, or a scale + // value. We don't support the later form, but we want to parse it + // correctly. + // + // Not that even though it would be completely consistent to support syntax + // like "1(%eax,,1)", the assembler doesn't. if (Lexer.is(asmtok::Register)) { if (ParseX86Register(Op)) return true; IndexReg = Op.getReg(); Scale = 1; // If not specified, the scale defaults to 1. - } - if (Lexer.is(asmtok::Comma)) { - Lexer.Lex(); // Eat the comma. - - // If present, get and validate scale amount. - if (Lexer.is(asmtok::IntVal)) { - int64_t ScaleVal = Lexer.getCurIntVal(); - if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8) - return TokError("scale factor in address must be 1, 2, 4 or 8"); - Lexer.Lex(); // eat the scale. - Scale = (unsigned)ScaleVal; + if (Lexer.isNot(asmtok::RParen)) { + // Parse the scale amount: + // ::= ',' [scale-expression] + if (Lexer.isNot(asmtok::Comma)) + return true; + Lexer.Lex(); // Eat the comma. + + if (Lexer.isNot(asmtok::RParen)) { + int64_t ScaleVal; + if (ParseAbsoluteExpression(ScaleVal)) + return true; + + // Validate the scale amount. + if (ScaleVal != 1 && ScaleVal != 2 && ScaleVal != 4 && ScaleVal != 8) + return TokError("scale factor in address must be 1, 2, 4 or 8"); + Scale = (unsigned)ScaleVal; + } } + } else if (Lexer.isNot(asmtok::RParen)) { + // Otherwise we have the unsupported form of a scale amount without an + // index. + SMLoc Loc = Lexer.getLoc(); + + int64_t Value; + if (ParseAbsoluteExpression(Value)) + return true; + + return Error(Loc, "cannot have scale factor without index register"); } } |