1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 19:23:23 +01:00

[X86] Merge disp8 and cdisp8 handling into a single helper function to reduce some code.

We currently handle EVEX and non-EVEX separately in two places. By sinking the EVEX
check into the existing helper for CDisp8 we can simplify these two places.

Differential Revision: https://reviews.llvm.org/D84730
This commit is contained in:
Craig Topper 2020-07-28 09:53:42 -07:00
parent 86c994e4c4
commit 54651fb7c2

View File

@ -113,33 +113,28 @@ static void emitConstant(uint64_t Val, unsigned Size, raw_ostream &OS) {
}
}
/// \returns true if this signed displacement fits in a 8-bit sign-extended
/// field.
static bool isDisp8(int Value) { return Value == (int8_t)Value; }
/// Determine if this immediate can fit in a disp8 or a compressed disp8 for
/// EVEX instructions. \p will be set to the value to pass to the ImmOffset
/// parameter of emitImmediate.
static bool isDispOrCDisp8(uint64_t TSFlags, int Value, int &ImmOffset) {
bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
/// \returns true if this signed displacement fits in a 8-bit compressed
/// dispacement field.
static bool isCDisp8(uint64_t TSFlags, int Value, int &CValue) {
assert(((TSFlags & X86II::EncodingMask) == X86II::EVEX) &&
"Compressed 8-bit displacement is only valid for EVEX inst.");
unsigned CD8_Scale =
int CD8_Scale =
(TSFlags & X86II::CD8_Scale_Mask) >> X86II::CD8_Scale_Shift;
if (CD8_Scale == 0) {
CValue = Value;
return isDisp8(Value);
}
if (!HasEVEX || CD8_Scale == 0)
return isInt<8>(Value);
unsigned Mask = CD8_Scale - 1;
assert((CD8_Scale & Mask) == 0 && "Invalid memory object size.");
if (Value & Mask) // Unaligned offset
assert(isPowerOf2_32(CD8_Scale) && "Unexpected CD8 scale!");
if (Value & (CD8_Scale - 1)) // Unaligned offset
return false;
Value /= (int)CD8_Scale;
bool Ret = (Value == (int8_t)Value);
if (Ret)
CValue = Value;
return Ret;
int CDisp8 = Value / CD8_Scale;
if (!isInt<8>(CDisp8))
return false;
// ImmOffset will be added to Value in emitImmediate leaving just CDisp8.
ImmOffset = CDisp8 - Value;
return true;
}
/// \returns the appropriate fixup kind to use for an immediate in an
@ -393,7 +388,6 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
const MCOperand &Scale = MI.getOperand(Op + X86::AddrScaleAmt);
const MCOperand &IndexReg = MI.getOperand(Op + X86::AddrIndexReg);
unsigned BaseReg = Base.getReg();
bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
// Handle %rip relative addressing.
if (BaseReg == X86::RIP ||
@ -487,7 +481,7 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
}
if (Disp.isImm() && isDisp8(Disp.getImm())) {
if (Disp.isImm() && isInt<8>(Disp.getImm())) {
if (Disp.getImm() == 0 && RMfield != 6) {
// There is no displacement; just the register.
emitByte(modRMByte(0, RegOpcodeField, RMfield), OS);
@ -557,18 +551,11 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
// Otherwise, if the displacement fits in a byte, encode as [REG+disp8].
if (Disp.isImm()) {
if (!HasEVEX && isDisp8(Disp.getImm())) {
emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), OS);
emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups);
return;
}
// Try EVEX compressed 8-bit displacement first; if failed, fall back to
// 32-bit displacement.
int CDisp8 = 0;
if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) {
int ImmOffset = 0;
if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
emitByte(modRMByte(1, RegOpcodeField, BaseRegNo), OS);
emitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, StartByte, OS, Fixups,
CDisp8 - Disp.getImm());
ImmOffset);
return;
}
}
@ -589,7 +576,6 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
bool ForceDisp32 = false;
bool ForceDisp8 = false;
int CDisp8 = 0;
int ImmOffset = 0;
if (BaseReg == 0) {
// If there is no base register, we emit the special case SIB byte with
@ -606,15 +592,10 @@ void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
BaseRegNo != N86::EBP) {
// Emit no displacement ModR/M byte
emitByte(modRMByte(0, RegOpcodeField, 4), OS);
} else if (!HasEVEX && isDisp8(Disp.getImm())) {
} else if (isDispOrCDisp8(TSFlags, Disp.getImm(), ImmOffset)) {
// Emit the disp8 encoding.
emitByte(modRMByte(1, RegOpcodeField, 4), OS);
ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
} else if (HasEVEX && isCDisp8(TSFlags, Disp.getImm(), CDisp8)) {
// Emit the disp8 encoding.
emitByte(modRMByte(1, RegOpcodeField, 4), OS);
ForceDisp8 = true; // Make sure to force 8 bit disp if Base=EBP
ImmOffset = CDisp8 - Disp.getImm();
} else {
// Emit the normal disp32 encoding.
emitByte(modRMByte(2, RegOpcodeField, 4), OS);