Index: lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- lib/Target/X86/AsmParser/X86AsmParser.cpp +++ lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -2763,6 +2763,7 @@ assert(Op.isToken() && "Leading operand should always be a mnemonic!"); StringRef Mnemonic = Op.getToken(); SMRange EmptyRange = None; + StringRef Base = Op.getToken(); // First, handle aliases that expand to multiple instructions. MatchFPUWaitAlias(IDLoc, Op, Operands, Out, MatchingInlineAsm); @@ -2789,11 +2790,37 @@ } } + SmallVector Match; + uint64_t ErrorInfoMissingFeature = 0; + + // If unsized push has immediate operand we should default the default pointer + // size for the size. + if (Mnemonic == "push" && Operands.size() == 2) { + auto *X86Op = static_cast(Operands[1].get()); + if (X86Op->isImm()) { + // If it's not a constant fall through and let remainder take care of it. + const auto *CE = dyn_cast(X86Op->getImm()); + unsigned Size = getPointerWidth(); + if (CE && + (isIntN(Size, CE->getValue()) || isUIntN(Size, CE->getValue()))) { + SmallString<16> Tmp; + Tmp += Base; + Tmp += (is64BitMode()) + ? "q" + : (is32BitMode()) ? "l" : (is16BitMode()) ? "w" : " "; + Op.setTokenValue(Tmp); + // Do match in ATT mode to allow explicit suffix usage. + Match.push_back(MatchInstruction(Operands, Inst, ErrorInfo, + MatchingInlineAsm, + false /*isParsingIntelSyntax()*/)); + Op.setTokenValue(Base); + } + } + } + // If an unsized memory operand is present, try to match with each memory // operand size. In Intel assembly, the size is not part of the instruction // mnemonic. - SmallVector Match; - uint64_t ErrorInfoMissingFeature = 0; if (UnsizedMemOp && UnsizedMemOp->isMemUnsized()) { static const unsigned MopSizes[] = {8, 16, 32, 64, 80, 128, 256, 512}; for (unsigned Size : MopSizes) { Index: test/MC/X86/pr22028.s =================================================================== --- /dev/null +++ test/MC/X86/pr22028.s @@ -0,0 +1,23 @@ +// RUN: llvm-mc -triple i386-unknown-unknown-code16 -show-encoding %s | FileCheck --check-prefix=CHECK16 %s +// RUN: llvm-mc -triple i386-unknown-unknown -show-encoding %s | FileCheck --check-prefix=CHECK %s +// RUN: llvm-mc -triple i686-unknown-unknown -show-encoding %s | FileCheck --check-prefix=CHECK %s + +.intel_syntax + +push 0 +push -1 +push 30 +push 257 +push 65536 + +//CHECK16: pushw $0 # encoding: [0x6a,0x00] +//CHECK16: pushw $-1 # encoding: [0x6a,0xff] +//CHECK16: pushw $30 # encoding: [0x6a,0x1e] +//CHECK16: pushw $257 # encoding: [0x68,0x01,0x01] +//CHECK16: pushl $65536 # encoding: [0x66,0x68,0x00,0x00,0x01,0x00] + +//CHECK: pushl $0 # encoding: [0x6a,0x00] +//CHECK: pushl $-1 # encoding: [0x6a,0xff] +//CHECK: pushl $30 # encoding: [0x6a,0x1e] +//CHECK: pushl $257 # encoding: [0x68,0x01,0x01,0x00,0x00] +//CHECK: pushl $65536 # encoding: [0x68,0x00,0x00,0x01,0x00]