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:
parent
86c994e4c4
commit
54651fb7c2
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user