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);
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>
// 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;
}
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(
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;
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.
/// 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
// 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(),
// 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;
}
}
+ // 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;
/// 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;
case Register:
OS << "Reg:" << X86IntelInstPrinter::getRegisterName(Reg.RegNo);
break;
+ case DXRegister:
+ OS << "DXReg";
+ break;
case Immediate:
PrintImmValue(Imm.Val, "Imm:");
break;
bool isPrefix() const { return Kind == Prefix; }
bool isReg() const override { return Kind == Register; }
+ bool isDXReg() const { return Kind == DXRegister; }
bool isGR32orGR64() const {
return Kind == Register &&
}
static std::unique_ptr<X86Operand>
+ CreateDXReg(SMLoc StartLoc, SMLoc EndLoc) {
+ return llvm::make_unique<X86Operand>(DXRegister, StartLoc, EndLoc);
+ }
+
+ static std::unique_ptr<X86Operand>
CreatePrefix(unsigned Prefixes, SMLoc StartLoc, SMLoc EndLoc) {
auto Res = llvm::make_unique<X86Operand>(Prefix, StartLoc, EndLoc);
Res->Pref.Prefixes = Prefixes;