diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp index 989c2976..e0601794 100644 --- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -69,6 +69,7 @@ class X86AsmParser : public MCTargetAsmParser { // PUSH i8 --> PUSH32i8 // PUSH word i8 --> PUSH16i8 bool push32; + bool push16; SMLoc consumeToken() { MCAsmParser &Parser = getParser(); SMLoc Result = Parser.getTok().getLoc(); @@ -2031,10 +2032,12 @@ std::unique_ptr X86AsmParser::ParseIntelOperand(std::string Mnem, un Start, End, 0); } - // dirty hacky way to deal with PUSH 0xd/PUSH word 0xd + // dirty hacky way to deal with PUSH 0xd/PUSH word 0xd/PUSH word 0x1122 if (Mnem == "push") { if (Size == 0) push32 = true; + if (Size == 16) + push16 = true; } const MCExpr *ImmExpr = MCConstantExpr::create(Imm, getContext()); @@ -2609,6 +2612,7 @@ bool X86AsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name, Name == "rex64" || Name == "data16"; push32 = false; + push16 = false; // This does the actual operand parsing. Don't parse any more if we have a // prefix juxtaposed with an operation like "lock incl 4(%rax)", because we @@ -3216,8 +3220,15 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode, ErrorInfoMissingFeature = ErrorInfo; } + if (push32 && Inst.getOpcode() == X86::PUSH16i8) Inst.setOpcode(X86::PUSH32i8); + + if (push16 && (Inst.getOpcode() == X86::PUSH64i8)) + Inst.setOpcode(X86::PUSH16i8); + + if (push16 && (Inst.getOpcode() == X86::PUSH64i32 || Inst.getOpcode() == X86::PUSHi32) ) + Inst.setOpcode(X86::PUSHi16); // Restore the size of the unsized memory operand if we modified it. if (UnsizedMemOp)