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);
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>
// 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;
}
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(
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;
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.
/// 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
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)) {
// 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;
}
}
- // 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;