36#define DEBUG_TYPE "mccodeemitter"
40enum PrefixKind {
None, REX, REX2, XOP, VEX2, VEX3, EVEX };
44class X86OpcodePrefixHelper {
159 unsigned EVEX_L2 : 1;
161 unsigned EVEX_V2 : 1;
162 unsigned EVEX_aaa : 3;
163 PrefixKind Kind =
None;
166 unsigned getRegEncoding(
const MCInst &
MI,
unsigned OpNum)
const {
170 void setR(
unsigned Encoding) { R = Encoding >> 3 & 1; }
171 void setR2(
unsigned Encoding) {
172 R2 = Encoding >> 4 & 1;
173 assert((!
R2 || (Kind <= REX2 || Kind == EVEX)) &&
"invalid setting");
175 void setX(
unsigned Encoding) {
X = Encoding >> 3 & 1; }
176 void setX2(
unsigned Encoding) {
177 assert((Kind <= REX2 || Kind == EVEX) &&
"invalid setting");
178 X2 = Encoding >> 4 & 1;
180 void setB(
unsigned Encoding) {
B = Encoding >> 3 & 1; }
181 void setB2(
unsigned Encoding) {
182 assert((Kind <= REX2 || Kind == EVEX) &&
"invalid setting");
183 B2 = Encoding >> 4 & 1;
185 void set4V(
unsigned Encoding) { VEX_4V = Encoding & 0xf; }
186 void setV2(
unsigned Encoding) { EVEX_V2 = Encoding >> 4 & 1; }
189 void setW(
bool V) { W = V; }
190 void setR(
const MCInst &
MI,
unsigned OpNum) {
191 setR(getRegEncoding(
MI, OpNum));
193 void setX(
const MCInst &
MI,
unsigned OpNum,
unsigned Shift = 3) {
199 X = Encoding >> Shift & 1;
201 void setB(
const MCInst &
MI,
unsigned OpNum) {
202 B = getRegEncoding(
MI, OpNum) >> 3 & 1;
204 void set4V(
const MCInst &
MI,
unsigned OpNum,
bool IsImm =
false) {
207 set4V(~(
MI.getOperand(OpNum).getImm()));
209 set4V(getRegEncoding(
MI, OpNum));
211 void setL(
bool V) { VEX_L = V; }
212 void setPP(
unsigned V) { VEX_PP = V; }
213 void set5M(
unsigned V) { VEX_5M = V; }
214 void setR2(
const MCInst &
MI,
unsigned OpNum) {
215 setR2(getRegEncoding(
MI, OpNum));
217 void setRR2(
const MCInst &
MI,
unsigned OpNum) {
218 unsigned Encoding = getRegEncoding(
MI, OpNum);
222 void setM(
bool V) { M = V; }
223 void setXX2(
const MCInst &
MI,
unsigned OpNum) {
231 void setBB2(
const MCInst &
MI,
unsigned OpNum) {
239 void setZ(
bool V) { EVEX_z = V; }
240 void setL2(
bool V) { EVEX_L2 = V; }
241 void setEVEX_b(
bool V) { EVEX_b = V; }
242 void setEVEX_U(
bool V) { X2 = V; }
243 void setV2(
const MCInst &
MI,
unsigned OpNum,
bool HasVEX_4V) {
252 void set4VV2(
const MCInst &
MI,
unsigned OpNum) {
253 unsigned Encoding = getRegEncoding(
MI, OpNum);
257 void setAAA(
const MCInst &
MI,
unsigned OpNum) {
258 EVEX_aaa = getRegEncoding(
MI, OpNum);
260 void setNF(
bool V) { EVEX_aaa |= V << 2; }
261 void setSC(
const MCInst &
MI,
unsigned OpNum) {
262 unsigned Encoding =
MI.getOperand(OpNum).getImm();
263 EVEX_V2 = ~(Encoding >> 3) & 0x1;
264 EVEX_aaa = Encoding & 0x7;
268 : W(0), R(0),
X(0),
B(0), M(0),
R2(0), X2(0), B2(0), VEX_4V(0), VEX_L(0),
269 VEX_PP(0), VEX_5M(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0),
270 EVEX_aaa(0), MRI(MRI) {}
272 void setLowerBound(PrefixKind K) { Kind = K; }
274 PrefixKind determineOptimalKind() {
280 Kind = (
R2 | X2 | B2) ? REX2 : (W | R |
X |
B) ? REX :
None;
283 Kind = (
R2 | X2 | B2) ? REX2 : REX;
291 Kind = (W |
X |
B | (VEX_5M != 1)) ? VEX3 : VEX2;
299 ((~R) & 0x1) << 7 | ((~
X) & 0x1) << 6 | ((
~B) & 0x1) << 5;
300 uint8_t LastPayload = ((~VEX_4V) & 0xf) << 3 | VEX_L << 2 | VEX_PP;
305 emitByte(0x40 | W << 3 | R << 2 |
X << 1 |
B, CB);
309 emitByte(M << 7 |
R2 << 6 | X2 << 5 | B2 << 4 | W << 3 | R << 2 |
X << 1 |
315 emitByte(((~R) & 1) << 7 | LastPayload, CB);
319 emitByte(Kind == VEX3 ? 0xC4 : 0x8F, CB);
320 emitByte(FirstPayload | VEX_5M, CB);
321 emitByte(W << 7 | LastPayload, CB);
324 assert(VEX_5M && !(VEX_5M & 0x8) &&
"invalid mmm fields for EVEX!");
326 emitByte(FirstPayload | ((~
R2) & 0x1) << 4 | B2 << 3 | VEX_5M, CB);
327 emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | ((~X2) & 0x1) << 2 | VEX_PP,
329 emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 |
330 ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa,
343 : MCII(mcii), Ctx(ctx) {}
344 X86MCCodeEmitter(
const X86MCCodeEmitter &) =
delete;
345 X86MCCodeEmitter &operator=(
const X86MCCodeEmitter &) =
delete;
346 ~X86MCCodeEmitter()
override =
default;
356 unsigned getX86RegNum(
const MCOperand &MO)
const;
358 unsigned getX86RegEncoding(
const MCInst &
MI,
unsigned OpNum)
const;
365 void emitRegModRMByte(
const MCOperand &ModRMReg,
unsigned RegOpcodeFld,
368 void emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
371 void emitMemModRMByte(
const MCInst &
MI,
unsigned Op,
unsigned RegOpcodeField,
376 bool ForceSIB =
false)
const;
381 PrefixKind emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
385 void emitSegmentOverridePrefix(
unsigned SegOperand,
const MCInst &
MI,
388 PrefixKind emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
392 PrefixKind emitREXPrefix(
int MemOperand,
const MCInst &
MI,
400 assert(
Mod < 4 && RegOpcode < 8 && RM < 8 &&
"ModRM Fields out of range!");
401 return RM | (RegOpcode << 3) | (
Mod << 6);
407 for (
unsigned i = 0; i !=
Size; ++i) {
408 emitByte(Val & 255, CB);
421 CD8_Scale = CD8_Scale ? 1U << (CD8_Scale - 1) : 0U;
422 if (!HasEVEX || !CD8_Scale)
426 if (
Value & (CD8_Scale - 1))
429 int CDisp8 =
Value /
static_cast<int>(CD8_Scale);
434 ImmOffset = CDisp8 -
Value;
488 if (S.
getName() !=
"_GLOBAL_OFFSET_TABLE_")
504 unsigned Opcode =
MI.getOpcode();
506 if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4 &&
507 Opcode != X86::JCC_4) ||
521unsigned X86MCCodeEmitter::getX86RegNum(
const MCOperand &MO)
const {
525unsigned X86MCCodeEmitter::getX86RegEncoding(
const MCInst &
MI,
526 unsigned OpNum)
const {
530void X86MCCodeEmitter::emitImmediate(
const MCOperand &DispOp, SMLoc Loc,
533 SmallVectorImpl<char> &CB,
534 SmallVectorImpl<MCFixup> &Fixups,
535 int ImmOffset)
const {
548 const MCExpr *Expr =
nullptr;
549 if (DispOp.
isImm()) {
577 ImmOffset =
static_cast<int>(CB.
size() - StartByte);
583 const MCBinaryExpr *
Bin =
static_cast<const MCBinaryExpr *
>(Expr);
601void X86MCCodeEmitter::emitRegModRMByte(
const MCOperand &ModRMReg,
602 unsigned RegOpcodeFld,
603 SmallVectorImpl<char> &CB)
const {
604 emitByte(
modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), CB);
607void X86MCCodeEmitter::emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
608 SmallVectorImpl<char> &CB)
const {
613void X86MCCodeEmitter::emitMemModRMByte(
614 const MCInst &
MI,
unsigned Op,
unsigned RegOpcodeField,
uint64_t TSFlags,
615 PrefixKind Kind,
uint64_t StartByte, SmallVectorImpl<char> &CB,
616 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI,
617 bool ForceSIB)
const {
625 if (BaseReg == X86::RIP ||
626 BaseReg == X86::EIP) {
628 "Rip-relative addressing requires 64-bit mode");
629 assert(!IndexReg.
getReg() && !ForceSIB &&
"Invalid rip-relative address");
630 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
632 unsigned Opcode =
MI.getOpcode();
662 case X86::TAILJMPm64:
676 case X86::ADD64rm_NF:
677 case X86::ADD64rm_ND:
678 case X86::ADD64mr_ND:
679 case X86::ADD64mr_NF_ND:
680 case X86::ADD64rm_NF_ND:
696 emitImmediate(Disp,
MI.getLoc(),
FixupKind,
true, StartByte, CB, Fixups,
701 unsigned BaseRegNo =
BaseReg ? getX86RegNum(
Base) : -1U;
703 bool IsAdSize16 = STI.
hasFeature(X86::Is32Bit) &&
721 static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
722 unsigned RMfield = R16Table[BaseRegNo];
724 assert(RMfield &&
"invalid 16-bit base register");
727 unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];
729 assert(IndexReg16 &&
"invalid 16-bit index register");
731 assert(((IndexReg16 ^ RMfield) & 2) &&
732 "invalid 16-bit base/index register combination");
734 "invalid scale for 16-bit memory reference");
738 RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
740 RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
744 if (Disp.
getImm() == 0 && RMfield != 6) {
746 emitByte(
modRMByte(0, RegOpcodeField, RMfield), CB);
750 emitByte(
modRMByte(1, RegOpcodeField, RMfield), CB);
751 emitImmediate(Disp,
MI.getLoc(),
FK_Data_1,
false, StartByte, CB,
756 emitByte(
modRMByte(2, RegOpcodeField, RMfield), CB);
758 assert(!IndexReg.
getReg() &&
"Unexpected index register!");
760 emitByte(
modRMByte(0, RegOpcodeField, 6), CB);
764 emitImmediate(Disp,
MI.getLoc(),
FK_Data_2,
false, StartByte, CB, Fixups);
773 bool AllowNoDisp = !UseDisp8 && !UseDisp32;
775 bool AllowDisp8 = !UseDisp32;
781 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
782 emitImmediate(Disp,
MI.getLoc(),
FK_Data_4,
false, StartByte, CB, Fixups);
792 if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp) {
793 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
804 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
814 if (Disp.
isImm() && AllowDisp8) {
817 emitByte(
modRMByte(1, RegOpcodeField, BaseRegNo), CB);
818 emitImmediate(Disp,
MI.getLoc(),
FK_Data_1,
false, StartByte, CB,
827 emitByte(
modRMByte(2, RegOpcodeField, BaseRegNo), CB);
828 unsigned Opcode =
MI.getOpcode();
838 "Cannot use ESP as index reg!");
840 bool ForceDisp32 =
false;
841 bool ForceDisp8 =
false;
847 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
849 }
else if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp &&
856 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
857 }
else if (Disp.
isImm() && AllowDisp8 &&
862 emitByte(
modRMByte(1, RegOpcodeField, 4), CB);
866 emitByte(
modRMByte(2, RegOpcodeField, 4), CB);
871 static const unsigned SSTable[] = {~0
U, 0, 1, ~0
U, 2, ~0
U, ~0
U, ~0
U, 3};
872 unsigned SS = SSTable[Scale.
getImm()];
874 unsigned IndexRegNo = IndexReg.
getReg() ? getX86RegNum(IndexReg) : 4;
876 emitSIBByte(SS, IndexRegNo, BaseRegNo, CB);
880 emitImmediate(Disp,
MI.getLoc(),
FK_Data_1,
false, StartByte, CB, Fixups,
882 else if (ForceDisp32)
891PrefixKind X86MCCodeEmitter::emitPrefixImpl(
const MCInst &
MI,
892 const MCSubtargetInfo &STI,
893 SmallVectorImpl<char> &CB)
const {
894 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
899 if (MemoryOperand != -1)
903 unsigned Flags =
MI.getFlags();
920 if (
MI.getOperand(2).getReg() != X86::DS)
921 emitSegmentOverridePrefix(2,
MI, CB);
925 if (
MI.getOperand(1).getReg() != X86::DS)
926 emitSegmentOverridePrefix(1,
MI, CB);
930 emitSegmentOverridePrefix(1,
MI, CB);
937 ? emitVEXOpcodePrefix(MemoryOperand,
MI, STI, CB)
938 : emitOpcodePrefix(MemoryOperand,
MI, STI, CB);
955X86MCCodeEmitter::emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
956 const MCSubtargetInfo &STI,
957 SmallVectorImpl<char> &CB)
const {
958 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
964 unsigned NumOps =
MI.getNumOperands();
967 const MCOperand &MO =
MI.getOperand(
I);
971 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
973 "Cannot encode high byte register in VEX/EVEX-prefixed instruction");
982 Prefix.setLowerBound(XOP);
989 Prefix.setLowerBound(EVEX);
1054 bool EncodeRC =
false;
1055 uint8_t EVEX_rc = 0;
1097 if (!IsND && HasVEX_4V)
1101 if (HasTwoConditionalOps) {
1129 if (!IsND && HasVEX_4V)
1136 if (HasTwoConditionalOps) {
1181 if (HasTwoConditionalOps) {
1206 if (!IsND && HasVEX_4V)
1213 if (HasTwoConditionalOps) {
1221 unsigned RcOperand =
NumOps - 1;
1222 assert(RcOperand >= CurOp);
1223 EVEX_rc =
MI.getOperand(RcOperand).getImm();
1224 assert(EVEX_rc <= 3 &&
"Invalid rounding control!");
1268 if (!IsND && HasVEX_4V)
1272 if (HasTwoConditionalOps) {
1307 if (HasTwoConditionalOps) {
1315 Prefix.setL(EVEX_rc & 0x1);
1316 Prefix.setL2(EVEX_rc & 0x2);
1318 PrefixKind
Kind =
Prefix.determineOptimalKind();
1329PrefixKind X86MCCodeEmitter::emitREXPrefix(
int MemOperand,
const MCInst &
MI,
1330 const MCSubtargetInfo &STI,
1331 SmallVectorImpl<char> &CB)
const {
1335 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
1338 unsigned NumOps =
MI.getNumOperands();
1339 bool UsesHighByteReg =
false;
1341 bool HasRegOp =
false;
1344 for (
unsigned i = CurOp; i !=
NumOps; ++i) {
1345 const MCOperand &MO =
MI.getOperand(i);
1351 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
1352 UsesHighByteReg =
true;
1355 Prefix.setLowerBound(REX);
1365 Prefix.setLowerBound(REX);
1370 Prefix.setLowerBound(REX);
1373 Prefix.setLowerBound(REX2);
1376 assert(!HasRegOp &&
"Unexpected form in emitREXPrefix!");
1436 PrefixKind
Kind =
Prefix.determineOptimalKind();
1437 if (Kind && UsesHighByteReg)
1439 "Cannot encode high byte register in REX-prefixed instruction");
1445void X86MCCodeEmitter::emitSegmentOverridePrefix(
1446 unsigned SegOperand,
const MCInst &
MI, SmallVectorImpl<char> &CB)
const {
1448 if (MCRegister
Reg =
MI.getOperand(SegOperand).getReg())
1458PrefixKind X86MCCodeEmitter::emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
1459 const MCSubtargetInfo &STI,
1460 SmallVectorImpl<char> &CB)
const {
1461 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
1491 "REX.W requires 64bit mode.");
1492 PrefixKind
Kind = emitREXPrefix(MemOperand,
MI, STI, CB);
1520void X86MCCodeEmitter::emitPrefix(
const MCInst &
MI, SmallVectorImpl<char> &CB,
1521 const MCSubtargetInfo &STI)
const {
1528 emitPrefixImpl(
MI, STI, CB);
1533 static_cast<X86MCCodeEmitter &
>(MCE).
emitPrefix(
MI, CB, STI);
1536void X86MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
1540 unsigned Opcode =
MI.getOpcode();
1542 uint64_t TSFlags =
Desc.TSFlags;
1551 uint64_t StartByte = CB.
size();
1553 PrefixKind Kind = emitPrefixImpl(
MI, STI, CB);
1564 unsigned I8RegNum = 0;
1571 unsigned OpcodeOffset = 0;
1579 errs() <<
"FORM: " << Form <<
"\n";
1584 emitByte(BaseOpcode, CB);
1588 emitByte(BaseOpcode, CB);
1592 emitByte(BaseOpcode, CB);
1596 emitByte(BaseOpcode, CB);
1600 OpcodeOffset =
MI.getOperand(
NumOps - 1).getImm();
1601 assert(OpcodeOffset < 16 &&
"Unexpected opcode offset!");
1605 emitByte(BaseOpcode + OpcodeOffset, CB);
1612 StartByte, CB, Fixups);
1616 emitByte(BaseOpcode, CB);
1622 emitByte(BaseOpcode, CB);
1625 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
FK_Data_1,
false,
1626 StartByte, CB, Fixups);
1629 emitByte(BaseOpcode, CB);
1632 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
FK_Data_2,
false,
1633 StartByte, CB, Fixups);
1637 emitByte(BaseOpcode + getX86RegNum(
MI.getOperand(CurOp++)), CB);
1641 emitByte(BaseOpcode, CB);
1642 unsigned SrcRegNum = CurOp + 1;
1652 emitRegModRMByte(
MI.getOperand(CurOp),
1653 getX86RegNum(
MI.getOperand(SrcRegNum)), CB);
1654 CurOp = SrcRegNum + 1;
1658 unsigned FirstOp = CurOp++;
1659 unsigned SecondOp = CurOp++;
1660 unsigned CC =
MI.getOperand(CurOp++).getImm();
1661 emitByte(BaseOpcode + CC, CB);
1662 emitRegModRMByte(
MI.getOperand(FirstOp),
1663 getX86RegNum(
MI.getOperand(SecondOp)), CB);
1667 unsigned CC =
MI.getOperand(8).getImm();
1668 emitByte(BaseOpcode + CC, CB);
1670 emitMemModRMByte(
MI, CurOp + 1, getX86RegNum(
MI.getOperand(0)), TSFlags,
1671 Kind, StartByte, CB, Fixups, STI,
false);
1672 CurOp = SrcRegNum + 3;
1677 emitByte(BaseOpcode, CB);
1690 emitMemModRMByte(
MI, CurOp, getX86RegNum(
MI.getOperand(SrcRegNum)), TSFlags,
1691 Kind, StartByte, CB, Fixups, STI, ForceSIB);
1692 CurOp = SrcRegNum + 1;
1696 unsigned MemOp = CurOp;
1698 unsigned RegOp = CurOp++;
1699 unsigned CC =
MI.getOperand(CurOp++).getImm();
1700 emitByte(BaseOpcode + CC, CB);
1701 emitMemModRMByte(
MI, MemOp, getX86RegNum(
MI.getOperand(RegOp)), TSFlags,
1702 Kind, StartByte, CB, Fixups, STI);
1706 emitByte(BaseOpcode, CB);
1707 unsigned SrcRegNum = CurOp + 1;
1718 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1719 getX86RegNum(
MI.getOperand(CurOp)), CB);
1720 CurOp = SrcRegNum + 1;
1722 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1729 emitByte(BaseOpcode, CB);
1730 unsigned SrcRegNum = CurOp + 1;
1732 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1733 getX86RegNum(
MI.getOperand(CurOp)), CB);
1734 CurOp = SrcRegNum + 1;
1739 emitByte(BaseOpcode, CB);
1740 unsigned SrcRegNum = CurOp + 1;
1746 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1747 I8RegNum = getX86RegEncoding(
MI, SrcRegNum++);
1749 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1750 getX86RegNum(
MI.getOperand(CurOp)), CB);
1751 CurOp = SrcRegNum + 1;
1757 unsigned FirstOp = CurOp++;
1758 unsigned SecondOp = CurOp++;
1760 unsigned CC =
MI.getOperand(CurOp++).getImm();
1761 emitByte(BaseOpcode + CC, CB);
1763 emitRegModRMByte(
MI.getOperand(SecondOp),
1764 getX86RegNum(
MI.getOperand(FirstOp)), CB);
1769 unsigned FirstMemOp = CurOp + 1;
1780 emitByte(BaseOpcode, CB);
1783 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1784 TSFlags, Kind, StartByte, CB, Fixups, STI, ForceSIB);
1787 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1791 unsigned FirstMemOp = CurOp + 1;
1793 emitByte(BaseOpcode, CB);
1795 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1796 TSFlags, Kind, StartByte, CB, Fixups, STI);
1802 unsigned FirstMemOp = CurOp + 1;
1807 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1808 I8RegNum = getX86RegEncoding(
MI, FirstMemOp++);
1810 emitByte(BaseOpcode, CB);
1812 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1813 TSFlags, Kind, StartByte, CB, Fixups, STI);
1820 unsigned RegOp = CurOp++;
1821 unsigned FirstMemOp = CurOp;
1824 unsigned CC =
MI.getOperand(CurOp++).getImm();
1825 emitByte(BaseOpcode + CC, CB);
1827 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(RegOp)),
1828 TSFlags, Kind, StartByte, CB, Fixups, STI);
1833 unsigned RegOp = CurOp++;
1835 unsigned CC =
MI.getOperand(CurOp++).getImm();
1836 emitByte(BaseOpcode + CC, CB);
1837 emitRegModRMByte(
MI.getOperand(RegOp), 0, CB);
1854 emitByte(BaseOpcode, CB);
1855 emitRegModRMByte(
MI.getOperand(CurOp++),
1859 emitByte(BaseOpcode, CB);
1860 emitByte(
modRMByte(3, getX86RegNum(
MI.getOperand(CurOp++)), 0), CB);
1864 unsigned FirstMemOp = CurOp;
1867 unsigned CC =
MI.getOperand(CurOp++).getImm();
1868 emitByte(BaseOpcode + CC, CB);
1870 emitMemModRMByte(
MI, FirstMemOp, 0, TSFlags, Kind, StartByte, CB, Fixups,
1888 emitByte(BaseOpcode, CB);
1889 emitMemModRMByte(
MI, CurOp,
1891 Kind, StartByte, CB, Fixups, STI);
1903 emitByte(BaseOpcode, CB);
1971 emitByte(BaseOpcode, CB);
1979 assert(I8RegNum < 16 &&
"Register encoding out of range");
1982 unsigned Val =
MI.getOperand(CurOp++).getImm();
1983 assert(Val < 16 &&
"Immediate operand value out of range");
1987 StartByte, CB, Fixups);
1994 unsigned RemainingOps =
NumOps - CurOp - 2 * HasTwoConditionalOps;
2002 "TSFlags indicates immediate but no operand provides it");
2003 while (RemainingOps) {
2004 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
2009 CurOp += 2 * HasTwoConditionalOps;
2015 if (CB.
size() - StartByte > 15)
2016 Ctx.
reportError(
MI.getLoc(),
"instruction length exceeds the limit of 15");
2020 errs() <<
"Cannot encode all operands of: ";
2030 return new X86MCCodeEmitter(MCII, Ctx);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
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)
Binary assembler expressions.
const MCExpr * getLHS() const
Get the left-hand side expression of the binary operator.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
const MCExpr * getRHS() const
Get the right-hand side expression of the binary operator.
MCCodeEmitter - Generic instruction encoding interface.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
const MCRegisterInfo * getRegisterInfo() const
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
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 MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
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)
MCRegister 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...
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Wrapper class representing physical registers. Should be passed by value.
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.
bool hasImm(uint64_t TSFlags)
bool hasNewDataDest(uint64_t TSFlags)
int getMemoryOperandIdx(const MCInstrDesc &Desc)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
@ 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 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.
bool needSIB(MCRegister BaseReg, MCRegister IndexReg, bool In64BitMode)
uint8_t getBaseOpcodeFor(uint64_t TSFlags)
bool isApxExtendedReg(MCRegister Reg)
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.
void emitPrefix(MCCodeEmitter &MCE, const MCInst &MI, SmallVectorImpl< char > &CB, const MCSubtargetInfo &STI)
EncodingOfSegmentOverridePrefix getSegmentOverridePrefixForReg(MCRegister Reg)
Given a segment register, return the encoding of the segment override prefix for it.
@ reloc_riprel_4byte_movq_load_rex2
@ reloc_signed_4byte_relax
@ reloc_branch_4byte_pcrel
@ reloc_riprel_4byte_relax
@ reloc_riprel_4byte_relax_evex
@ reloc_riprel_4byte_relax_rex
@ reloc_global_offset_table
@ reloc_riprel_4byte_movq_load
@ reloc_riprel_4byte_relax_rex2
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
MCCodeEmitter * createX86MCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
static Lanai::Fixups FixupKind(const MCExpr *Expr)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI 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.
@ FirstLiteralRelocationKind
@ 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_Data_2
A two-byte fixup.
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.