diff options
| author | Craig Topper <craig.topper@intel.com> | 2018-06-22 22:28:39 +0000 |
|---|---|---|
| committer | Craig Topper <craig.topper@intel.com> | 2018-06-22 22:28:39 +0000 |
| commit | 10e2f73793981045ae35239fc5590d131a486f11 (patch) | |
| tree | eb59d9b9bd7820d1e2053da0e4c2eb16ddd48c07 | |
| parent | 1e2d5cb06c4543f0c49beb8b585d63a90e915499 (diff) | |
| download | bcm5719-llvm-10e2f73793981045ae35239fc5590d131a486f11.tar.gz bcm5719-llvm-10e2f73793981045ae35239fc5590d131a486f11.zip | |
[X86][AsmParser] Keep track of whether an explicit scale was specified while parsing an address in Intel syntax. Use it for improved error checking.
This allows us to check these:
-16-bit addressing doesn't support scale so we should error if we find one there.
-Multiplying ESP/RSP by a scale even if the scale is 1 should be an error because ESP/RSP can't be an index.
llvm-svn: 335398
| -rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 24 | ||||
| -rw-r--r-- | llvm/test/MC/X86/intel-syntax-error.s | 6 |
2 files changed, 22 insertions, 8 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 424373e7e87..fced1b70acc 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -346,7 +346,7 @@ private: public: IntelExprStateMachine() : State(IES_INIT), PrevState(IES_ERROR), BaseReg(0), IndexReg(0), - TmpReg(0), Scale(1), Imm(0), Sym(nullptr), BracCount(0), + TmpReg(0), Scale(0), Imm(0), Sym(nullptr), BracCount(0), MemExpr(false) {} void addImm(int64_t imm) { Imm += imm; } @@ -452,7 +452,7 @@ private: IC.pushOperator(IC_PLUS); if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { // If we already have a BaseReg, then assume this is the IndexReg with - // a scale of 1. + // no explicit scale. if (!BaseReg) { BaseReg = TmpReg; } else { @@ -461,7 +461,7 @@ private: return true; } IndexReg = TmpReg; - Scale = 1; + Scale = 0; } } break; @@ -505,7 +505,7 @@ private: IC.pushOperator(IC_NEG); if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { // If we already have a BaseReg, then assume this is the IndexReg with - // a scale of 1. + // no explicit scale. if (!BaseReg) { BaseReg = TmpReg; } else { @@ -514,7 +514,7 @@ private: return true; } IndexReg = TmpReg; - Scale = 1; + Scale = 0; } } break; @@ -737,13 +737,13 @@ private: State = IES_RBRAC; if (CurrState == IES_REGISTER && PrevState != IES_MULTIPLY) { // If we already have a BaseReg, then assume this is the IndexReg with - // a scale of 1. + // no explicit scale. if (!BaseReg) { BaseReg = TmpReg; } else { assert (!IndexReg && "BaseReg/IndexReg already set!"); IndexReg = TmpReg; - Scale = 1; + Scale = 0; } } break; @@ -1858,10 +1858,18 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() { unsigned IndexReg = SM.getIndexReg(); unsigned Scale = SM.getScale(); - if (Scale == 1 && BaseReg != X86::ESP && BaseReg != X86::RSP && + if (Scale == 0 && BaseReg != X86::ESP && BaseReg != X86::RSP && (IndexReg == X86::ESP || IndexReg == X86::RSP)) std::swap(BaseReg, IndexReg); + if (Scale != 0 && + X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) + return ErrorOperand(Start, "16-bit addresses cannot have a scale"); + + // If there was no explicit scale specified, change it to 1. + if (Scale == 0) + Scale = 1; + // If this is a 16-bit addressing mode with the base and index in the wrong // order, swap them so CheckBaseRegAndIndexRegAndScale doesn't fail. It is // shared with att syntax where order matters. diff --git a/llvm/test/MC/X86/intel-syntax-error.s b/llvm/test/MC/X86/intel-syntax-error.s index 89044c0098b..2ccfc490463 100644 --- a/llvm/test/MC/X86/intel-syntax-error.s +++ b/llvm/test/MC/X86/intel-syntax-error.s @@ -46,3 +46,9 @@ punpckldq mm0, qword ptr [rsp] // CHECK: error: invalid 16-bit base register lea bx, [ax] + +// CHECK: invalid base+index expression +lea eax, [eax+esp*1] + +// CHECK: 16-bit addresses cannot have a scale +lea ax, [bx+si*1] |

