Update the X86 assembler for .intel_syntax to produce an error for invalid base

registers in memory addresses that do not match the index register. As it does
for .att_syntax.

rdar://15887380

llvm-svn: 199948
This commit is contained in:
Kevin Enderby 2014-01-23 22:34:42 +00:00
parent 632c6cd114
commit bc570f289a
2 changed files with 55 additions and 32 deletions

View File

@ -1152,6 +1152,44 @@ struct X86Operand : public MCParsedAsmOperand {
} // end anonymous namespace.
static bool CheckBaseRegAndIndexReg(unsigned BaseReg, unsigned IndexReg,
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.
if (BaseReg != 0 && IndexReg != 0) {
if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
(X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
IndexReg != X86::RIZ) {
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){
ErrMsg = "base register is 32-bit, but index register is not";
return true;
}
if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
ErrMsg = "base register is 16-bit, but index register is not";
return true;
}
if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
IndexReg != X86::SI && IndexReg != X86::DI) ||
((BaseReg == X86::SI || BaseReg == X86::DI) &&
IndexReg != X86::BX && IndexReg != X86::BP)) {
ErrMsg = "invalid 16-bit base/index register combination";
return true;
}
}
}
return false;
}
bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
{
// Return true and let a normal complaint about bogus operands happen.
@ -1575,6 +1613,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
else
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
}
StringRef ErrMsg;
if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
Error(StartInBrac, ErrMsg);
return 0;
}
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
End, Size);
}
@ -2080,39 +2123,12 @@ X86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
Error(IndexLoc, "16-bit memory operand may not include only index register");
return 0;
}
// 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.
if (BaseReg != 0 && IndexReg != 0) {
if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
(X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg)) &&
IndexReg != X86::RIZ) {
Error(BaseLoc, "base register is 64-bit, but index register is not");
StringRef ErrMsg;
if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
Error(BaseLoc, ErrMsg);
return 0;
}
if (X86MCRegisterClasses[X86::GR32RegClassID].contains(BaseReg) &&
(X86MCRegisterClasses[X86::GR16RegClassID].contains(IndexReg) ||
X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) &&
IndexReg != X86::EIZ){
Error(BaseLoc, "base register is 32-bit, but index register is not");
return 0;
}
if (X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg)) {
if (X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg) ||
X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg)) {
Error(BaseLoc, "base register is 16-bit, but index register is not");
return 0;
}
if (((BaseReg == X86::BX || BaseReg == X86::BP) &&
IndexReg != X86::SI && IndexReg != X86::DI) ||
((BaseReg == X86::SI || BaseReg == X86::DI) &&
IndexReg != X86::BX && IndexReg != X86::BP)) {
Error(BaseLoc, "invalid 16-bit base/index register combination");
return 0;
}
}
}
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
MemStart, MemEnd);

View File

@ -0,0 +1,7 @@
// RUN: not llvm-mc -triple x86_64-unknown-unknown %s 2> %t.err
// RUN: FileCheck < %t.err %s
.intel_syntax
// CHECK: error: base register is 64-bit, but index register is not
lea rax, [rdi + edx]