summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@intel.com>2018-07-03 18:07:30 +0000
committerCraig Topper <craig.topper@intel.com>2018-07-03 18:07:30 +0000
commitadc51ae4255044fe3ba50768013d7f47b2102c79 (patch)
treea6b8f0db51750a662816a2a9f658e3c1e1cd548e /llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
parentbc598f0d61b54324639eb029374493cf6cd55c6f (diff)
downloadbcm5719-llvm-adc51ae4255044fe3ba50768013d7f47b2102c79.tar.gz
bcm5719-llvm-adc51ae4255044fe3ba50768013d7f47b2102c79.zip
[X86][AsmParser] Rework the in/out (%dx) hack one more time.
This patch adds a new token type specifically for (%dx). We will now always create this token when we parse (%dx). After all operands have been parsed, if the mnemonic is in/out we'll morph this token to a regular register token. Otherwise we keep it as the special DX token which won't match any instructions. This removes the need for passing Mnemonic through the parsing functions. It also seems closer to gas where when its used on the wrong instruction it just gets diagnosed as an invalid operand rather than a bad memory address. llvm-svn: 336218
Diffstat (limited to 'llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r--llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp58
1 files changed, 35 insertions, 23 deletions
diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 7fd7e0b0ec3..e8a2468f874 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -819,8 +819,8 @@ private:
std::unique_ptr<llvm::MCParsedAsmOperand> &&Dst);
bool VerifyAndAdjustOperands(OperandVector &OrigOperands,
OperandVector &FinalOperands);
- std::unique_ptr<X86Operand> ParseOperand(StringRef Mnemonic);
- std::unique_ptr<X86Operand> ParseATTOperand(StringRef Mnemonic);
+ std::unique_ptr<X86Operand> ParseOperand();
+ std::unique_ptr<X86Operand> ParseATTOperand();
std::unique_ptr<X86Operand> ParseIntelOperand();
std::unique_ptr<X86Operand> ParseIntelOffsetOfOperator();
bool ParseIntelDotOperator(IntelExprStateMachine &SM, SMLoc &End);
@@ -835,8 +835,7 @@ private:
InlineAsmIdentifierInfo &Info,
bool IsUnevaluatedOperand, SMLoc &End);
- std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc,
- StringRef Mnemonic);
+ std::unique_ptr<X86Operand> ParseMemOperand(unsigned SegReg, SMLoc StartLoc);
bool ParseIntelMemoryOperandSize(unsigned &Size);
std::unique_ptr<X86Operand>
@@ -1011,7 +1010,8 @@ static bool CheckBaseRegAndIndexRegAndScale(unsigned BaseReg, unsigned IndexReg,
// 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))) {
+ BaseReg != X86::SI && BaseReg != X86::DI)) &&
+ BaseReg != X86::DX) {
ErrMsg = "invalid 16-bit base register";
return true;
}
@@ -1332,10 +1332,10 @@ bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
return false;
}
-std::unique_ptr<X86Operand> X86AsmParser::ParseOperand(StringRef Mnemonic) {
+std::unique_ptr<X86Operand> X86AsmParser::ParseOperand() {
if (isParsingIntelSyntax())
return ParseIntelOperand();
- return ParseATTOperand(Mnemonic);
+ return ParseATTOperand();
}
std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
@@ -1932,12 +1932,12 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseIntelOperand() {
BaseReg, IndexReg, Scale, Start, End, Size);
}
-std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand(StringRef Mnemonic) {
+std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand() {
MCAsmParser &Parser = getParser();
switch (getLexer().getKind()) {
default:
// Parse a memory operand with no segment register.
- return ParseMemOperand(0, Parser.getTok().getLoc(), Mnemonic);
+ return ParseMemOperand(0, Parser.getTok().getLoc());
case AsmToken::Percent: {
// Read the register.
unsigned RegNo;
@@ -1963,7 +1963,7 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseATTOperand(StringRef Mnemonic) {
return ErrorOperand(Start, "invalid segment register");
getParser().Lex(); // Eat the colon.
- return ParseMemOperand(RegNo, Start, Mnemonic);
+ return ParseMemOperand(RegNo, Start);
}
case AsmToken::Dollar: {
// $42 -> immediate.
@@ -2089,8 +2089,7 @@ bool X86AsmParser::HandleAVX512Operand(OperandVector &Operands,
/// 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,
- StringRef Mnemonic) {
+ SMLoc MemStart) {
MCAsmParser &Parser = getParser();
// We have to disambiguate a parenthesized expression "(4+5)" from the start
@@ -2245,16 +2244,8 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
// 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);
+ cast<MCConstantExpr>(Disp)->getValue() == 0)
+ return X86Operand::CreateDXReg(BaseLoc, BaseLoc);
StringRef ErrMsg;
if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(),
@@ -2517,7 +2508,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
// Read the operands.
while(1) {
- if (std::unique_ptr<X86Operand> Op = ParseOperand(Name)) {
+ if (std::unique_ptr<X86Operand> Op = ParseOperand()) {
Operands.push_back(std::move(Op));
if (HandleAVX512Operand(Operands, *Operands.back()))
return true;
@@ -2587,6 +2578,27 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
}
}
+ // 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.isDXReg())
+ Operands.back() = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
+ Op.getEndLoc());
+ }
+ // 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.isDXReg())
+ Operands[1] = X86Operand::CreateReg(X86::DX, Op.getStartLoc(),
+ Op.getEndLoc());
+ }
+
SmallVector<std::unique_ptr<MCParsedAsmOperand>, 2> TmpOperands;
bool HadVerifyError = false;
OpenPOWER on IntegriCloud