From: Nirav Dave Date: Fri, 4 Jan 2019 17:11:15 +0000 (+0000) Subject: Undo r350355 "[X86] Remove terrible DX Register parsing hack in parse operand. NFCI." X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a1e0885134740b6e66af024c062345d5a04fde3e;p=llvm Undo r350355 "[X86] Remove terrible DX Register parsing hack in parse operand. NFCI." Add missing test case and update comments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350406 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 214fd547471..4801078925c 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2240,6 +2240,14 @@ std::unique_ptr X86AsmParser::ParseMemOperand(unsigned SegReg, 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(Disp) && + cast(Disp)->getValue() == 0) + return X86Operand::CreateDXReg(BaseLoc, BaseLoc); + StringRef ErrMsg; if (CheckBaseRegAndIndexRegAndScale(BaseReg, IndexReg, Scale, is64BitMode(), ErrMsg)) { diff --git a/lib/Target/X86/AsmParser/X86Operand.h b/lib/Target/X86/AsmParser/X86Operand.h index ef5f17dd6fd..4d4aae0a1c6 100644 --- a/lib/Target/X86/AsmParser/X86Operand.h +++ b/lib/Target/X86/AsmParser/X86Operand.h @@ -30,7 +30,7 @@ namespace llvm { /// X86Operand - Instances of this class represent a parsed X86 machine /// instruction. struct X86Operand final : public MCParsedAsmOperand { - enum KindTy { Token, Register, Immediate, Memory, Prefix } Kind; + enum KindTy { Token, Register, Immediate, Memory, Prefix, DXRegister } Kind; SMLoc StartLoc, EndLoc; SMLoc OffsetOfLoc; @@ -118,6 +118,9 @@ struct X86Operand final : public MCParsedAsmOperand { case Register: OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo); break; + case DXRegister: + OS << "DXReg"; + break; case Immediate: PrintImmValue(Imm.Val, "Imm:"); break; @@ -441,10 +444,7 @@ struct X86Operand final : public MCParsedAsmOperand { bool isPrefix() const { return Kind == Prefix; } bool isReg() const override { return Kind == Register; } - bool isDXReg() const { - return Kind == Memory && getMemBaseReg() == X86::DX && !getMemIndexReg() && - getMemScale() == 1; - } + bool isDXReg() const { return Kind == DXRegister; } bool isGR32orGR64() const { return Kind == Register && @@ -543,6 +543,11 @@ struct X86Operand final : public MCParsedAsmOperand { return Res; } + static std::unique_ptr + CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) { + return llvm::make_unique(DXRegister, StartLoc, EndLoc); + } + static std::unique_ptr CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) { auto Res = llvm::make_unique(Prefix, StartLoc, EndLoc);