aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp')
-rw-r--r--lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp618
1 files changed, 280 insertions, 338 deletions
diff --git a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
index dfab6ec10775..96c2e81c332a 100644
--- a/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
+++ b/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
@@ -76,36 +76,16 @@ public:
return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg()) & 0x7;
}
- // On regular x86, both XMM0-XMM7 and XMM8-XMM15 are encoded in the range
- // 0-7 and the difference between the 2 groups is given by the REX prefix.
- // In the VEX prefix, registers are seen sequencially from 0-15 and encoded
- // in 1's complement form, example:
- //
- // ModRM field => XMM9 => 1
- // VEX.VVVV => XMM9 => ~9
- //
- // See table 4-35 of Intel AVX Programming Reference for details.
- unsigned char getVEXRegisterEncoding(const MCInst &MI,
- unsigned OpNum) const {
- unsigned SrcReg = MI.getOperand(OpNum).getReg();
- unsigned SrcRegNum = GetX86RegNum(MI.getOperand(OpNum));
- if (X86II::isX86_64ExtendedReg(SrcReg))
- SrcRegNum |= 8;
-
- // The registers represented through VEX_VVVV should
- // be encoded in 1's complement form.
- return (~SrcRegNum) & 0xf;
+ unsigned getX86RegEncoding(const MCInst &MI, unsigned OpNum) const {
+ return Ctx.getRegisterInfo()->getEncodingValue(
+ MI.getOperand(OpNum).getReg());
}
- unsigned char getWriteMaskRegisterEncoding(const MCInst &MI,
- unsigned OpNum) const {
- assert(X86::K0 != MI.getOperand(OpNum).getReg() &&
- "Invalid mask register as write-mask!");
- unsigned MaskRegNum = GetX86RegNum(MI.getOperand(OpNum));
- return MaskRegNum;
+ bool isX86_64ExtendedReg(const MCInst &MI, unsigned OpNum) const {
+ return (getX86RegEncoding(MI, OpNum) >> 3) & 1;
}
- void EmitByte(unsigned char C, unsigned &CurByte, raw_ostream &OS) const {
+ void EmitByte(uint8_t C, unsigned &CurByte, raw_ostream &OS) const {
OS << (char)C;
++CurByte;
}
@@ -125,8 +105,8 @@ public:
SmallVectorImpl<MCFixup> &Fixups,
int ImmOffset = 0) const;
- inline static unsigned char ModRMByte(unsigned Mod, unsigned RegOpcode,
- unsigned RM) {
+ inline static uint8_t ModRMByte(unsigned Mod, unsigned RegOpcode,
+ unsigned RM) {
assert(Mod < 4 && RegOpcode < 8 && RM < 8 && "ModRM Fields out of range!");
return RM | (RegOpcode << 3) | (Mod << 6);
}
@@ -142,11 +122,9 @@ public:
EmitByte(ModRMByte(SS, Index, Base), CurByte, OS);
}
-
- void EmitMemModRMByte(const MCInst &MI, unsigned Op,
- unsigned RegOpcodeField,
- uint64_t TSFlags, unsigned &CurByte, raw_ostream &OS,
- SmallVectorImpl<MCFixup> &Fixups,
+ void emitMemModRMByte(const MCInst &MI, unsigned Op, unsigned RegOpcodeField,
+ uint64_t TSFlags, bool Rex, unsigned &CurByte,
+ raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI) const;
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
@@ -160,10 +138,12 @@ public:
void EmitSegmentOverridePrefix(unsigned &CurByte, unsigned SegOperand,
const MCInst &MI, raw_ostream &OS) const;
- void EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
+ bool emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte, int MemOperand,
const MCInst &MI, const MCInstrDesc &Desc,
- const MCSubtargetInfo &STI,
- raw_ostream &OS) const;
+ const MCSubtargetInfo &STI, raw_ostream &OS) const;
+
+ uint8_t DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
+ int MemOperand, const MCInstrDesc &Desc) const;
};
} // end anonymous namespace
@@ -177,7 +157,7 @@ MCCodeEmitter *llvm::createX86MCCodeEmitter(const MCInstrInfo &MCII,
/// isDisp8 - Return true if this signed displacement fits in a 8-bit
/// sign-extended field.
static bool isDisp8(int Value) {
- return Value == (signed char)Value;
+ return Value == (int8_t)Value;
}
/// isCDisp8 - Return true if this signed displacement fits in a 8-bit
@@ -198,7 +178,7 @@ static bool isCDisp8(uint64_t TSFlags, int Value, int& CValue) {
if (Value & Mask) // Unaligned offset
return false;
Value /= (int)CD8_Scale;
- bool Ret = (Value == (signed char)Value);
+ bool Ret = (Value == (int8_t)Value);
if (Ret)
CValue = Value;
@@ -231,6 +211,10 @@ static bool Is32BitMemOperand(const MCInst &MI, unsigned Op) {
(IndexReg.getReg() != 0 &&
X86MCRegisterClasses[X86::GR32RegClassID].contains(IndexReg.getReg())))
return true;
+ if (BaseReg.getReg() == X86::EIP) {
+ assert(IndexReg.getReg() == 0 && "Invalid eip-based address.");
+ return true;
+ }
return false;
}
@@ -343,7 +327,9 @@ EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
// the start of the field, not the end of the field.
if (FixupKind == FK_PCRel_4 ||
FixupKind == MCFixupKind(X86::reloc_riprel_4byte) ||
- FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load))
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte_movq_load) ||
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax) ||
+ FixupKind == MCFixupKind(X86::reloc_riprel_4byte_relax_rex))
ImmOffset -= 4;
if (FixupKind == FK_PCRel_2)
ImmOffset -= 2;
@@ -359,12 +345,12 @@ EmitImmediate(const MCOperand &DispOp, SMLoc Loc, unsigned Size,
EmitConstant(0, Size, CurByte, OS);
}
-void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
+void X86MCCodeEmitter::emitMemModRMByte(const MCInst &MI, unsigned Op,
unsigned RegOpcodeField,
- uint64_t TSFlags, unsigned &CurByte,
- raw_ostream &OS,
+ uint64_t TSFlags, bool Rex,
+ unsigned &CurByte, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
- const MCSubtargetInfo &STI) const{
+ const MCSubtargetInfo &STI) const {
const MCOperand &Disp = MI.getOperand(Op+X86::AddrDisp);
const MCOperand &Base = MI.getOperand(Op+X86::AddrBaseReg);
const MCOperand &Scale = MI.getOperand(Op+X86::AddrScaleAmt);
@@ -373,18 +359,38 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
bool HasEVEX = (TSFlags & X86II::EncodingMask) == X86II::EVEX;
// Handle %rip relative addressing.
- if (BaseReg == X86::RIP) { // [disp32+RIP] in X86-64 mode
+ if (BaseReg == X86::RIP ||
+ BaseReg == X86::EIP) { // [disp32+rIP] in X86-64 mode
assert(is64BitMode(STI) && "Rip-relative addressing requires 64-bit mode");
assert(IndexReg.getReg() == 0 && "Invalid rip-relative address");
EmitByte(ModRMByte(0, RegOpcodeField, 5), CurByte, OS);
- unsigned FixupKind = X86::reloc_riprel_4byte;
-
+ unsigned Opcode = MI.getOpcode();
// movq loads are handled with a special relocation form which allows the
// linker to eliminate some loads for GOT references which end up in the
// same linkage unit.
- if (MI.getOpcode() == X86::MOV64rm)
- FixupKind = X86::reloc_riprel_4byte_movq_load;
+ unsigned FixupKind = [=]() {
+ switch (Opcode) {
+ default:
+ return X86::reloc_riprel_4byte;
+ case X86::MOV64rm:
+ assert(Rex);
+ return X86::reloc_riprel_4byte_movq_load;
+ case X86::CALL64m:
+ case X86::JMP64m:
+ case X86::TEST64rm:
+ case X86::ADC64rm:
+ case X86::ADD64rm:
+ case X86::AND64rm:
+ case X86::CMP64rm:
+ case X86::OR64rm:
+ case X86::SBB64rm:
+ case X86::SUB64rm:
+ case X86::XOR64rm:
+ return Rex ? X86::reloc_riprel_4byte_relax_rex
+ : X86::reloc_riprel_4byte_relax;
+ }
+ }();
// rip-relative addressing is actually relative to the *next* instruction.
// Since an immediate can follow the mod/rm byte for an instruction, this
@@ -510,8 +516,11 @@ void X86MCCodeEmitter::EmitMemModRMByte(const MCInst &MI, unsigned Op,
// Otherwise, emit the most general non-SIB encoding: [REG+disp32]
EmitByte(ModRMByte(2, RegOpcodeField, BaseRegNo), CurByte, OS);
- EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(X86::reloc_signed_4byte),
- CurByte, OS, Fixups);
+ unsigned Opcode = MI.getOpcode();
+ unsigned FixupKind = Opcode == X86::MOV32rm ? X86::reloc_signed_4byte_relax
+ : X86::reloc_signed_4byte;
+ EmitImmediate(Disp, MI.getLoc(), 4, MCFixupKind(FixupKind), CurByte, OS,
+ Fixups);
return;
}
@@ -603,26 +612,26 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// 1: Same as REX_R=0 (must be 1 in 32-bit mode)
// 0: Same as REX_R=1 (64 bit mode only)
//
- unsigned char VEX_R = 0x1;
- unsigned char EVEX_R2 = 0x1;
+ uint8_t VEX_R = 0x1;
+ uint8_t EVEX_R2 = 0x1;
// VEX_X: equivalent to REX.X, only used when a
// register is used for index in SIB Byte.
//
// 1: Same as REX.X=0 (must be 1 in 32-bit mode)
// 0: Same as REX.X=1 (64-bit mode only)
- unsigned char VEX_X = 0x1;
+ uint8_t VEX_X = 0x1;
// VEX_B:
//
// 1: Same as REX_B=0 (ignored in 32-bit mode)
// 0: Same as REX_B=1 (64 bit mode only)
//
- unsigned char VEX_B = 0x1;
+ uint8_t VEX_B = 0x1;
// VEX_W: opcode specific (use like REX.W, or used for
// opcode extension, or ignored, depending on the opcode byte)
- unsigned char VEX_W = 0;
+ uint8_t VEX_W = (TSFlags & X86II::VEX_W) ? 1 : 0;
// VEX_5M (VEX m-mmmmm field):
//
@@ -634,20 +643,31 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// 0b01000: XOP map select - 08h instructions with imm byte
// 0b01001: XOP map select - 09h instructions with no imm byte
// 0b01010: XOP map select - 0Ah instructions with imm dword
- unsigned char VEX_5M = 0;
+ uint8_t VEX_5M;
+ switch (TSFlags & X86II::OpMapMask) {
+ default: llvm_unreachable("Invalid prefix!");
+ case X86II::TB: VEX_5M = 0x1; break; // 0F
+ case X86II::T8: VEX_5M = 0x2; break; // 0F 38
+ case X86II::TA: VEX_5M = 0x3; break; // 0F 3A
+ case X86II::XOP8: VEX_5M = 0x8; break;
+ case X86II::XOP9: VEX_5M = 0x9; break;
+ case X86II::XOPA: VEX_5M = 0xA; break;
+ }
// VEX_4V (VEX vvvv field): a register specifier
// (in 1's complement form) or 1111 if unused.
- unsigned char VEX_4V = 0xf;
- unsigned char EVEX_V2 = 0x1;
+ uint8_t VEX_4V = 0xf;
+ uint8_t EVEX_V2 = 0x1;
- // VEX_L (Vector Length):
+ // EVEX_L2/VEX_L (Vector Length):
//
- // 0: scalar or 128-bit vector
- // 1: 256-bit vector
+ // L2 L
+ // 0 0: scalar or 128-bit vector
+ // 0 1: 256-bit vector
+ // 1 0: 512-bit vector
//
- unsigned char VEX_L = 0;
- unsigned char EVEX_L2 = 0;
+ uint8_t VEX_L = (TSFlags & X86II::VEX_L) ? 1 : 0;
+ uint8_t EVEX_L2 = (TSFlags & X86II::EVEX_L2) ? 1 : 0;
// VEX_PP: opcode extension providing equivalent
// functionality of a SIMD prefix
@@ -657,56 +677,32 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// 0b10: F3
// 0b11: F2
//
- unsigned char VEX_PP = 0;
+ uint8_t VEX_PP;
+ switch (TSFlags & X86II::OpPrefixMask) {
+ default: llvm_unreachable("Invalid op prefix!");
+ case X86II::PS: VEX_PP = 0x0; break; // none
+ case X86II::PD: VEX_PP = 0x1; break; // 66
+ case X86II::XS: VEX_PP = 0x2; break; // F3
+ case X86II::XD: VEX_PP = 0x3; break; // F2
+ }
// EVEX_U
- unsigned char EVEX_U = 1; // Always '1' so far
+ uint8_t EVEX_U = 1; // Always '1' so far
// EVEX_z
- unsigned char EVEX_z = 0;
+ uint8_t EVEX_z = (HasEVEX_K && (TSFlags & X86II::EVEX_Z)) ? 1 : 0;
// EVEX_b
- unsigned char EVEX_b = 0;
+ uint8_t EVEX_b = (TSFlags & X86II::EVEX_B) ? 1 : 0;
// EVEX_rc
- unsigned char EVEX_rc = 0;
+ uint8_t EVEX_rc = 0;
// EVEX_aaa
- unsigned char EVEX_aaa = 0;
+ uint8_t EVEX_aaa = 0;
bool EncodeRC = false;
- if (TSFlags & X86II::VEX_W)
- VEX_W = 1;
-
- if (TSFlags & X86II::VEX_L)
- VEX_L = 1;
- if (TSFlags & X86II::EVEX_L2)
- EVEX_L2 = 1;
-
- if (HasEVEX_K && (TSFlags & X86II::EVEX_Z))
- EVEX_z = 1;
-
- if ((TSFlags & X86II::EVEX_B))
- EVEX_b = 1;
-
- switch (TSFlags & X86II::OpPrefixMask) {
- default: break; // VEX_PP already correct
- case X86II::PD: VEX_PP = 0x1; break; // 66
- case X86II::XS: VEX_PP = 0x2; break; // F3
- case X86II::XD: VEX_PP = 0x3; break; // F2
- }
-
- switch (TSFlags & X86II::OpMapMask) {
- default: llvm_unreachable("Invalid prefix!");
- case X86II::TB: VEX_5M = 0x1; break; // 0F
- case X86II::T8: VEX_5M = 0x2; break; // 0F 38
- case X86II::TA: VEX_5M = 0x3; break; // 0F 3A
- case X86II::XOP8: VEX_5M = 0x8; break;
- case X86II::XOP9: VEX_5M = 0x9; break;
- case X86II::XOPA: VEX_5M = 0xA; break;
- }
-
// Classify VEX_B, VEX_4V, VEX_R, VEX_X
unsigned NumOps = Desc.getNumOperands();
unsigned CurOp = X86II::getOperandBias(Desc);
@@ -721,38 +717,30 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// MemAddr, src1(VEX_4V), src2(ModR/M)
// MemAddr, src1(ModR/M), imm8
//
- if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand +
- X86::AddrBaseReg).getReg()))
- VEX_B = 0x0;
- if (X86II::isX86_64ExtendedReg(MI.getOperand(MemOperand +
- X86::AddrIndexReg).getReg()))
- VEX_X = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(MemOperand +
- X86::AddrIndexReg).getReg()))
- EVEX_V2 = 0x0;
+ unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
+ VEX_B = ~(BaseRegEnc >> 3) & 1;
+ unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
+ VEX_X = ~(IndexRegEnc >> 3) & 1;
+ if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV.
+ EVEX_V2 = ~(IndexRegEnc >> 4) & 1;
CurOp += X86::AddrNumOperands;
if (HasEVEX_K)
- EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++);
+ EVEX_aaa = getX86RegEncoding(MI, CurOp++);
if (HasVEX_4V) {
- VEX_4V = getVEXRegisterEncoding(MI, CurOp);
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_V2 = 0x0;
- CurOp++;
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+ EVEX_V2 = ~(VRegEnc >> 4) & 1;
}
- const MCOperand &MO = MI.getOperand(CurOp);
- if (MO.isReg()) {
- if (X86II::isX86_64ExtendedReg(MO.getReg()))
- VEX_R = 0x0;
- if (X86II::is32ExtendedReg(MO.getReg()))
- EVEX_R2 = 0x0;
- }
+ unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_R = ~(RegEnc >> 3) & 1;
+ EVEX_R2 = ~(RegEnc >> 4) & 1;
break;
}
- case X86II::MRMSrcMem:
+ case X86II::MRMSrcMem: {
// MRMSrcMem instructions forms:
// src1(ModR/M), MemAddr
// src1(ModR/M), src2(VEX_4V), MemAddr
@@ -762,31 +750,25 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// FMA4:
// dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM)
// dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M),
- if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_R = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_R2 = 0x0;
- CurOp++;
+ unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_R = ~(RegEnc >> 3) & 1;
+ EVEX_R2 = ~(RegEnc >> 4) & 1;
if (HasEVEX_K)
- EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++);
+ EVEX_aaa = getX86RegEncoding(MI, CurOp++);
if (HasVEX_4V) {
- VEX_4V = getVEXRegisterEncoding(MI, CurOp);
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_V2 = 0x0;
- CurOp++;
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+ EVEX_V2 = ~(VRegEnc >> 4) & 1;
}
- if (X86II::isX86_64ExtendedReg(
- MI.getOperand(MemOperand+X86::AddrBaseReg).getReg()))
- VEX_B = 0x0;
- if (X86II::isX86_64ExtendedReg(
- MI.getOperand(MemOperand+X86::AddrIndexReg).getReg()))
- VEX_X = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(MemOperand +
- X86::AddrIndexReg).getReg()))
- EVEX_V2 = 0x0;
+ unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
+ VEX_B = ~(BaseRegEnc >> 3) & 1;
+ unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
+ VEX_X = ~(IndexRegEnc >> 3) & 1;
+ if (!HasVEX_4V) // Only needed with VSIB which don't use VVVV.
+ EVEX_V2 = ~(IndexRegEnc >> 4) & 1;
if (HasVEX_4VOp3)
// Instruction format for 4VOp3:
@@ -794,8 +776,9 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// CurOp points to start of the MemoryOperand,
// it skips TIED_TO operands if exist, then increments past src1.
// CurOp + X86::AddrNumOperands will point to src3.
- VEX_4V = getVEXRegisterEncoding(MI, CurOp+X86::AddrNumOperands);
+ VEX_4V = ~getX86RegEncoding(MI, CurOp + X86::AddrNumOperands) & 0xf;
break;
+ }
case X86II::MRM0m: case X86II::MRM1m:
case X86II::MRM2m: case X86II::MRM3m:
case X86II::MRM4m: case X86II::MRM5m:
@@ -804,24 +787,21 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// MemAddr
// src1(VEX_4V), MemAddr
if (HasVEX_4V) {
- VEX_4V = getVEXRegisterEncoding(MI, CurOp);
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_V2 = 0x0;
- CurOp++;
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+ EVEX_V2 = ~(VRegEnc >> 4) & 1;
}
if (HasEVEX_K)
- EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++);
-
- if (X86II::isX86_64ExtendedReg(
- MI.getOperand(MemOperand+X86::AddrBaseReg).getReg()))
- VEX_B = 0x0;
- if (X86II::isX86_64ExtendedReg(
- MI.getOperand(MemOperand+X86::AddrIndexReg).getReg()))
- VEX_X = 0x0;
+ EVEX_aaa = getX86RegEncoding(MI, CurOp++);
+
+ unsigned BaseRegEnc = getX86RegEncoding(MI, MemOperand + X86::AddrBaseReg);
+ VEX_B = ~(BaseRegEnc >> 3) & 1;
+ unsigned IndexRegEnc = getX86RegEncoding(MI, MemOperand+X86::AddrIndexReg);
+ VEX_X = ~(IndexRegEnc >> 3) & 1;
break;
}
- case X86II::MRMSrcReg:
+ case X86II::MRMSrcReg: {
// MRMSrcReg instructions forms:
// dst(ModR/M), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM)
// dst(ModR/M), src1(ModR/M)
@@ -830,32 +810,27 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// FMA4:
// dst(ModR/M.reg), src1(VEX_4V), src2(ModR/M), src3(VEX_I8IMM)
// dst(ModR/M.reg), src1(VEX_4V), src2(VEX_I8IMM), src3(ModR/M),
- if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_R = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_R2 = 0x0;
- CurOp++;
+ unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_R = ~(RegEnc >> 3) & 1;
+ EVEX_R2 = ~(RegEnc >> 4) & 1;
if (HasEVEX_K)
- EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++);
+ EVEX_aaa = getX86RegEncoding(MI, CurOp++);
if (HasVEX_4V) {
- VEX_4V = getVEXRegisterEncoding(MI, CurOp);
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_V2 = 0x0;
- CurOp++;
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+ EVEX_V2 = ~(VRegEnc >> 4) & 1;
}
if (HasMemOp4) // Skip second register source (encoded in I8IMM)
CurOp++;
- if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_B = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_X = 0x0;
- CurOp++;
+ RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_B = ~(RegEnc >> 3) & 1;
+ VEX_X = ~(RegEnc >> 4) & 1;
if (HasVEX_4VOp3)
- VEX_4V = getVEXRegisterEncoding(MI, CurOp++);
+ VEX_4V = ~getX86RegEncoding(MI, CurOp++) & 0xf;
if (EVEX_b) {
if (HasEVEX_RC) {
unsigned RcOperand = NumOps-1;
@@ -865,55 +840,52 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
EncodeRC = true;
}
break;
- case X86II::MRMDestReg:
+ }
+ case X86II::MRMDestReg: {
// MRMDestReg instructions forms:
// dst(ModR/M), src(ModR/M)
// dst(ModR/M), src(ModR/M), imm8
// dst(ModR/M), src1(VEX_4V), src2(ModR/M)
- if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_B = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_X = 0x0;
- CurOp++;
+ unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_B = ~(RegEnc >> 3) & 1;
+ VEX_X = ~(RegEnc >> 4) & 1;
if (HasEVEX_K)
- EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++);
+ EVEX_aaa = getX86RegEncoding(MI, CurOp++);
if (HasVEX_4V) {
- VEX_4V = getVEXRegisterEncoding(MI, CurOp);
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_V2 = 0x0;
- CurOp++;
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+ EVEX_V2 = ~(VRegEnc >> 4) & 1;
}
- if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_R = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_R2 = 0x0;
+ RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_R = ~(RegEnc >> 3) & 1;
+ EVEX_R2 = ~(RegEnc >> 4) & 1;
if (EVEX_b)
EncodeRC = true;
break;
+ }
case X86II::MRM0r: case X86II::MRM1r:
case X86II::MRM2r: case X86II::MRM3r:
case X86II::MRM4r: case X86II::MRM5r:
- case X86II::MRM6r: case X86II::MRM7r:
+ case X86II::MRM6r: case X86II::MRM7r: {
// MRM0r-MRM7r instructions forms:
// dst(VEX_4V), src(ModR/M), imm8
if (HasVEX_4V) {
- VEX_4V = getVEXRegisterEncoding(MI, CurOp);
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- EVEX_V2 = 0x0;
- CurOp++;
+ unsigned VRegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_4V = ~VRegEnc & 0xf;
+ EVEX_V2 = ~(VRegEnc >> 4) & 1;
}
if (HasEVEX_K)
- EVEX_aaa = getWriteMaskRegisterEncoding(MI, CurOp++);
+ EVEX_aaa = getX86RegEncoding(MI, CurOp++);
- if (X86II::isX86_64ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_B = 0x0;
- if (X86II::is32ExtendedReg(MI.getOperand(CurOp).getReg()))
- VEX_X = 0x0;
+ unsigned RegEnc = getX86RegEncoding(MI, CurOp++);
+ VEX_B = ~(RegEnc >> 3) & 1;
+ VEX_X = ~(RegEnc >> 4) & 1;
break;
}
+ }
if (Encoding == X86II::VEX || Encoding == X86II::XOP) {
// VEX opcode prefix can have 2 or 3 bytes
@@ -931,7 +903,7 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// +-----+ +--------------+ +-------------------+
// | 8Fh | | RXB | m-mmmm | | W | vvvv | L | pp |
// +-----+ +--------------+ +-------------------+
- unsigned char LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);
+ uint8_t LastByte = VEX_PP | (VEX_L << 2) | (VEX_4V << 3);
// Can we use the 2 byte VEX prefix?
if (Encoding == X86II::VEX && VEX_B && VEX_X && !VEX_W && (VEX_5M == 1)) {
@@ -954,8 +926,6 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
assert((VEX_5M & 0x3) == VEX_5M
&& "More than 2 significant bits in VEX.m-mmmm fields for EVEX!");
- VEX_5M &= 0x3;
-
EmitByte(0x62, CurByte, OS);
EmitByte((VEX_R << 7) |
(VEX_X << 6) |
@@ -968,26 +938,27 @@ void X86MCCodeEmitter::EmitVEXOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
VEX_PP, CurByte, OS);
if (EncodeRC)
EmitByte((EVEX_z << 7) |
- (EVEX_rc << 5) |
- (EVEX_b << 4) |
- (EVEX_V2 << 3) |
- EVEX_aaa, CurByte, OS);
+ (EVEX_rc << 5) |
+ (EVEX_b << 4) |
+ (EVEX_V2 << 3) |
+ EVEX_aaa, CurByte, OS);
else
EmitByte((EVEX_z << 7) |
- (EVEX_L2 << 6) |
- (VEX_L << 5) |
- (EVEX_b << 4) |
- (EVEX_V2 << 3) |
- EVEX_aaa, CurByte, OS);
+ (EVEX_L2 << 6) |
+ (VEX_L << 5) |
+ (EVEX_b << 4) |
+ (EVEX_V2 << 3) |
+ EVEX_aaa, CurByte, OS);
}
}
/// DetermineREXPrefix - Determine if the MCInst has to be encoded with a X86-64
/// REX prefix which specifies 1) 64-bit instructions, 2) non-default operand
/// size, and 3) use of X86-64 extended registers.
-static unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
- const MCInstrDesc &Desc) {
- unsigned REX = 0;
+uint8_t X86MCCodeEmitter::DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
+ int MemOperand,
+ const MCInstrDesc &Desc) const {
+ uint8_t REX = 0;
bool UsesHighByteReg = false;
if (TSFlags & X86II::REX_W)
@@ -996,13 +967,10 @@ static unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
if (MI.getNumOperands() == 0) return REX;
unsigned NumOps = MI.getNumOperands();
- // FIXME: MCInst should explicitize the two-addrness.
- bool isTwoAddr = NumOps > 1 &&
- Desc.getOperandConstraint(1, MCOI::TIED_TO) != -1;
+ unsigned CurOp = X86II::getOperandBias(Desc);
// If it accesses SPL, BPL, SIL, or DIL, then it requires a 0x40 REX prefix.
- unsigned i = isTwoAddr ? 1 : 0;
- for (; i != NumOps; ++i) {
+ for (unsigned i = CurOp; i != NumOps; ++i) {
const MCOperand &MO = MI.getOperand(i);
if (!MO.isReg()) continue;
unsigned Reg = MO.getReg();
@@ -1016,65 +984,44 @@ static unsigned DetermineREXPrefix(const MCInst &MI, uint64_t TSFlags,
}
switch (TSFlags & X86II::FormMask) {
+ case X86II::AddRegFrm:
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 0; // REX.B
+ break;
case X86II::MRMSrcReg:
- if (MI.getOperand(0).isReg() &&
- X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
- REX |= 1 << 2; // set REX.R
- i = isTwoAddr ? 2 : 1;
- for (; i != NumOps; ++i) {
- const MCOperand &MO = MI.getOperand(i);
- if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg()))
- REX |= 1 << 0; // set REX.B
- }
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 2; // REX.R
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 0; // REX.B
break;
case X86II::MRMSrcMem: {
- if (MI.getOperand(0).isReg() &&
- X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
- REX |= 1 << 2; // set REX.R
- unsigned Bit = 0;
- i = isTwoAddr ? 2 : 1;
- for (; i != NumOps; ++i) {
- const MCOperand &MO = MI.getOperand(i);
- if (MO.isReg()) {
- if (X86II::isX86_64ExtendedReg(MO.getReg()))
- REX |= 1 << Bit; // set REX.B (Bit=0) and REX.X (Bit=1)
- Bit++;
- }
- }
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 2; // REX.R
+ REX |= isX86_64ExtendedReg(MI, MemOperand+X86::AddrBaseReg) << 0; // REX.B
+ REX |= isX86_64ExtendedReg(MI, MemOperand+X86::AddrIndexReg) << 1; // REX.X
+ CurOp += X86::AddrNumOperands;
break;
}
+ case X86II::MRMDestReg:
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 0; // REX.B
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 2; // REX.R
+ break;
+ case X86II::MRMDestMem:
+ REX |= isX86_64ExtendedReg(MI, MemOperand+X86::AddrBaseReg) << 0; // REX.B
+ REX |= isX86_64ExtendedReg(MI, MemOperand+X86::AddrIndexReg) << 1; // REX.X
+ CurOp += X86::AddrNumOperands;
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 2; // REX.R
+ break;
case X86II::MRMXm:
case X86II::MRM0m: case X86II::MRM1m:
case X86II::MRM2m: case X86II::MRM3m:
case X86II::MRM4m: case X86II::MRM5m:
case X86II::MRM6m: case X86II::MRM7m:
- case X86II::MRMDestMem: {
- unsigned e = (isTwoAddr ? X86::AddrNumOperands+1 : X86::AddrNumOperands);
- i = isTwoAddr ? 1 : 0;
- if (NumOps > e && MI.getOperand(e).isReg() &&
- X86II::isX86_64ExtendedReg(MI.getOperand(e).getReg()))
- REX |= 1 << 2; // set REX.R
- unsigned Bit = 0;
- for (; i != e; ++i) {
- const MCOperand &MO = MI.getOperand(i);
- if (MO.isReg()) {
- if (X86II::isX86_64ExtendedReg(MO.getReg()))
- REX |= 1 << Bit; // REX.B (Bit=0) and REX.X (Bit=1)
- Bit++;
- }
- }
+ REX |= isX86_64ExtendedReg(MI, MemOperand+X86::AddrBaseReg) << 0; // REX.B
+ REX |= isX86_64ExtendedReg(MI, MemOperand+X86::AddrIndexReg) << 1; // REX.X
break;
- }
- default:
- if (MI.getOperand(0).isReg() &&
- X86II::isX86_64ExtendedReg(MI.getOperand(0).getReg()))
- REX |= 1 << 0; // set REX.B
- i = isTwoAddr ? 2 : 1;
- for (unsigned e = NumOps; i != e; ++i) {
- const MCOperand &MO = MI.getOperand(i);
- if (MO.isReg() && X86II::isX86_64ExtendedReg(MO.getReg()))
- REX |= 1 << 2; // set REX.R
- }
+ case X86II::MRMXr:
+ case X86II::MRM0r: case X86II::MRM1r:
+ case X86II::MRM2r: case X86II::MRM3r:
+ case X86II::MRM4r: case X86II::MRM5r:
+ case X86II::MRM6r: case X86II::MRM7r:
+ REX |= isX86_64ExtendedReg(MI, CurOp++) << 0; // REX.B
break;
}
if (REX && UsesHighByteReg)
@@ -1101,16 +1048,18 @@ void X86MCCodeEmitter::EmitSegmentOverridePrefix(unsigned &CurByte,
}
}
-/// EmitOpcodePrefix - Emit all instruction prefixes prior to the opcode.
+/// Emit all instruction prefixes prior to the opcode.
///
/// MemOperand is the operand # of the start of a memory operand if present. If
/// Not present, it is -1.
-void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
+///
+/// Returns true if a REX prefix was used.
+bool X86MCCodeEmitter::emitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
int MemOperand, const MCInst &MI,
const MCInstrDesc &Desc,
const MCSubtargetInfo &STI,
raw_ostream &OS) const {
-
+ bool Ret = false;
// Emit the operand size opcode prefix as needed.
if ((TSFlags & X86II::OpSizeMask) == (is16BitMode(STI) ? X86II::OpSize32
: X86II::OpSize16))
@@ -1135,8 +1084,10 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
// Handle REX prefix.
// FIXME: Can this come before F2 etc to simplify emission?
if (is64BitMode(STI)) {
- if (unsigned REX = DetermineREXPrefix(MI, TSFlags, Desc))
+ if (uint8_t REX = DetermineREXPrefix(MI, TSFlags, MemOperand, Desc)) {
EmitByte(0x40 | REX, CurByte, OS);
+ Ret = true;
+ }
}
// 0x0F escape code must be emitted just before the opcode.
@@ -1156,6 +1107,7 @@ void X86MCCodeEmitter::EmitOpcodePrefix(uint64_t TSFlags, unsigned &CurByte,
EmitByte(0x3A, CurByte, OS);
break;
}
+ return Ret;
}
void X86MCCodeEmitter::
@@ -1183,14 +1135,18 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
bool HasVEX_4V = TSFlags & X86II::VEX_4V;
bool HasVEX_4VOp3 = TSFlags & X86II::VEX_4VOp3;
bool HasMemOp4 = TSFlags & X86II::MemOp4;
- const unsigned MemOp4_I8IMMOperand = 2;
+ bool HasVEX_I8IMM = TSFlags & X86II::VEX_I8IMM;
+ assert((!HasMemOp4 || HasVEX_I8IMM) && "MemOp4 should imply VEX_I8IMM");
// It uses the EVEX.aaa field?
bool HasEVEX_K = TSFlags & X86II::EVEX_K;
bool HasEVEX_RC = TSFlags & X86II::EVEX_RC;
+ // Used if a register is encoded in 7:4 of immediate.
+ unsigned I8RegNum = 0;
+
// Determine where the memory operand starts, if present.
- int MemoryOperand = X86II::getMemoryOperandNo(TSFlags, Opcode);
+ int MemoryOperand = X86II::getMemoryOperandNo(TSFlags);
if (MemoryOperand != -1) MemoryOperand += CurOp;
// Emit segment override opcode prefix as needed.
@@ -1226,19 +1182,20 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
if (need_address_override)
EmitByte(0x67, CurByte, OS);
+ bool Rex = false;
if (Encoding == 0)
- EmitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
+ Rex = emitOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, STI, OS);
else
EmitVEXOpcodePrefix(TSFlags, CurByte, MemoryOperand, MI, Desc, OS);
- unsigned char BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);
+ uint8_t BaseOpcode = X86II::getBaseOpcodeFor(TSFlags);
if (TSFlags & X86II::Has3DNow0F0FOpcode)
BaseOpcode = 0x0F; // Weird 3DNow! encoding.
- unsigned SrcRegNum = 0;
- switch (TSFlags & X86II::FormMask) {
- default: errs() << "FORM: " << (TSFlags & X86II::FormMask) << "\n";
+ uint64_t Form = TSFlags & X86II::FormMask;
+ switch (Form) {
+ default: errs() << "FORM: " << Form << "\n";
llvm_unreachable("Unknown FormMask value in X86MCCodeEmitter!");
case X86II::Pseudo:
llvm_unreachable("Pseudo instruction shouldn't be emitted");
@@ -1315,12 +1272,12 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitByte(BaseOpcode + GetX86RegNum(MI.getOperand(CurOp++)), CurByte, OS);
break;
- case X86II::MRMDestReg:
+ case X86II::MRMDestReg: {
EmitByte(BaseOpcode, CurByte, OS);
- SrcRegNum = CurOp + 1;
+ unsigned SrcRegNum = CurOp + 1;
if (HasEVEX_K) // Skip writemask
- SrcRegNum++;
+ ++SrcRegNum;
if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
++SrcRegNum;
@@ -1329,71 +1286,68 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
GetX86RegNum(MI.getOperand(SrcRegNum)), CurByte, OS);
CurOp = SrcRegNum + 1;
break;
-
- case X86II::MRMDestMem:
+ }
+ case X86II::MRMDestMem: {
EmitByte(BaseOpcode, CurByte, OS);
- SrcRegNum = CurOp + X86::AddrNumOperands;
+ unsigned SrcRegNum = CurOp + X86::AddrNumOperands;
if (HasEVEX_K) // Skip writemask
- SrcRegNum++;
+ ++SrcRegNum;
if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
++SrcRegNum;
- EmitMemModRMByte(MI, CurOp,
- GetX86RegNum(MI.getOperand(SrcRegNum)),
- TSFlags, CurByte, OS, Fixups, STI);
+ emitMemModRMByte(MI, CurOp, GetX86RegNum(MI.getOperand(SrcRegNum)), TSFlags,
+ Rex, CurByte, OS, Fixups, STI);
CurOp = SrcRegNum + 1;
break;
-
- case X86II::MRMSrcReg:
+ }
+ case X86II::MRMSrcReg: {
EmitByte(BaseOpcode, CurByte, OS);
- SrcRegNum = CurOp + 1;
+ unsigned SrcRegNum = CurOp + 1;
if (HasEVEX_K) // Skip writemask
- SrcRegNum++;
+ ++SrcRegNum;
if (HasVEX_4V) // Skip 1st src (which is encoded in VEX_VVVV)
++SrcRegNum;
- if (HasMemOp4) // Skip 2nd src (which is encoded in I8IMM)
- ++SrcRegNum;
+ if (HasMemOp4) // Capture 2nd src (which is encoded in I8IMM)
+ I8RegNum = getX86RegEncoding(MI, SrcRegNum++);
EmitRegModRMByte(MI.getOperand(SrcRegNum),
GetX86RegNum(MI.getOperand(CurOp)), CurByte, OS);
-
- // 2 operands skipped with HasMemOp4, compensate accordingly
- CurOp = HasMemOp4 ? SrcRegNum : SrcRegNum + 1;
+ CurOp = SrcRegNum + 1;
if (HasVEX_4VOp3)
++CurOp;
+ if (!HasMemOp4 && HasVEX_I8IMM)
+ I8RegNum = getX86RegEncoding(MI, CurOp++);
// do not count the rounding control operand
if (HasEVEX_RC)
- NumOps--;
+ --NumOps;
break;
-
+ }
case X86II::MRMSrcMem: {
- int AddrOperands = X86::AddrNumOperands;
unsigned FirstMemOp = CurOp+1;
- if (HasEVEX_K) { // Skip writemask
- ++AddrOperands;
+ if (HasEVEX_K) // Skip writemask
++FirstMemOp;
- }
- if (HasVEX_4V) {
- ++AddrOperands;
+ if (HasVEX_4V)
++FirstMemOp; // Skip the register source (which is encoded in VEX_VVVV).
- }
- if (HasMemOp4) // Skip second register source (encoded in I8IMM)
- ++FirstMemOp;
+
+ if (HasMemOp4) // Capture second register source (encoded in I8IMM)
+ I8RegNum = getX86RegEncoding(MI, FirstMemOp++);
EmitByte(BaseOpcode, CurByte, OS);
- EmitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
- TSFlags, CurByte, OS, Fixups, STI);
- CurOp += AddrOperands + 1;
+ emitMemModRMByte(MI, FirstMemOp, GetX86RegNum(MI.getOperand(CurOp)),
+ TSFlags, Rex, CurByte, OS, Fixups, STI);
+ CurOp = FirstMemOp + X86::AddrNumOperands;
if (HasVEX_4VOp3)
++CurOp;
+ if (!HasMemOp4 && HasVEX_I8IMM)
+ I8RegNum = getX86RegEncoding(MI, CurOp++);
break;
}
@@ -1407,7 +1361,6 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
if (HasEVEX_K) // Skip writemask
++CurOp;
EmitByte(BaseOpcode, CurByte, OS);
- uint64_t Form = TSFlags & X86II::FormMask;
EmitRegModRMByte(MI.getOperand(CurOp++),
(Form == X86II::MRMXr) ? 0 : Form-X86II::MRM0r,
CurByte, OS);
@@ -1424,9 +1377,9 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
if (HasEVEX_K) // Skip writemask
++CurOp;
EmitByte(BaseOpcode, CurByte, OS);
- uint64_t Form = TSFlags & X86II::FormMask;
- EmitMemModRMByte(MI, CurOp, (Form == X86II::MRMXm) ? 0 : Form-X86II::MRM0m,
- TSFlags, CurByte, OS, Fixups, STI);
+ emitMemModRMByte(MI, CurOp,
+ (Form == X86II::MRMXm) ? 0 : Form - X86II::MRM0m, TSFlags,
+ Rex, CurByte, OS, Fixups, STI);
CurOp += X86::AddrNumOperands;
break;
}
@@ -1453,38 +1406,27 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
case X86II::MRM_FC: case X86II::MRM_FD: case X86II::MRM_FE:
case X86II::MRM_FF:
EmitByte(BaseOpcode, CurByte, OS);
-
- uint64_t Form = TSFlags & X86II::FormMask;
EmitByte(0xC0 + Form - X86II::MRM_C0, CurByte, OS);
break;
}
- // If there is a remaining operand, it must be a trailing immediate. Emit it
- // according to the right size for the instruction. Some instructions
- // (SSE4a extrq and insertq) have two trailing immediates.
- while (CurOp != NumOps && NumOps - CurOp <= 2) {
+ if (HasVEX_I8IMM) {
// The last source register of a 4 operand instruction in AVX is encoded
// in bits[7:4] of a immediate byte.
- if (TSFlags & X86II::VEX_I8IMM) {
- const MCOperand &MO = MI.getOperand(HasMemOp4 ? MemOp4_I8IMMOperand
- : CurOp);
- ++CurOp;
- unsigned RegNum = GetX86RegNum(MO) << 4;
- if (X86II::isX86_64ExtendedReg(MO.getReg()))
- RegNum |= 1 << 7;
- // If there is an additional 5th operand it must be an immediate, which
- // is encoded in bits[3:0]
- if (CurOp != NumOps) {
- const MCOperand &MIMM = MI.getOperand(CurOp++);
- if (MIMM.isImm()) {
- unsigned Val = MIMM.getImm();
- assert(Val < 16 && "Immediate operand value out of range");
- RegNum |= Val;
- }
- }
- EmitImmediate(MCOperand::createImm(RegNum), MI.getLoc(), 1, FK_Data_1,
- CurByte, OS, Fixups);
- } else {
+ assert(I8RegNum < 16 && "Register encoding out of range");
+ I8RegNum <<= 4;
+ if (CurOp != NumOps) {
+ unsigned Val = MI.getOperand(CurOp++).getImm();
+ assert(Val < 16 && "Immediate operand value out of range");
+ I8RegNum |= Val;
+ }
+ EmitImmediate(MCOperand::createImm(I8RegNum), MI.getLoc(), 1, FK_Data_1,
+ CurByte, OS, Fixups);
+ } else {
+ // If there is a remaining operand, it must be a trailing immediate. Emit it
+ // according to the right size for the instruction. Some instructions
+ // (SSE4a extrq and insertq) have two trailing immediates.
+ while (CurOp != NumOps && NumOps - CurOp <= 2) {
EmitImmediate(MI.getOperand(CurOp++), MI.getLoc(),
X86II::getSizeOfImm(TSFlags), getImmFixupKind(TSFlags),
CurByte, OS, Fixups);