diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 1daa2ed27214..ac3222631303 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -978,15 +978,36 @@ static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, // both 64-bit or 32-bit registers. // To support VSIB, IndexReg can be 128-bit or 256-bit registers. - if ((BaseReg == X86::RIP && IndexReg != 0) || (IndexReg == X86::RIP) || - (IndexReg == X86::ESP) || (IndexReg == X86::RSP)) { + if (BaseReg != 0 && + !(BaseReg == X86::RIP || BaseReg == X86::EIP || + X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) || + X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) || + X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg))) { + ErrMsg = "invalid base+index expression"; + return true; + } + + if (IndexReg != 0 && + !(IndexReg == X86::EIZ || IndexReg == X86::RIZ || + X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || + X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) || + X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) || + X86MCRegisterClasses[X86::VR128XRegClassID].contains(IndexReg) || + X86MCRegisterClasses[X86::VR256XRegClassID].contains(IndexReg) || + X86MCRegisterClasses[X86::VR512RegClassID].contains(IndexReg))) { + ErrMsg = "invalid base+index expression"; + return true; + } + + if (((BaseReg == X86::RIP || BaseReg == X86::EIP) && IndexReg != 0) || + IndexReg == X86::EIP || IndexReg == X86::RIP || + IndexReg == X86::ESP || IndexReg == X86::RSP) { 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. + // and then only in non-64-bit modes. if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg) && (Is64BitMode || (BaseReg != X86::BX && BaseReg != X86::BP && BaseReg != X86::SI && BaseReg != X86::DI))) { @@ -1003,15 +1024,15 @@ static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg, if (BaseReg != 0 && IndexReg != 0) { if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) && (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || - X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) && - IndexReg != X86::RIZ) { + X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) || + IndexReg == X86::EIZ)) { ErrMsg = "base register is 64-bit, but index register is not"; return true; } if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) && (X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) || - X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) && - IndexReg != X86::EIZ){ + X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg) || + IndexReg == X86::RIZ)) { ErrMsg = "base register is 32-bit, but index register is not"; return true; } diff --git a/llvm/test/MC/X86/x86_errors.s b/llvm/test/MC/X86/x86_errors.s index 1abcfa5aaeb2..1fe0a583e59c 100644 --- a/llvm/test/MC/X86/x86_errors.s +++ b/llvm/test/MC/X86/x86_errors.s @@ -102,3 +102,19 @@ lea (%si,%bx), %ax // 32: error: invalid 16-bit base/index register combination // 64: error: invalid 16-bit base register lea (%di,%bx), %ax + +// 32: error: invalid base+index expression +// 64: error: invalid base+index expression +mov (,%eip), %rbx + +// 32: error: invalid base+index expression +// 64: error: invalid base+index expression +mov (%eip,%eax), %rbx + +// 32: error: register %rax is only available in 64-bit mode +// 64: error: base register is 64-bit, but index register is not +mov (%rax,%eiz), %ebx + +// 32: error: register %riz is only available in 64-bit mode +// 64: error: base register is 32-bit, but index register is not +mov (%eax,%riz), %ebx