35#define DEBUG_TYPE "mccodeemitter"
39enum PrefixKind {
None, REX, REX2, XOP, VEX2, VEX3, EVEX };
43class X86OpcodePrefixHelper {
158 unsigned EVEX_L2 : 1;
160 unsigned EVEX_V2 : 1;
161 unsigned EVEX_aaa : 3;
162 PrefixKind Kind =
None;
165 unsigned getRegEncoding(
const MCInst &
MI,
unsigned OpNum)
const {
166 return MRI.getEncodingValue(
MI.getOperand(OpNum).getReg());
169 void setR(
unsigned Encoding) { R = Encoding >> 3 & 1; }
170 void setR2(
unsigned Encoding) {
171 R2 = Encoding >> 4 & 1;
172 assert((!
R2 || (Kind <= REX2 || Kind == EVEX)) &&
"invalid setting");
174 void setX(
unsigned Encoding) { X = Encoding >> 3 & 1; }
175 void setX2(
unsigned Encoding) {
176 assert((Kind <= REX2 || Kind == EVEX) &&
"invalid setting");
177 X2 = Encoding >> 4 & 1;
179 void setB(
unsigned Encoding) { B = Encoding >> 3 & 1; }
180 void setB2(
unsigned Encoding) {
181 assert((Kind <= REX2 || Kind == EVEX) &&
"invalid setting");
182 B2 = Encoding >> 4 & 1;
184 void set4V(
unsigned Encoding) { VEX_4V = Encoding & 0xf; }
185 void setV2(
unsigned Encoding) { EVEX_V2 = Encoding >> 4 & 1; }
188 void setW(
bool V) { W = V; }
189 void setR(
const MCInst &
MI,
unsigned OpNum) {
190 setR(getRegEncoding(
MI, OpNum));
192 void setX(
const MCInst &
MI,
unsigned OpNum,
unsigned Shift = 3) {
193 unsigned Reg =
MI.getOperand(OpNum).getReg();
197 unsigned Encoding =
MRI.getEncodingValue(Reg);
198 X = Encoding >> Shift & 1;
200 void setB(
const MCInst &
MI,
unsigned OpNum) {
201 B = getRegEncoding(
MI, OpNum) >> 3 & 1;
203 void set4V(
const MCInst &
MI,
unsigned OpNum,
bool IsImm =
false) {
206 set4V(~(
MI.getOperand(OpNum).getImm()));
208 set4V(getRegEncoding(
MI, OpNum));
210 void setL(
bool V) { VEX_L = V; }
211 void setPP(
unsigned V) { VEX_PP = V; }
212 void set5M(
unsigned V) { VEX_5M = V; }
213 void setR2(
const MCInst &
MI,
unsigned OpNum) {
214 setR2(getRegEncoding(
MI, OpNum));
216 void setRR2(
const MCInst &
MI,
unsigned OpNum) {
217 unsigned Encoding = getRegEncoding(
MI, OpNum);
221 void setM(
bool V) { M = V; }
222 void setXX2(
const MCInst &
MI,
unsigned OpNum) {
223 unsigned Reg =
MI.getOperand(OpNum).getReg();
224 unsigned Encoding =
MRI.getEncodingValue(Reg);
230 void setBB2(
const MCInst &
MI,
unsigned OpNum) {
231 unsigned Reg =
MI.getOperand(OpNum).getReg();
232 unsigned Encoding =
MRI.getEncodingValue(Reg);
238 void setZ(
bool V) { EVEX_z = V; }
239 void setL2(
bool V) { EVEX_L2 = V; }
240 void setEVEX_b(
bool V) { EVEX_b = V; }
241 void setV2(
const MCInst &
MI,
unsigned OpNum,
bool HasVEX_4V) {
245 unsigned Reg =
MI.getOperand(OpNum).getReg();
248 setV2(
MRI.getEncodingValue(Reg));
250 void set4VV2(
const MCInst &
MI,
unsigned OpNum) {
251 unsigned Encoding = getRegEncoding(
MI, OpNum);
255 void setAAA(
const MCInst &
MI,
unsigned OpNum) {
256 EVEX_aaa = getRegEncoding(
MI, OpNum);
258 void setNF(
bool V) { EVEX_aaa |= V << 2; }
259 void setSC(
const MCInst &
MI,
unsigned OpNum) {
260 unsigned Encoding =
MI.getOperand(OpNum).getImm();
261 EVEX_V2 = ~(Encoding >> 3) & 0x1;
262 EVEX_aaa = Encoding & 0x7;
266 : W(0), R(0), X(0), B(0), M(0),
R2(0), X2(0), B2(0), VEX_4V(0), VEX_L(0),
267 VEX_PP(0), VEX_5M(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0),
270 void setLowerBound(PrefixKind K) { Kind = K; }
272 PrefixKind determineOptimalKind() {
278 Kind = (
R2 | X2 | B2) ? REX2 : (W | R | X | B) ? REX :
None;
281 Kind = (
R2 | X2 | B2) ? REX2 : REX;
289 Kind = (W | X | B | (VEX_5M != 1)) ? VEX3 : VEX2;
296 uint8_t FirstPayload =
297 ((~R) & 0x1) << 7 | ((~X) & 0x1) << 6 | ((~B) & 0x1) << 5;
298 uint8_t LastPayload = ((~VEX_4V) & 0xf) << 3 | VEX_L << 2 | VEX_PP;
303 emitByte(0x40 | W << 3 | R << 2 | X << 1 | B, CB);
307 emitByte(M << 7 |
R2 << 6 | X2 << 5 | B2 << 4 | W << 3 | R << 2 | X << 1 |
313 emitByte(((~R) & 1) << 7 | LastPayload, CB);
317 emitByte(Kind == VEX3 ? 0xC4 : 0x8F, CB);
318 emitByte(FirstPayload | VEX_5M, CB);
319 emitByte(W << 7 | LastPayload, CB);
322 assert(VEX_5M && !(VEX_5M & 0x8) &&
"invalid mmm fields for EVEX!");
324 emitByte(FirstPayload | ((~
R2) & 0x1) << 4 | B2 << 3 | VEX_5M, CB);
325 emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | ((~X2) & 0x1) << 2 | VEX_PP,
327 emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 |
328 ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa,
341 : MCII(mcii), Ctx(ctx) {}
342 X86MCCodeEmitter(
const X86MCCodeEmitter &) =
delete;
343 X86MCCodeEmitter &
operator=(
const X86MCCodeEmitter &) =
delete;
344 ~X86MCCodeEmitter()
override =
default;
354 unsigned getX86RegNum(
const MCOperand &MO)
const;
356 unsigned getX86RegEncoding(
const MCInst &
MI,
unsigned OpNum)
const;
358 void emitImmediate(
const MCOperand &Disp,
SMLoc Loc,
unsigned ImmSize,
363 void emitRegModRMByte(
const MCOperand &ModRMReg,
unsigned RegOpcodeFld,
366 void emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
369 void emitMemModRMByte(
const MCInst &
MI,
unsigned Op,
unsigned RegOpcodeField,
374 bool ForceSIB =
false)
const;
376 PrefixKind emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
380 PrefixKind emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
384 void emitSegmentOverridePrefix(
unsigned SegOperand,
const MCInst &
MI,
387 PrefixKind emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
391 PrefixKind emitREXPrefix(
int MemOperand,
const MCInst &
MI,
398static uint8_t
modRMByte(
unsigned Mod,
unsigned RegOpcode,
unsigned RM) {
399 assert(
Mod < 4 && RegOpcode < 8 && RM < 8 &&
"ModRM Fields out of range!");
400 return RM | (RegOpcode << 3) | (
Mod << 6);
406 for (
unsigned i = 0; i !=
Size; ++i) {
407 emitByte(Val & 255, CB);
420 CD8_Scale = CD8_Scale ? 1U << (CD8_Scale - 1) : 0U;
421 if (!HasEVEX || !CD8_Scale)
422 return isInt<8>(
Value);
425 if (
Value & (CD8_Scale - 1))
428 int CDisp8 =
Value /
static_cast<int>(CD8_Scale);
429 if (!isInt<8>(CDisp8))
433 ImmOffset = CDisp8 -
Value;
475 if (S.
getName() !=
"_GLOBAL_OFFSET_TABLE_")
491 unsigned Opcode =
MI.getOpcode();
493 if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4 &&
494 Opcode != X86::JCC_4) ||
507unsigned X86MCCodeEmitter::getX86RegNum(
const MCOperand &MO)
const {
508 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg()) & 0x7;
511unsigned X86MCCodeEmitter::getX86RegEncoding(
const MCInst &
MI,
512 unsigned OpNum)
const {
513 return Ctx.getRegisterInfo()->getEncodingValue(
MI.getOperand(OpNum).getReg());
516void X86MCCodeEmitter::emitImmediate(
const MCOperand &DispOp,
SMLoc Loc,
521 int ImmOffset)
const {
522 const MCExpr *Expr =
nullptr;
523 if (DispOp.
isImm()) {
551 ImmOffset =
static_cast<int>(CB.
size() - StartByte);
591 Expr, FixupKind, Loc));
595void X86MCCodeEmitter::emitRegModRMByte(
const MCOperand &ModRMReg,
596 unsigned RegOpcodeFld,
598 emitByte(
modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), CB);
601void X86MCCodeEmitter::emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
607void X86MCCodeEmitter::emitMemModRMByte(
611 bool ForceSIB)
const {
616 unsigned BaseReg =
Base.getReg();
619 if (BaseReg == X86::RIP ||
620 BaseReg == X86::EIP) {
622 "Rip-relative addressing requires 64-bit mode");
624 "Invalid rip-relative address");
625 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
627 unsigned Opcode =
MI.getOpcode();
631 if (!(Disp.
isExpr() && isa<MCSymbolRefExpr>(Disp.
getExpr())))
644 assert(Kind == REX || Kind == REX2);
658 case X86::TAILJMPm64:
687 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte, CB,
692 unsigned BaseRegNo = BaseReg ? getX86RegNum(
Base) : -1U;
709 static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
710 unsigned RMfield = R16Table[BaseRegNo];
712 assert(RMfield &&
"invalid 16-bit base register");
715 unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];
717 assert(IndexReg16 &&
"invalid 16-bit index register");
719 assert(((IndexReg16 ^ RMfield) & 2) &&
720 "invalid 16-bit base/index register combination");
722 "invalid scale for 16-bit memory reference");
726 RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
728 RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
732 if (Disp.
getImm() == 0 && RMfield != 6) {
734 emitByte(
modRMByte(0, RegOpcodeField, RMfield), CB);
738 emitByte(
modRMByte(1, RegOpcodeField, RMfield), CB);
739 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups);
743 emitByte(
modRMByte(2, RegOpcodeField, RMfield), CB);
745 assert(IndexReg.
getReg() == 0 &&
"Unexpected index register!");
747 emitByte(
modRMByte(0, RegOpcodeField, 6), CB);
751 emitImmediate(Disp,
MI.getLoc(), 2,
FK_Data_2, StartByte, CB, Fixups);
760 bool AllowNoDisp = !UseDisp8 && !UseDisp32;
762 bool AllowDisp8 = !UseDisp32;
768 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
769 emitImmediate(Disp,
MI.getLoc(), 4,
FK_Data_4, StartByte, CB, Fixups);
779 if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp) {
780 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
786 auto *
Sym = dyn_cast<MCSymbolRefExpr>(Disp.
getExpr());
791 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
801 if (Disp.
isImm() && AllowDisp8) {
804 emitByte(
modRMByte(1, RegOpcodeField, BaseRegNo), CB);
805 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups,
814 emitByte(
modRMByte(2, RegOpcodeField, BaseRegNo), CB);
815 unsigned Opcode =
MI.getOpcode();
818 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte, CB,
825 "Cannot use ESP as index reg!");
827 bool ForceDisp32 =
false;
828 bool ForceDisp8 =
false;
834 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
836 }
else if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp &&
843 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
844 }
else if (Disp.
isImm() && AllowDisp8 &&
849 emitByte(
modRMByte(1, RegOpcodeField, 4), CB);
853 emitByte(
modRMByte(2, RegOpcodeField, 4), CB);
858 static const unsigned SSTable[] = {~0
U, 0, 1, ~0
U, 2, ~0
U, ~0
U, ~0
U, 3};
859 unsigned SS = SSTable[Scale.
getImm()];
861 unsigned IndexRegNo = IndexReg.
getReg() ? getX86RegNum(IndexReg) : 4;
863 emitSIBByte(SS, IndexRegNo, BaseRegNo, CB);
867 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups,
869 else if (ForceDisp32)
871 StartByte, CB, Fixups);
878PrefixKind X86MCCodeEmitter::emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
881 uint64_t TSFlags = MCII.get(
MI.getOpcode()).TSFlags;
885 if (MemoryOperand != -1) {
886 MemoryOperand += CurOp;
891 unsigned Flags =
MI.getFlags();
908 if (
MI.getOperand(2).getReg() != X86::DS)
909 emitSegmentOverridePrefix(2,
MI, CB);
915 if (
MI.getOperand(1).getReg() != X86::DS)
916 emitSegmentOverridePrefix(1,
MI, CB);
926 emitSegmentOverridePrefix(1,
MI, CB);
934 ? emitVEXOpcodePrefix(MemoryOperand,
MI, STI, CB)
935 : emitOpcodePrefix(MemoryOperand,
MI, STI, CB);
952X86MCCodeEmitter::emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
961 unsigned NumOps =
MI.getNumOperands();
968 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
970 "Cannot encode high byte register in VEX/EVEX-prefixed instruction");
974 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
979 Prefix.setLowerBound(XOP);
986 Prefix.setLowerBound(EVEX);
1053 bool EncodeRC =
false;
1054 uint8_t EVEX_rc = 0;
1096 if (!IsND && HasVEX_4V)
1100 if (HasTwoConditionalOps) {
1128 if (!IsND && HasVEX_4V)
1135 if (HasTwoConditionalOps) {
1179 if (HasTwoConditionalOps) {
1204 if (!IsND && HasVEX_4V)
1211 if (HasTwoConditionalOps) {
1218 unsigned NumOps =
Desc.getNumOperands();
1219 unsigned RcOperand = NumOps - 1;
1220 assert(RcOperand >= CurOp);
1221 EVEX_rc =
MI.getOperand(RcOperand).getImm();
1222 assert(EVEX_rc <= 3 &&
"Invalid rounding control!");
1266 if (!IsND && HasVEX_4V)
1270 if (HasTwoConditionalOps) {
1304 if (HasTwoConditionalOps) {
1312 Prefix.setL(EVEX_rc & 0x1);
1313 Prefix.setL2(EVEX_rc & 0x2);
1315 PrefixKind
Kind =
Prefix.determineOptimalKind();
1326PrefixKind X86MCCodeEmitter::emitREXPrefix(
int MemOperand,
const MCInst &
MI,
1331 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
1335 unsigned NumOps =
MI.getNumOperands();
1336 bool UsesHighByteReg =
false;
1338 bool HasRegOp =
false;
1341 for (
unsigned i = CurOp; i != NumOps; ++i) {
1348 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
1349 UsesHighByteReg =
true;
1352 Prefix.setLowerBound(REX);
1359 const auto *
Ref = dyn_cast<MCSymbolRefExpr>(MO.
getExpr());
1362 Prefix.setLowerBound(REX);
1367 Prefix.setLowerBound(REX2);
1370 assert(!HasRegOp &&
"Unexpected form in emitREXPrefix!");
1430 PrefixKind
Kind =
Prefix.determineOptimalKind();
1431 if (Kind && UsesHighByteReg)
1433 "Cannot encode high byte register in REX-prefixed instruction");
1439void X86MCCodeEmitter::emitSegmentOverridePrefix(
1442 if (
unsigned Reg =
MI.getOperand(SegOperand).getReg())
1452PrefixKind X86MCCodeEmitter::emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
1485 "REX.W requires 64bit mode.");
1486 PrefixKind
Kind = emitREXPrefix(MemOperand,
MI, STI, CB);
1516 unsigned Opcode =
MI.getOpcode();
1526 emitPrefixImpl(CurOp,
MI, STI, CB);
1529void X86MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
1533 unsigned Opcode =
MI.getOpcode();
1541 unsigned NumOps =
Desc.getNumOperands();
1546 PrefixKind
Kind = emitPrefixImpl(CurOp,
MI, STI, CB);
1557 unsigned I8RegNum = 0;
1564 unsigned OpcodeOffset = 0;
1572 errs() <<
"FORM: " <<
Form <<
"\n";
1580 emitByte(BaseOpcode, CB);
1584 OpcodeOffset =
MI.getOperand(NumOps - 1).getImm();
1585 assert(OpcodeOffset < 16 &&
"Unexpected opcode offset!");
1589 emitByte(BaseOpcode + OpcodeOffset, CB);
1601 emitByte(BaseOpcode, CB);
1602 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1604 StartByte, CB, Fixups);
1608 emitByte(BaseOpcode, CB);
1609 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1611 StartByte, CB, Fixups);
1612 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 1,
FK_Data_1, StartByte,
1616 emitByte(BaseOpcode, CB);
1617 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1619 StartByte, CB, Fixups);
1620 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 2,
FK_Data_2, StartByte,
1625 emitByte(BaseOpcode + getX86RegNum(
MI.getOperand(CurOp++)), CB);
1629 emitByte(BaseOpcode, CB);
1630 unsigned SrcRegNum = CurOp + 1;
1640 emitRegModRMByte(
MI.getOperand(CurOp),
1641 getX86RegNum(
MI.getOperand(SrcRegNum)), CB);
1642 CurOp = SrcRegNum + 1;
1646 unsigned FirstOp = CurOp++;
1647 unsigned SecondOp = CurOp++;
1648 unsigned CC =
MI.getOperand(CurOp++).getImm();
1649 emitByte(BaseOpcode +
CC, CB);
1650 emitRegModRMByte(
MI.getOperand(FirstOp),
1651 getX86RegNum(
MI.getOperand(SecondOp)), CB);
1655 unsigned CC =
MI.getOperand(8).getImm();
1656 emitByte(BaseOpcode +
CC, CB);
1658 emitMemModRMByte(
MI, CurOp + 1, getX86RegNum(
MI.getOperand(0)), TSFlags,
1659 Kind, StartByte, CB, Fixups, STI,
false);
1660 CurOp = SrcRegNum + 3;
1665 emitByte(BaseOpcode, CB);
1678 emitMemModRMByte(
MI, CurOp, getX86RegNum(
MI.getOperand(SrcRegNum)), TSFlags,
1679 Kind, StartByte, CB, Fixups, STI, ForceSIB);
1680 CurOp = SrcRegNum + 1;
1684 unsigned MemOp = CurOp;
1686 unsigned RegOp = CurOp++;
1687 unsigned CC =
MI.getOperand(CurOp++).getImm();
1688 emitByte(BaseOpcode +
CC, CB);
1689 emitMemModRMByte(
MI,
MemOp, getX86RegNum(
MI.getOperand(RegOp)), TSFlags,
1690 Kind, StartByte, CB, Fixups, STI);
1694 emitByte(BaseOpcode, CB);
1695 unsigned SrcRegNum = CurOp + 1;
1706 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1707 getX86RegNum(
MI.getOperand(CurOp)), CB);
1708 CurOp = SrcRegNum + 1;
1710 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1717 emitByte(BaseOpcode, CB);
1718 unsigned SrcRegNum = CurOp + 1;
1720 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1721 getX86RegNum(
MI.getOperand(CurOp)), CB);
1722 CurOp = SrcRegNum + 1;
1727 emitByte(BaseOpcode, CB);
1728 unsigned SrcRegNum = CurOp + 1;
1734 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1735 I8RegNum = getX86RegEncoding(
MI, SrcRegNum++);
1737 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1738 getX86RegNum(
MI.getOperand(CurOp)), CB);
1739 CurOp = SrcRegNum + 1;
1745 unsigned FirstOp = CurOp++;
1746 unsigned SecondOp = CurOp++;
1748 unsigned CC =
MI.getOperand(CurOp++).getImm();
1749 emitByte(BaseOpcode +
CC, CB);
1751 emitRegModRMByte(
MI.getOperand(SecondOp),
1752 getX86RegNum(
MI.getOperand(FirstOp)), CB);
1757 unsigned FirstMemOp = CurOp + 1;
1768 emitByte(BaseOpcode, CB);
1771 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1772 TSFlags, Kind, StartByte, CB, Fixups, STI, ForceSIB);
1775 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1779 unsigned FirstMemOp = CurOp + 1;
1781 emitByte(BaseOpcode, CB);
1783 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1784 TSFlags, Kind, StartByte, CB, Fixups, STI);
1790 unsigned FirstMemOp = CurOp + 1;
1795 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1796 I8RegNum = getX86RegEncoding(
MI, FirstMemOp++);
1798 emitByte(BaseOpcode, CB);
1800 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1801 TSFlags, Kind, StartByte, CB, Fixups, STI);
1808 unsigned RegOp = CurOp++;
1809 unsigned FirstMemOp = CurOp;
1812 unsigned CC =
MI.getOperand(CurOp++).getImm();
1813 emitByte(BaseOpcode +
CC, CB);
1815 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(RegOp)),
1816 TSFlags, Kind, StartByte, CB, Fixups, STI);
1821 unsigned RegOp = CurOp++;
1823 unsigned CC =
MI.getOperand(CurOp++).getImm();
1824 emitByte(BaseOpcode +
CC, CB);
1825 emitRegModRMByte(
MI.getOperand(RegOp), 0, CB);
1842 emitByte(BaseOpcode, CB);
1843 emitRegModRMByte(
MI.getOperand(CurOp++),
1847 emitByte(BaseOpcode, CB);
1848 emitByte(
modRMByte(3, getX86RegNum(
MI.getOperand(CurOp++)), 0), CB);
1852 unsigned FirstMemOp = CurOp;
1855 unsigned CC =
MI.getOperand(CurOp++).getImm();
1856 emitByte(BaseOpcode +
CC, CB);
1858 emitMemModRMByte(
MI, FirstMemOp, 0, TSFlags, Kind, StartByte, CB, Fixups,
1876 emitByte(BaseOpcode, CB);
1877 emitMemModRMByte(
MI, CurOp,
1879 Kind, StartByte, CB, Fixups, STI);
1891 emitByte(BaseOpcode, CB);
1959 emitByte(BaseOpcode, CB);
1967 assert(I8RegNum < 16 &&
"Register encoding out of range");
1969 if (CurOp != NumOps) {
1970 unsigned Val =
MI.getOperand(CurOp++).getImm();
1971 assert(Val < 16 &&
"Immediate operand value out of range");
1975 StartByte, CB, Fixups);
1982 unsigned RemaningOps = NumOps - CurOp - 2 * HasTwoConditionalOps;
1983 while (RemaningOps) {
1984 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1986 StartByte, CB, Fixups);
1989 CurOp += 2 * HasTwoConditionalOps;
1995 if (CB.
size() - StartByte > 15)
1996 Ctx.reportError(
MI.getLoc(),
"instruction length exceeds the limit of 15");
1999 if ( CurOp != NumOps) {
2000 errs() <<
"Cannot encode all operands of: ";
2010 return new X86MCCodeEmitter(MCII, Ctx);
unsigned const MachineRegisterInfo * MRI
static bool isPCRel(unsigned Kind)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static MCFixupKind getImmFixupKind(uint64_t TSFlags)
static bool isPCRel32Branch(const MCInst &MI, const MCInstrInfo &MCII)
static GlobalOffsetTableExprKind startsWithGlobalOffsetTable(const MCExpr *Expr)
Check if this expression starts with GLOBAL_OFFSET_TABLE and if it is of the form GLOBAL_OFFSET_TABLE...
static uint8_t modRMByte(unsigned Mod, unsigned RegOpcode, unsigned RM)
static bool isDispOrCDisp8(uint64_t TSFlags, int Value, int &ImmOffset)
Determine if this immediate can fit in a disp8 or a compressed disp8 for EVEX instructions.
GlobalOffsetTableExprKind
static void emitConstant(uint64_t Val, unsigned Size, SmallVectorImpl< char > &CB)
static bool hasSecRelSymbolRef(const MCExpr *Expr)
This class represents an Operation in the Expression.
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
MCCodeEmitter - Generic instruction encoding interface.
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
virtual void emitPrefix(const MCInst &Inst, SmallVectorImpl< char > &CB, const MCSubtargetInfo &STI) const
Append the prefixes of given instruction to the code buffer.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
Base class for the full range of assembler expressions which are needed for parsing.
@ SymbolRef
References to labels and assigned expressions.
@ Binary
Binary expressions.
static MCFixupKind getKindForSize(unsigned Size, bool IsPCRel)
Return the generic fixup kind for a value with the given size.
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Instances of this class represent a single low-level machine instruction.
Describe properties that are true of each instruction in the target description file.
Interface to description of machine instruction set.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Instances of this class represent operands of the MCInst class.
static MCOperand createImm(int64_t Val)
unsigned getReg() const
Returns the register number.
const MCExpr * getExpr() const
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
Represent a reference to a symbol from inside an expression.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
StringRef getName() const
getName - Get the symbol name.
Represents a location in source code.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
bool isX32() const
Tests whether the target is X32.
LLVM Value Representation.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Reg
All possible values of the reg field in the ModR/M byte.
bool hasImm(uint64_t TSFlags)
bool hasNewDataDest(uint64_t TSFlags)
@ MRM0X
MRM0X-MRM7X - Instructions that operate that have mod=11 and an opcode but ignore r/m.
@ RawFrm
Raw - This form is for instructions that don't have any operands, so they are just a fixed opcode val...
@ RawFrmDstSrc
RawFrmDstSrc - This form is for instructions that use the source index register SI/ESI/RSI with a pos...
@ EVEX
EVEX - Specifies that this instruction use EVEX form which provides syntax support up to 32 512-bit r...
@ ExplicitREX2Prefix
For instructions that require REX2 prefix even if EGPR is not used.
@ MRMSrcMemCC
MRMSrcMemCC - This form is used for instructions that use the Mod/RM byte to specify the operands and...
@ MRM_C0
MRM_XX (XX: C0-FF)- A mod/rm byte of exactly 0xXX.
@ RawFrmDst
RawFrmDst - This form is for instructions that use the destination index register DI/EDI/RDI.
@ MRMDestMem4VOp3CC
MRMDestMem4VOp3CC - This form is used for instructions that use the Mod/RM byte to specify a destinat...
@ AddCCFrm
AddCCFrm - This form is used for Jcc that encode the condition code in the lower 4 bits of the opcode...
@ T_MAP4
MAP4, MAP5, MAP6, MAP7 - Prefix after the 0x0F prefix.
@ PrefixByte
PrefixByte - This form is used for instructions that represent a prefix byte like data16 or rep.
@ MRMr0
Instructions operate on a register Reg/Opcode operand not the r/m field.
@ MRMXm
MRMXm - This form is used for instructions that use the Mod/RM byte to specify a memory source,...
@ MRM0r
MRM0r-MRM7r - Instructions that operate on a register r/m operand and use reg field to hold extended ...
@ MRMDestMemFSIB
MRMDestMem - But force to use the SIB field.
@ AddRegFrm
AddRegFrm - This form is used for instructions like 'push r32' that have their one register operand a...
@ VEX
VEX - encoding using 0xC4/0xC5.
@ RawFrmImm8
RawFrmImm8 - This is used for the ENTER instruction, which has two immediates, the first of which is ...
@ TB
TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...
@ XOP
XOP - Opcode prefix used by XOP instructions.
@ MRMXr
MRMXr - This form is used for instructions that use the Mod/RM byte to specify a register source,...
@ MRMSrcMem4VOp3
MRMSrcMem4VOp3 - This form is used for instructions that encode operand 3 with VEX....
@ XOP8
XOP8 - Prefix to include use of imm byte.
@ MRMDestRegCC
MRMDestRegCC - This form is used for the cfcmov instructions, which use the Mod/RM byte to specify th...
@ PD
PD - Prefix code for packed double precision vector floating point operations performed in the SSE re...
@ MRMDestMem
MRMDestMem - This form is used for instructions that use the Mod/RM byte to specify a destination,...
@ MRMSrcMemFSIB
MRMSrcMem - But force to use the SIB field.
@ MRMSrcRegOp4
MRMSrcRegOp4 - This form is used for instructions that use the Mod/RM byte to specify the fourth sour...
@ MRMXrCC
MRMXCCr - This form is used for instructions that use the Mod/RM byte to specify a register source,...
@ T8
T8, TA - Prefix after the 0x0F prefix.
@ MRMDestMemCC
MRMDestMemCC - This form is used for the cfcmov instructions, which use the Mod/RM byte to specify th...
@ XOP9
XOP9 - Prefix to exclude use of imm byte.
@ MRMXmCC
MRMXm - This form is used for instructions that use the Mod/RM byte to specify a memory source,...
@ RawFrmImm16
RawFrmImm16 - This is used for CALL FAR instructions, which have two immediates, the first of which i...
@ MRMSrcReg
MRMSrcReg - This form is used for instructions that use the Mod/RM byte to specify a source,...
@ RawFrmSrc
RawFrmSrc - This form is for instructions that use the source index register SI/ESI/RSI with a possib...
@ MRMDestReg
MRMDestReg - This form is used for instructions that use the Mod/RM byte to specify a destination,...
@ MRMSrcMem
MRMSrcMem - This form is used for instructions that use the Mod/RM byte to specify a source,...
@ MRMSrcMemOp4
MRMSrcMemOp4 - This form is used for instructions that use the Mod/RM byte to specify the fourth sour...
@ Pseudo
PseudoFrm - This represents an instruction that is a pseudo instruction or one that has not been impl...
@ CD8_Scale_Shift
The scaling factor for the AVX512's 8-bit compressed displacement.
@ MRMSrcRegCC
MRMSrcRegCC - This form is used for instructions that use the Mod/RM byte to specify the operands and...
@ MRM0m
MRM0m-MRM7m - Instructions that operate on a memory r/m operand and use reg field to hold extended op...
@ ThreeDNow
ThreeDNow - This indicates that the instruction uses the wacky 0x0F 0x0F prefix for 3DNow!...
@ XS
XS, XD - These prefix codes are for single and double precision scalar floating point operations perf...
@ XOPA
XOPA - Prefix to encode 0xA in VEX.MMMM of XOP instructions.
@ MRMSrcReg4VOp3
MRMSrcReg4VOp3 - This form is used for instructions that encode operand 3 with VEX....
@ RawFrmMemOffs
RawFrmMemOffs - This form is for instructions that store an absolute memory offset as an immediate wi...
bool isX86_64NonExtLowByteReg(unsigned reg)
bool needSIB(unsigned BaseReg, unsigned IndexReg, bool In64BitMode)
bool isPseudo(uint64_t TSFlags)
bool isImmPCRel(uint64_t TSFlags)
unsigned getSizeOfImm(uint64_t TSFlags)
Decode the "size of immediate" field from the TSFlags field of the specified instruction.
uint8_t getBaseOpcodeFor(uint64_t TSFlags)
bool isApxExtendedReg(unsigned RegNo)
int getMemoryOperandNo(uint64_t TSFlags)
unsigned getOperandBias(const MCInstrDesc &Desc)
Compute whether all of the def operands are repeated in the uses and therefore should be skipped.
bool isImmSigned(uint64_t TSFlags)
bool is16BitMemOperand(const MCInst &MI, unsigned Op, const MCSubtargetInfo &STI)
bool needsAddressSizeOverride(const MCInst &MI, const MCSubtargetInfo &STI, int MemoryOperand, uint64_t TSFlags)
Returns true if this instruction needs an Address-Size override prefix.
EncodingOfSegmentOverridePrefix getSegmentOverridePrefixForReg(unsigned Reg)
Given a segment register, return the encoding of the segment override prefix for it.
@ reloc_global_offset_table8
@ reloc_signed_4byte_relax
@ reloc_branch_4byte_pcrel
@ reloc_riprel_4byte_relax
@ reloc_riprel_4byte_relax_rex
@ reloc_global_offset_table
@ reloc_riprel_4byte_movq_load
This is an optimization pass for GlobalISel generic memory operations.
MCCodeEmitter * createX86MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
MCFixupKind
Extensible enumeration to represent the type of a fixup.
@ FK_PCRel_4
A four-byte pc relative fixup.
@ FK_PCRel_2
A two-byte pc relative fixup.
@ FK_Data_8
A eight-byte fixup.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_SecRel_4
A four-byte section relative fixup.
@ FK_PCRel_1
A one-byte pc relative fixup.
@ FK_Data_2
A two-byte fixup.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
Description of the encoding of one expression Op.