mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[X86] Add assembler support for {disp8} and {disp32} to control the size of displacement used for memory operands.
These prefixes should override the default behavior and force a larger immediate size. I don't believe gas issues any warning if you use {disp8} when a 32-bit displacement is already required. And this patch doesn't either. This completes the {disp8} and {disp32} support from PR46650. Reviewed By: RKSimon Differential Revision: https://reviews.llvm.org/D84793
This commit is contained in:
parent
183d6fbbe7
commit
ad26adfc58
@ -3572,6 +3572,12 @@ bool X86AsmParser::MatchAndEmitATTInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
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);
|
||||
|
||||
@ -3806,6 +3812,12 @@ bool X86AsmParser::MatchAndEmitIntelInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
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);
|
||||
|
||||
|
@ -62,6 +62,8 @@ namespace X86 {
|
||||
IP_HAS_LOCK = 16,
|
||||
IP_HAS_NOTRACK = 32,
|
||||
IP_USE_VEX3 = 64,
|
||||
IP_USE_DISP8 = 128,
|
||||
IP_USE_DISP32 = 256,
|
||||
};
|
||||
|
||||
enum OperandType : unsigned {
|
||||
|
@ -505,12 +505,18 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
return;
|
||||
}
|
||||
|
||||
// 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
|
||||
// 2-7) and absolute references.
|
||||
// Check for presence of {disp8} or {disp32} pseudo prefixes.
|
||||
bool UseDisp8 = MI.getFlags() & X86::IP_USE_DISP8;
|
||||
bool UseDisp32 = MI.getFlags() & X86::IP_USE_DISP32;
|
||||
|
||||
if ( // The SIB byte must be used if there is an index register.
|
||||
// We only allow no displacement if no pseudo prefix is present.
|
||||
bool AllowNoDisp = !UseDisp8 && !UseDisp32;
|
||||
// Disp8 is allowed unless the {disp32} prefix is present.
|
||||
bool AllowDisp8 = !UseDisp32;
|
||||
|
||||
// Determine whether a SIB byte is needed.
|
||||
if (// The SIB byte must be used if there is an index register or the
|
||||
// encoding requires a SIB byte.
|
||||
!ForceSIB && IndexReg.getReg() == 0 &&
|
||||
// The SIB byte must be used if the base is ESP/RSP/R12, all of which
|
||||
// encode to an R/M value of 4, which indicates that a SIB byte is
|
||||
@ -526,12 +532,12 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
return;
|
||||
}
|
||||
|
||||
// If the base is not EBP/ESP and there is no displacement, use simple
|
||||
// indirect register encoding, this handles addresses like [EAX]. The
|
||||
// encoding for [EBP] with no displacement means [disp32] so we handle it
|
||||
// by emitting a displacement of 0 below.
|
||||
// If the base is not EBP/ESP/R12/R13 and there is no displacement, use
|
||||
// simple indirect register encoding, this handles addresses like [EAX].
|
||||
// The encoding for [EBP] or[R13] with no displacement means [disp32] so we
|
||||
// handle it by emitting a displacement of 0 later.
|
||||
if (BaseRegNo != N86::EBP) {
|
||||
if (Disp.isImm() && Disp.getImm() == 0) {
|
||||
if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp) {
|
||||
emitByte(modRMByte(0, RegOpcodeField, BaseRegNo), OS);
|
||||
return;
|
||||
}
|
||||
@ -550,7 +556,10 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
}
|
||||
|
||||
// Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
|
||||
if (Disp.isImm()) {
|
||||
// Including a compressed disp8 for EVEX instructions that support it.
|
||||
// This also handles the 0 displacement for [EBP] or [R13]. We can't use
|
||||
// disp8 if the {disp32} pseudo prefix is present.
|
||||
if (Disp.isImm() && AllowDisp8) {
|
||||
int ImmOffset = 0;
|
||||
if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
|
||||
emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), OS);
|
||||
@ -560,7 +569,9 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, emit the most general non-SIB encoding: [REG+disp32]
|
||||
// Otherwise, emit the most general non-SIB encoding: [REG+disp32].
|
||||
// Displacement may be 0 for [EBP] or [R13] case if {disp32} pseudo prefix
|
||||
// prevented using disp8 above.
|
||||
emitByte(modRMByte(2, RegOpcodeField, BaseRegNo), OS);
|
||||
unsigned Opcode = MI.getOpcode();
|
||||
unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax
|
||||
@ -580,21 +591,26 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
if (BaseReg == 0) {
|
||||
// If there is no base register, we emit the special case SIB byte with
|
||||
// MOD=0, BASE=5, to JUST get the index, scale, and displacement.
|
||||
BaseRegNo = 5;
|
||||
emitByte(modRMByte(0, RegOpcodeField, 4), OS);
|
||||
ForceDisp32 = true;
|
||||
} else if (Disp.isImm() && Disp.getImm() == 0 &&
|
||||
// Base reg can't be anything that ends up with '5' as the base
|
||||
// reg, it is the magic [*] nomenclature that indicates no base.
|
||||
} else if (Disp.isImm() && Disp.getImm() == 0 && AllowNoDisp &&
|
||||
// Base reg can't be EBP/RBP/R13 as that would end up with '5' as
|
||||
// the base field, but that is the magic [*] nomenclature that
|
||||
// indicates no base when mod=0. For these cases we'll emit a 0
|
||||
// displacement instead.
|
||||
BaseRegNo != N86::EBP) {
|
||||
// Emit no displacement ModR/M byte
|
||||
emitByte(modRMByte(0, RegOpcodeField, 4), OS);
|
||||
} else if (Disp.isImm() &&
|
||||
} else if (Disp.isImm() && AllowDisp8 &&
|
||||
isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
|
||||
// Emit the disp8 encoding.
|
||||
// Displacement fits in a byte or matches an EVEX compressed disp8, use
|
||||
// disp8 encoding. This also handles EBP/R13 base with 0 displacement unless
|
||||
// {disp32} pseudo prefix was used.
|
||||
emitByte(modRMByte(1, RegOpcodeField, 4), OS);
|
||||
ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
|
||||
ForceDisp8 = true;
|
||||
} else {
|
||||
// Emit the normal disp32 encoding.
|
||||
// Otherwise, emit the normal disp32 encoding.
|
||||
emitByte(modRMByte(2, RegOpcodeField, 4), OS);
|
||||
ForceDisp32 = true;
|
||||
}
|
||||
@ -605,11 +621,6 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
|
||||
|
||||
unsigned IndexRegNo = IndexReg.getReg() ? getX86RegNum(IndexReg) : 4;
|
||||
|
||||
// Handle the SIB byte for the case where there is no base, see Intel
|
||||
// Manual 2A, table 2-7. The displacement has already been output.
|
||||
if (BaseReg == 0)
|
||||
BaseRegNo = 5;
|
||||
|
||||
emitSIBByte(SS, IndexRegNo, BaseRegNo, OS);
|
||||
|
||||
// Do we need to output a displacement?
|
||||
|
@ -1904,3 +1904,91 @@ ud1 %rdx, %rdi
|
||||
// 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)
|
||||
|
Loading…
Reference in New Issue
Block a user