Index: llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp =================================================================== --- llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -3548,6 +3548,12 @@ if (ForcedVEXEncoding == VEXEncoding_VEX3) Prefixes |= X86::IP_USE_VEX3; + // Set encoded flags for {disp8} and {disp32}. + if (ForcedDispEncoding == DispEncoding_Disp8) + Prefixes |= X86::IP_USE_DISP8; + else if (ForcedDispEncoding == DispEncoding_Disp32) + Prefixes |= X86::IP_USE_DISP32; + if (Prefixes) Inst.setFlags(Prefixes); @@ -3782,6 +3788,12 @@ if (ForcedVEXEncoding == VEXEncoding_VEX3) Prefixes |= X86::IP_USE_VEX3; + // Set encoded flags for {disp8} and {disp32}. + if (ForcedDispEncoding == DispEncoding_Disp8) + Prefixes |= X86::IP_USE_DISP8; + else if (ForcedDispEncoding == DispEncoding_Disp32) + Prefixes |= X86::IP_USE_DISP32; + if (Prefixes) Inst.setFlags(Prefixes); Index: llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -62,6 +62,8 @@ IP_HAS_LOCK = 16, IP_HAS_NOTRACK = 32, IP_USE_VEX3 = 64, + IP_USE_DISP8 = 128, + IP_USE_DISP32 = 256, }; enum OperandType : unsigned { Index: llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp =================================================================== --- llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp +++ llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp @@ -505,6 +505,9 @@ return; } + bool UseDisp8 = MI.getFlags() & X86::IP_USE_DISP8; + bool UseDisp32 = MI.getFlags() & X86::IP_USE_DISP32; + // Determine whether a SIB byte is needed. // If no BaseReg, issue a RIP relative instruction only if the MCE can // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table @@ -531,7 +534,7 @@ // encoding for [EBP] with no displacement means [disp32] so we handle it // by emitting a displacement of 0 below. if (BaseRegNo != N86::EBP) { - if (Disp.isImm() && Disp.getImm() == 0) { + if (Disp.isImm() && Disp.getImm() == 0 && !UseDisp8 && !UseDisp32) { emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), OS); return; } @@ -552,7 +555,7 @@ // Otherwise, if the displacement fits in a byte, encode as [REG+disp8]. if (Disp.isImm()) { int ImmOffset = 0; - if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) { + if (!UseDisp32 && isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) { emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), OS); emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups, ImmOffset); @@ -582,13 +585,13 @@ // MOD=0, BASE=5, to JUST get the index, scale, and displacement. emitByte(modRMByte(0, RegOpcodeField, 4), OS); ForceDisp32 = true; - } else if (Disp.isImm() && Disp.getImm() == 0 && + } else if (Disp.isImm() && Disp.getImm() == 0 && !UseDisp8 && !UseDisp32 && // Base reg can't be anything that ends up with '5' as the base // reg, it is the magic [*] nomenclature that indicates no base. BaseRegNo != N86::EBP) { // Emit no displacement ModR/M byte emitByte(modRMByte(0, RegOpcodeField, 4), OS); - } else if (Disp.isImm() && + } else if (Disp.isImm() && !UseDisp32 && isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) { // Emit the disp8 encoding. emitByte(modRMByte(1, RegOpcodeField, 4), OS); Index: llvm/test/MC/X86/x86-64.s =================================================================== --- llvm/test/MC/X86/x86-64.s +++ llvm/test/MC/X86/x86-64.s @@ -1900,3 +1900,91 @@ // CHECK: ud1q (%rbx), %rcx // CHECK: encoding: [0x48,0x0f,0xb9,0x0b] ud2b (%rbx), %rcx + +// Requires no displacement by default +// CHECK: movl $1, (%rax) +// CHECK: encoding: [0xc7,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rax) +// CHECK: encoding: [0xc7,0x40,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rax) +// CHECK: encoding: [0xc7,0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, (%rax) +{disp8} movl $1, (%rax) +{disp32} movl $1, (%rax) + +// Requires disp8 by default +// CHECK: movl $1, (%rbp) +// CHECK: encoding: [0xc7,0x45,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rbp) +// CHECK: encoding: [0xc7,0x45,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rbp) +// CHECK: encoding: [0xc7,0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, (%rbp) +{disp8} movl $1, (%rbp) +{disp32} movl $1, (%rbp) + +// Requires disp8 by default +// CHECK: movl $1, (%r13) +// CHECK: encoding: [0x41,0xc7,0x45,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%r13) +// CHECK: encoding: [0x41,0xc7,0x45,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%r13) +// CHECK: encoding: [0x41,0xc7,0x85,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, (%r13) +{disp8} movl $1, (%r13) +{disp32} movl $1, (%r13) + +// Requires disp8 by default +// CHECK: movl $1, 8(%rax) +// CHECK: encoding: [0xc7,0x40,0x08,0x01,0x00,0x00,0x00] +// CHECK: movl $1, 8(%rax) +// CHECK: encoding: [0xc7,0x40,0x08,0x01,0x00,0x00,0x00] +// CHECK: movl $1, 8(%rax) +// CHECK: encoding: [0xc7,0x80,0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, 8(%rax) +{disp8} movl $1, 8(%rax) +{disp32} movl $1, 8(%rax) + +// Requires no displacement by default +// CHECK: movl $1, (%rax,%rbx,4) +// CHECK: encoding: [0xc7,0x04,0x98,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rax,%rbx,4) +// CHECK: encoding: [0xc7,0x44,0x98,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rax,%rbx,4) +// CHECK: encoding: [0xc7,0x84,0x98,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, (%rax,%rbx,4) +{disp8} movl $1, (%rax,%rbx,4) +{disp32} movl $1, (%rax,%rbx,4) + +// Requires disp8 by default. +// CHECK: movl $1, 8(%rax,%rbx,4) +// CHECK: encoding: [0xc7,0x44,0x98,0x08,0x01,0x00,0x00,0x00] +// CHECK: movl $1, 8(%rax,%rbx,4) +// CHECK: encoding: [0xc7,0x44,0x98,0x08,0x01,0x00,0x00,0x00] +// CHECK: movl $1, 8(%rax,%rbx,4) +// CHECK: encoding: [0xc7,0x84,0x98,0x08,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, 8(%rax,%rbx,4) +{disp8} movl $1, 8(%rax,%rbx,4) +{disp32} movl $1, 8(%rax,%rbx,4) + +// Requires disp8 by default. +// CHECK: movl $1, (%rbp,%rbx,4) +// CHECK: encoding: [0xc7,0x44,0x9d,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rbp,%rbx,4) +// CHECK: encoding: [0xc7,0x44,0x9d,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%rbp,%rbx,4) +// CHECK: encoding: [0xc7,0x84,0x9d,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, (%rbp,%rbx,4) +{disp8} movl $1, (%rbp,%rbx,4) +{disp32} movl $1, (%rbp,%rbx,4) + +// Requires disp8 by default. +// CHECK: movl $1, (%r13,%rbx,4) +// CHECK: encoding: [0x41,0xc7,0x44,0x9d,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%r13,%rbx,4) +// CHECK: encoding: [0x41,0xc7,0x44,0x9d,0x00,0x01,0x00,0x00,0x00] +// CHECK: movl $1, (%r13,%rbx,4) +// CHECK: encoding: [0x41,0xc7,0x84,0x9d,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00] +movl $1, (%r13,%rbx,4) +{disp8} movl $1, (%r13,%rbx,4) +{disp32} movl $1, (%r13,%rbx,4)