}
}
-/// \returns true if this signed displacement fits in a 8-bit sign-extended
-/// field.
-static bool isDisp8(int Value) { return Value == (int8_t)Value; }
-
-/// \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.");
+/// 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;
- 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
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 ||
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);
// 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;
}
}
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
BaseRegNo != N86::EBP) {
// Emit no displacement ModR/M byte
emitByte(modRMByte(0, RegOpcodeField, 4), OS);
- } else if (!HasEVEX && isDisp8(Disp.getImm())) {
- // 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)) {
+ } 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
- ImmOffset = CDisp8 - Disp.getImm();
} else {
// Emit the normal disp32 encoding.
emitByte(modRMByte(2, RegOpcodeField, 4), OS);