diff options
-rw-r--r-- | llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp | 43 | ||||
-rw-r--r-- | llvm/test/MC/X86/intel-syntax-error.s | 2 |
2 files changed, 26 insertions, 19 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index dc4f7ca6e26..d72af591f05 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -971,7 +971,8 @@ static unsigned MatchRegisterName(StringRef Name); /// } static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, - unsigned Scale, StringRef &ErrMsg) { + unsigned Scale, bool Is64BitMode, + StringRef &ErrMsg) { // If we have both a base register and an index register make sure they are // both 64-bit or 32-bit registers. // To support VSIB, IndexReg can be 128-bit or 256-bit registers. @@ -981,6 +982,24 @@ static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, ErrMsg = "invalid base+index expression"; return true; } + + // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed, + // and then only in non-64-bit modes. Except for DX, which is a special case + // because an unofficial form of in/out instructions uses it. + if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && + (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP && + BaseReg != X86::SI && BaseReg != X86::DI)) && + BaseReg != X86::DX) { + ErrMsg = "invalid 16-bit base register"; + return true; + } + + if (BaseReg == 0 && + X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) { + ErrMsg = "16-bit memory operand may not include only index register"; + return true; + } + if (BaseReg != 0 && IndexReg != 0) { if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || @@ -1842,7 +1861,8 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() { unsigned Scale = SM.getScale(); if ((BaseReg || IndexReg) && - CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) + CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(), + ErrMsg)) return ErrorOperand(Start, ErrMsg); if (isParsingInlineAsm()) return CreateMemForInlineAsm(RegNo, Disp, BaseReg, IndexReg, @@ -2161,24 +2181,9 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg, if (parseToken(AsmToken::RParen, "unexpected token in memory operand")) return nullptr; - // Check for use of invalid 16-bit registers. Only BX/BP/SI/DI are allowed, - // and then only in non-64-bit modes. Except for DX, which is a special case - // because an unofficial form of in/out instructions uses it. - if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && - (is64BitMode() || (BaseReg != X86::BX && BaseReg != X86::BP && - BaseReg != X86::SI && BaseReg != X86::DI)) && - BaseReg != X86::DX) { - Error(BaseLoc, "invalid 16-bit base register"); - return nullptr; - } - if (BaseReg == 0 && - X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg)) { - Error(IndexLoc, "16-bit memory operand may not include only index register"); - return nullptr; - } - StringRef ErrMsg; - if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, ErrMsg)) { + if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(), + ErrMsg)) { Error(BaseLoc, ErrMsg); return nullptr; } diff --git a/llvm/test/MC/X86/intel-syntax-error.s b/llvm/test/MC/X86/intel-syntax-error.s index ab875b4e982..89044c0098b 100644 --- a/llvm/test/MC/X86/intel-syntax-error.s +++ b/llvm/test/MC/X86/intel-syntax-error.s @@ -44,3 +44,5 @@ punpcklwd mm0, word ptr [rsp] // CHECK: error: invalid operand for instruction punpckldq mm0, qword ptr [rsp] +// CHECK: error: invalid 16-bit base register +lea bx, [ax] |