[llvm] r335403 - [X86][AsmParser] Rework that allows (%dx) to be used in place of %dx with in/out instructions.
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Fri Jun 22 17:03:21 PDT 2018
Author: ctopper
Date: Fri Jun 22 17:03:20 2018
New Revision: 335403
URL: http://llvm.org/viewvc/llvm-project?rev=335403&view=rev
Log:
[X86][AsmParser] Rework that allows (%dx) to be used in place of %dx with in/out instructions.
Previously, to support (%dx) we left a wide open hole in our 16-bit memory address checking. This let this address value be used with any instruction without error in the parser. It would later fail in the encoder with an assertion failure on debug builds and who knows what on release builds.
This patch passes the mnemonic down to the memory operand parsing function so we can allow the (%dx) form only on specific instructions.
Modified:
llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
Modified: llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp?rev=335403&r1=335402&r2=335403&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/X86/AsmParser/X86AsmParser.cpp Fri Jun 22 17:03:20 2018
@@ -819,8 +819,8 @@ private:
std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
OperandVector &FinalOperands);
- std::unique_ptr<X86Operand> ParseOperand();
- std::unique_ptr<X86Operand> ParseATTOperand();
+ std::unique_ptr<X86Operand> ParseOperand(StringRef Mnemonic);
+ std::unique_ptr<X86Operand> ParseATTOperand(StringRef Mnemonic);
std::unique_ptr<X86Operand> ParseIntelOperand();
std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
@@ -835,7 +835,8 @@ private:
InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedOperand, SMLoc &End);
- std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
+ std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc,
+ StringRef Mnemonic);
bool ParseIntelMemoryOperandSize(unsigned &Size);
std::unique_ptr<X86Operand>
@@ -988,8 +989,7 @@ static bool CheckBaseRegAndIndexRegAndSc
// 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) {
+ BaseReg != X86::SI && BaseReg != X86::DI))) {
ErrMsg = "invalid 16-bit base register";
return true;
}
@@ -1302,10 +1302,10 @@ bool X86AsmParser::VerifyAndAdjustOperan
return false;
}
-std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
+std::unique_ptr<X86Operand> X86AsmParser::ParseOperand(StringRef Mnemonic) {
if (isParsingIntelSyntax())
return ParseIntelOperand();
- return ParseATTOperand();
+ return ParseATTOperand(Mnemonic);
}
std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
@@ -1891,12 +1891,12 @@ std::unique_ptr<X86Operand> X86AsmParser
BaseReg, IndexReg, Scale, Start, End, Size);
}
-std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
+std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand(StringRef Mnemonic) {
MCAsmParser &Parser = getParser();
switch (getLexer().getKind()) {
default:
// Parse a memory operand with no segment register.
- return ParseMemOperand(0, Parser.getTok().getLoc());
+ return ParseMemOperand(0, Parser.getTok().getLoc(), Mnemonic);
case AsmToken::Percent: {
// Read the register.
unsigned RegNo;
@@ -1922,7 +1922,7 @@ std::unique_ptr<X86Operand> X86AsmParser
return ErrorOperand(Start, "invalid segment register");
getParser().Lex(); // Eat the colon.
- return ParseMemOperand(RegNo, Start);
+ return ParseMemOperand(RegNo, Start, Mnemonic);
}
case AsmToken::Dollar: {
// $42 -> immediate.
@@ -2048,7 +2048,8 @@ bool X86AsmParser::HandleAVX512Operand(O
/// ParseMemOperand: segment: disp(basereg, indexreg, scale). The '%ds:' prefix
/// has already been parsed if present.
std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
- SMLoc MemStart) {
+ SMLoc MemStart,
+ StringRef Mnemonic) {
MCAsmParser &Parser = getParser();
// We have to disambiguate a parenthesized expression "(4+5)" from the start
@@ -2198,6 +2199,22 @@ std::unique_ptr<X86Operand> X86AsmParser
if (parseToken(AsmToken::RParen, "unexpected token in memory operand"))
return nullptr;
+ // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
+ // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
+ // documented form in various unofficial manuals, so a lot of code uses it.
+ if (BaseReg == X86::DX && IndexReg == 0 && Scale == 1 &&
+ SegReg == 0 && isa<MCConstantExpr>(Disp) &&
+ cast<MCConstantExpr>(Disp)->getValue() == 0 &&
+ (Mnemonic == "outb" || Mnemonic == "outsb" ||
+ Mnemonic == "outw" || Mnemonic == "outsw" ||
+ Mnemonic == "outl" || Mnemonic == "outsl" ||
+ Mnemonic == "out" || Mnemonic == "outs" ||
+ Mnemonic == "inb" || Mnemonic == "insb" ||
+ Mnemonic == "inw" || Mnemonic == "insw" ||
+ Mnemonic == "inl" || Mnemonic == "insl" ||
+ Mnemonic == "in" || Mnemonic == "ins"))
+ return X86Operand::CreateReg(BaseReg, BaseLoc, BaseLoc);
+
StringRef ErrMsg;
if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
ErrMsg)) {
@@ -2459,7 +2476,7 @@ bool X86AsmParser::ParseInstruction(Pars
// Read the operands.
while(1) {
- if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
+ if (std::unique_ptr<X86Operand> Op = ParseOperand(Name)) {
Operands.push_back(std::move(Op));
if (HandleAVX512Operand(Operands, *Operands.back()))
return true;
@@ -2529,35 +2546,6 @@ bool X86AsmParser::ParseInstruction(Pars
}
}
- // This is a terrible hack to handle "out[s]?[bwl]? %al, (%dx)" ->
- // "outb %al, %dx". Out doesn't take a memory form, but this is a widely
- // documented form in various unofficial manuals, so a lot of code uses it.
- if ((Name == "outb" || Name == "outsb" || Name == "outw" || Name == "outsw" ||
- Name == "outl" || Name == "outsl" || Name == "out" || Name == "outs") &&
- Operands.size() == 3) {
- X86Operand &Op = (X86Operand &)*Operands.back();
- if (Op.isMem() && Op.Mem.SegReg == 0 &&
- isa<MCConstantExpr>(Op.Mem.Disp) &&
- cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
- Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
- SMLoc Loc = Op.getEndLoc();
- Operands.back() = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
- }
- }
- // Same hack for "in[s]?[bwl]? (%dx), %al" -> "inb %dx, %al".
- if ((Name == "inb" || Name == "insb" || Name == "inw" || Name == "insw" ||
- Name == "inl" || Name == "insl" || Name == "in" || Name == "ins") &&
- Operands.size() == 3) {
- X86Operand &Op = (X86Operand &)*Operands[1];
- if (Op.isMem() && Op.Mem.SegReg == 0 &&
- isa<MCConstantExpr>(Op.Mem.Disp) &&
- cast<MCConstantExpr>(Op.Mem.Disp)->getValue() == 0 &&
- Op.Mem.BaseReg == MatchRegisterName("dx") && Op.Mem.IndexReg == 0) {
- SMLoc Loc = Op.getEndLoc();
- Operands[1] = X86Operand::CreateReg(Op.Mem.BaseReg, Loc, Loc);
- }
- }
-
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
bool HadVerifyError = false;
More information about the llvm-commits
mailing list