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:
parent
632c6cd114
commit
bc570f289a
|
@ -1152,6 +1152,44 @@ struct X86Operand : public MCParsedAsmOperand {
|
||||||
|
|
||||||
} // end anonymous namespace.
|
} // 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)
|
bool X86AsmParser::doSrcDstMatch(X86Operand &Op1, X86Operand &Op2)
|
||||||
{
|
{
|
||||||
// Return true and let a normal complaint about bogus operands happen.
|
// Return true and let a normal complaint about bogus operands happen.
|
||||||
|
@ -1575,6 +1613,11 @@ X86Operand *X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
|
||||||
else
|
else
|
||||||
return X86Operand::CreateMem(SegReg, Disp, 0, 0, 1, Start, End, Size);
|
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,
|
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale, Start,
|
||||||
End, Size);
|
End, Size);
|
||||||
}
|
}
|
||||||
|
@ -2080,38 +2123,11 @@ X86Operand *X86AsmParser::ParseMemOperand(unsigned SegReg, SMLoc MemStart) {
|
||||||
Error(IndexLoc, "16-bit memory operand may not include only index register");
|
Error(IndexLoc, "16-bit memory operand may not include only index register");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// If we have both a base register and an index register make sure they are
|
|
||||||
// both 64-bit or 32-bit registers.
|
StringRef ErrMsg;
|
||||||
// To support VSIB, IndexReg can be 128-bit or 256-bit registers.
|
if (CheckBaseRegAndIndexReg(BaseReg, IndexReg, ErrMsg)) {
|
||||||
if (BaseReg != 0 && IndexReg != 0) {
|
Error(BaseLoc, ErrMsg);
|
||||||
if (X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) &&
|
return 0;
|
||||||
(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");
|
|
||||||
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,
|
return X86Operand::CreateMem(SegReg, Disp, BaseReg, IndexReg, Scale,
|
||||||
|
|
|
@ -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]
|
Loading…
Reference in New Issue