37#define DEBUG_TYPE "mccodeemitter"
41enum PrefixKind {
None, REX, REX2, XOP, VEX2, VEX3, EVEX };
45class X86OpcodePrefixHelper {
160 unsigned EVEX_L2 : 1;
162 unsigned EVEX_V2 : 1;
163 unsigned EVEX_aaa : 3;
164 PrefixKind Kind =
None;
167 unsigned getRegEncoding(
const MCInst &
MI,
unsigned OpNum)
const {
168 return MRI.getEncodingValue(
MI.getOperand(OpNum).getReg());
171 void setR(
unsigned Encoding) { R = Encoding >> 3 & 1; }
172 void setR2(
unsigned Encoding) {
173 R2 = Encoding >> 4 & 1;
174 assert((!
R2 || (Kind <= REX2 || Kind == EVEX)) &&
"invalid setting");
176 void setX(
unsigned Encoding) {
X = Encoding >> 3 & 1; }
177 void setX2(
unsigned Encoding) {
178 assert((Kind <= REX2 || Kind == EVEX) &&
"invalid setting");
179 X2 = Encoding >> 4 & 1;
181 void setB(
unsigned Encoding) {
B = Encoding >> 3 & 1; }
182 void setB2(
unsigned Encoding) {
183 assert((Kind <= REX2 || Kind == EVEX) &&
"invalid setting");
184 B2 = Encoding >> 4 & 1;
186 void set4V(
unsigned Encoding) { VEX_4V = Encoding & 0xf; }
187 void setV2(
unsigned Encoding) { EVEX_V2 = Encoding >> 4 & 1; }
190 void setW(
bool V) { W = V; }
191 void setR(
const MCInst &
MI,
unsigned OpNum) {
192 setR(getRegEncoding(
MI, OpNum));
194 void setX(
const MCInst &
MI,
unsigned OpNum,
unsigned Shift = 3) {
199 unsigned Encoding =
MRI.getEncodingValue(
Reg);
200 X = Encoding >> Shift & 1;
202 void setB(
const MCInst &
MI,
unsigned OpNum) {
203 B = getRegEncoding(
MI, OpNum) >> 3 & 1;
205 void set4V(
const MCInst &
MI,
unsigned OpNum,
bool IsImm =
false) {
208 set4V(~(
MI.getOperand(OpNum).getImm()));
210 set4V(getRegEncoding(
MI, OpNum));
212 void setL(
bool V) { VEX_L = V; }
213 void setPP(
unsigned V) { VEX_PP = V; }
214 void set5M(
unsigned V) { VEX_5M = V; }
215 void setR2(
const MCInst &
MI,
unsigned OpNum) {
216 setR2(getRegEncoding(
MI, OpNum));
218 void setRR2(
const MCInst &
MI,
unsigned OpNum) {
219 unsigned Encoding = getRegEncoding(
MI, OpNum);
223 void setM(
bool V) { M = V; }
224 void setXX2(
const MCInst &
MI,
unsigned OpNum) {
226 unsigned Encoding =
MRI.getEncodingValue(
Reg);
232 void setBB2(
const MCInst &
MI,
unsigned OpNum) {
234 unsigned Encoding =
MRI.getEncodingValue(
Reg);
240 void setZ(
bool V) { EVEX_z = V; }
241 void setL2(
bool V) { EVEX_L2 = V; }
242 void setEVEX_b(
bool V) { EVEX_b = V; }
243 void setEVEX_U(
bool V) { X2 = V; }
244 void setV2(
const MCInst &
MI,
unsigned OpNum,
bool HasVEX_4V) {
251 setV2(
MRI.getEncodingValue(
Reg));
253 void set4VV2(
const MCInst &
MI,
unsigned OpNum) {
254 unsigned Encoding = getRegEncoding(
MI, OpNum);
258 void setAAA(
const MCInst &
MI,
unsigned OpNum) {
259 EVEX_aaa = getRegEncoding(
MI, OpNum);
261 void setNF(
bool V) { EVEX_aaa |= V << 2; }
262 void setSC(
const MCInst &
MI,
unsigned OpNum) {
263 unsigned Encoding =
MI.getOperand(OpNum).getImm();
264 EVEX_V2 = ~(Encoding >> 3) & 0x1;
265 EVEX_aaa = Encoding & 0x7;
269 : W(0), R(0),
X(0),
B(0), M(0),
R2(0), X2(0), B2(0), VEX_4V(0), VEX_L(0),
270 VEX_PP(0), VEX_5M(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0),
273 void setLowerBound(PrefixKind K) { Kind = K; }
275 PrefixKind determineOptimalKind() {
281 Kind = (
R2 | X2 | B2) ? REX2 : (W | R |
X |
B) ? REX :
None;
284 Kind = (
R2 | X2 | B2) ? REX2 : REX;
292 Kind = (W |
X |
B | (VEX_5M != 1)) ? VEX3 : VEX2;
300 ((~R) & 0x1) << 7 | ((~
X) & 0x1) << 6 | ((
~B) & 0x1) << 5;
301 uint8_t LastPayload = ((~VEX_4V) & 0xf) << 3 | VEX_L << 2 | VEX_PP;
306 emitByte(0x40 | W << 3 | R << 2 |
X << 1 |
B, CB);
310 emitByte(M << 7 |
R2 << 6 | X2 << 5 | B2 << 4 | W << 3 | R << 2 |
X << 1 |
316 emitByte(((~R) & 1) << 7 | LastPayload, CB);
320 emitByte(Kind == VEX3 ? 0xC4 : 0x8F, CB);
321 emitByte(FirstPayload | VEX_5M, CB);
322 emitByte(W << 7 | LastPayload, CB);
325 assert(VEX_5M && !(VEX_5M & 0x8) &&
"invalid mmm fields for EVEX!");
327 emitByte(FirstPayload | ((~
R2) & 0x1) << 4 | B2 << 3 | VEX_5M, CB);
328 emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | ((~X2) & 0x1) << 2 | VEX_PP,
330 emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 |
331 ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa,
344 : MCII(mcii), Ctx(ctx) {}
345 X86MCCodeEmitter(
const X86MCCodeEmitter &) =
delete;
346 X86MCCodeEmitter &operator=(
const X86MCCodeEmitter &) =
delete;
347 ~X86MCCodeEmitter()
override =
default;
357 unsigned getX86RegNum(
const MCOperand &MO)
const;
359 unsigned getX86RegEncoding(
const MCInst &
MI,
unsigned OpNum)
const;
366 void emitRegModRMByte(
const MCOperand &ModRMReg,
unsigned RegOpcodeFld,
369 void emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
372 void emitMemModRMByte(
const MCInst &
MI,
unsigned Op,
unsigned RegOpcodeField,
377 bool ForceSIB =
false)
const;
379 PrefixKind emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
383 PrefixKind emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
387 void emitSegmentOverridePrefix(
unsigned SegOperand,
const MCInst &
MI,
390 PrefixKind emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
394 PrefixKind emitREXPrefix(
int MemOperand,
const MCInst &
MI,
402 assert(
Mod < 4 && RegOpcode < 8 && RM < 8 &&
"ModRM Fields out of range!");
403 return RM | (RegOpcode << 3) | (
Mod << 6);
409 for (
unsigned i = 0; i !=
Size; ++i) {
410 emitByte(Val & 255, CB);
423 CD8_Scale = CD8_Scale ? 1U << (CD8_Scale - 1) : 0U;
424 if (!HasEVEX || !CD8_Scale)
428 if (
Value & (CD8_Scale - 1))
431 int CDisp8 =
Value /
static_cast<int>(CD8_Scale);
436 ImmOffset = CDisp8 -
Value;
490 if (S.
getName() !=
"_GLOBAL_OFFSET_TABLE_")
506 unsigned Opcode =
MI.getOpcode();
508 if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4 &&
509 Opcode != X86::JCC_4) ||
523unsigned X86MCCodeEmitter::getX86RegNum(
const MCOperand &MO)
const {
527unsigned X86MCCodeEmitter::getX86RegEncoding(
const MCInst &
MI,
528 unsigned OpNum)
const {
532void X86MCCodeEmitter::emitImmediate(
const MCOperand &DispOp, SMLoc Loc,
535 SmallVectorImpl<char> &CB,
536 SmallVectorImpl<MCFixup> &Fixups,
537 int ImmOffset)
const {
550 const MCExpr *Expr =
nullptr;
551 if (DispOp.
isImm()) {
579 ImmOffset =
static_cast<int>(CB.
size() - StartByte);
585 const MCBinaryExpr *
Bin =
static_cast<const MCBinaryExpr *
>(Expr);
603void X86MCCodeEmitter::emitRegModRMByte(
const MCOperand &ModRMReg,
604 unsigned RegOpcodeFld,
605 SmallVectorImpl<char> &CB)
const {
606 emitByte(
modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), CB);
609void X86MCCodeEmitter::emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
610 SmallVectorImpl<char> &CB)
const {
615void X86MCCodeEmitter::emitMemModRMByte(
616 const MCInst &
MI,
unsigned Op,
unsigned RegOpcodeField, uint64_t TSFlags,
617 PrefixKind Kind, uint64_t StartByte, SmallVectorImpl<char> &CB,
618 SmallVectorImpl<MCFixup> &Fixups,
const MCSubtargetInfo &STI,
619 bool ForceSIB)
const {
627 if (BaseReg == X86::RIP ||
628 BaseReg == X86::EIP) {
630 "Rip-relative addressing requires 64-bit mode");
631 assert(!IndexReg.
getReg() && !ForceSIB &&
"Invalid rip-relative address");
632 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
634 unsigned Opcode =
MI.getOpcode();
664 case X86::TAILJMPm64:
678 case X86::ADD64rm_NF:
679 case X86::ADD64rm_ND:
680 case X86::ADD64mr_ND:
681 case X86::ADD64mr_NF_ND:
682 case X86::ADD64rm_NF_ND:
698 emitImmediate(Disp,
MI.getLoc(),
FixupKind,
true, StartByte, CB, Fixups,
703 unsigned BaseRegNo =
BaseReg ? getX86RegNum(
Base) : -1U;
705 bool IsAdSize16 = STI.
hasFeature(X86::Is32Bit) &&
723 static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
724 unsigned RMfield = R16Table[BaseRegNo];
726 assert(RMfield &&
"invalid 16-bit base register");
729 unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];
731 assert(IndexReg16 &&
"invalid 16-bit index register");
733 assert(((IndexReg16 ^ RMfield) & 2) &&
734 "invalid 16-bit base/index register combination");
736 "invalid scale for 16-bit memory reference");
740 RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
742 RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
746 if (Disp.
getImm() == 0 && RMfield != 6) {
748 emitByte(
modRMByte(0, RegOpcodeField, RMfield), CB);
752 emitByte(
modRMByte(1, RegOpcodeField, RMfield), CB);
753 emitImmediate(Disp,
MI.getLoc(),
FK_Data_1,
false, StartByte, CB,
758 emitByte(
modRMByte(2, RegOpcodeField, RMfield), CB);
760 assert(!IndexReg.
getReg() &&
"Unexpected index register!");
762 emitByte(
modRMByte(0, RegOpcodeField, 6), CB);
766 emitImmediate(Disp,
MI.getLoc(),
FK_Data_2,
false, StartByte, CB, Fixups);
775 bool AllowNoDisp = !UseDisp8 && !UseDisp32;
777 bool AllowDisp8 = !UseDisp32;
783 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
784 emitImmediate(Disp,
MI.getLoc(),
FK_Data_4,
false, StartByte, CB, Fixups);
794 if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp) {
795 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
806 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
816 if (Disp.
isImm() && AllowDisp8) {
819 emitByte(
modRMByte(1, RegOpcodeField, BaseRegNo), CB);
820 emitImmediate(Disp,
MI.getLoc(),
FK_Data_1,
false, StartByte, CB,
829 emitByte(
modRMByte(2, RegOpcodeField, BaseRegNo), CB);
830 unsigned Opcode =
MI.getOpcode();
840 "Cannot use ESP as index reg!");
842 bool ForceDisp32 =
false;
843 bool ForceDisp8 =
false;
849 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
851 }
else if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp &&
858 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
859 }
else if (Disp.
isImm() && AllowDisp8 &&
864 emitByte(
modRMByte(1, RegOpcodeField, 4), CB);
868 emitByte(
modRMByte(2, RegOpcodeField, 4), CB);
873 static const unsigned SSTable[] = {~0
U, 0, 1, ~0
U, 2, ~0
U, ~0
U, ~0
U, 3};
874 unsigned SS = SSTable[Scale.
getImm()];
876 unsigned IndexRegNo = IndexReg.
getReg() ? getX86RegNum(IndexReg) : 4;
878 emitSIBByte(SS, IndexRegNo, BaseRegNo, CB);
882 emitImmediate(Disp,
MI.getLoc(),
FK_Data_1,
false, StartByte, CB, Fixups,
884 else if (ForceDisp32)
893PrefixKind X86MCCodeEmitter::emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
894 const MCSubtargetInfo &STI,
895 SmallVectorImpl<char> &CB)
const {
900 if (MemoryOperand != -1) {
901 MemoryOperand += CurOp;
906 unsigned Flags =
MI.getFlags();
923 if (
MI.getOperand(2).getReg() != X86::DS)
924 emitSegmentOverridePrefix(2,
MI, CB);
930 if (
MI.getOperand(1).getReg() != X86::DS)
931 emitSegmentOverridePrefix(1,
MI, CB);
941 emitSegmentOverridePrefix(1,
MI, CB);
949 ? emitVEXOpcodePrefix(MemoryOperand,
MI, STI, CB)
950 : emitOpcodePrefix(MemoryOperand,
MI, STI, CB);
967X86MCCodeEmitter::emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
968 const MCSubtargetInfo &STI,
969 SmallVectorImpl<char> &CB)
const {
970 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
971 uint64_t TSFlags =
Desc.TSFlags;
976 unsigned NumOps =
MI.getNumOperands();
979 const MCOperand &MO =
MI.getOperand(
I);
983 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
985 "Cannot encode high byte register in VEX/EVEX-prefixed instruction");
994 Prefix.setLowerBound(XOP);
1001 Prefix.setLowerBound(EVEX);
1066 bool EncodeRC =
false;
1067 uint8_t EVEX_rc = 0;
1109 if (!IsND && HasVEX_4V)
1113 if (HasTwoConditionalOps) {
1141 if (!IsND && HasVEX_4V)
1148 if (HasTwoConditionalOps) {
1193 if (HasTwoConditionalOps) {
1218 if (!IsND && HasVEX_4V)
1225 if (HasTwoConditionalOps) {
1233 unsigned RcOperand =
NumOps - 1;
1234 assert(RcOperand >= CurOp);
1235 EVEX_rc =
MI.getOperand(RcOperand).getImm();
1236 assert(EVEX_rc <= 3 &&
"Invalid rounding control!");
1280 if (!IsND && HasVEX_4V)
1284 if (HasTwoConditionalOps) {
1319 if (HasTwoConditionalOps) {
1327 Prefix.setL(EVEX_rc & 0x1);
1328 Prefix.setL2(EVEX_rc & 0x2);
1330 PrefixKind
Kind =
Prefix.determineOptimalKind();
1341PrefixKind X86MCCodeEmitter::emitREXPrefix(
int MemOperand,
const MCInst &
MI,
1342 const MCSubtargetInfo &STI,
1343 SmallVectorImpl<char> &CB)
const {
1347 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
1348 uint64_t TSFlags =
Desc.TSFlags;
1350 unsigned NumOps =
MI.getNumOperands();
1351 bool UsesHighByteReg =
false;
1353 bool HasRegOp =
false;
1356 for (
unsigned i = CurOp; i !=
NumOps; ++i) {
1357 const MCOperand &MO =
MI.getOperand(i);
1363 if (
Reg == X86::AH ||
Reg == X86::BH ||
Reg == X86::CH ||
Reg == X86::DH)
1364 UsesHighByteReg =
true;
1367 Prefix.setLowerBound(REX);
1377 Prefix.setLowerBound(REX);
1382 Prefix.setLowerBound(REX);
1385 Prefix.setLowerBound(REX2);
1388 assert(!HasRegOp &&
"Unexpected form in emitREXPrefix!");
1448 PrefixKind
Kind =
Prefix.determineOptimalKind();
1449 if (Kind && UsesHighByteReg)
1451 "Cannot encode high byte register in REX-prefixed instruction");
1457void X86MCCodeEmitter::emitSegmentOverridePrefix(
1458 unsigned SegOperand,
const MCInst &
MI, SmallVectorImpl<char> &CB)
const {
1460 if (MCRegister
Reg =
MI.getOperand(SegOperand).getReg())
1470PrefixKind X86MCCodeEmitter::emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
1471 const MCSubtargetInfo &STI,
1472 SmallVectorImpl<char> &CB)
const {
1473 const MCInstrDesc &
Desc = MCII.
get(
MI.getOpcode());
1474 uint64_t TSFlags =
Desc.TSFlags;
1503 "REX.W requires 64bit mode.");
1504 PrefixKind
Kind = emitREXPrefix(MemOperand,
MI, STI, CB);
1532void X86MCCodeEmitter::emitPrefix(
const MCInst &
MI, SmallVectorImpl<char> &CB,
1533 const MCSubtargetInfo &STI)
const {
1534 unsigned Opcode =
MI.getOpcode();
1535 const MCInstrDesc &
Desc = MCII.
get(Opcode);
1536 uint64_t TSFlags =
Desc.TSFlags;
1544 emitPrefixImpl(CurOp,
MI, STI, CB);
1549 static_cast<X86MCCodeEmitter &
>(MCE).
emitPrefix(
MI, CB, STI);
1552void X86MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
1556 unsigned Opcode =
MI.getOpcode();
1569 PrefixKind Kind = emitPrefixImpl(CurOp,
MI, STI, CB);
1580 unsigned I8RegNum = 0;
1587 unsigned OpcodeOffset = 0;
1595 errs() <<
"FORM: " << Form <<
"\n";
1603 emitByte(BaseOpcode, CB);
1607 OpcodeOffset =
MI.getOperand(
NumOps - 1).getImm();
1608 assert(OpcodeOffset < 16 &&
"Unexpected opcode offset!");
1612 emitByte(BaseOpcode + OpcodeOffset, CB);
1619 StartByte, CB, Fixups);
1623 emitByte(BaseOpcode, CB);
1629 emitByte(BaseOpcode, CB);
1632 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
FK_Data_1,
false,
1633 StartByte, CB, Fixups);
1636 emitByte(BaseOpcode, CB);
1639 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
FK_Data_2,
false,
1640 StartByte, CB, Fixups);
1644 emitByte(BaseOpcode + getX86RegNum(
MI.getOperand(CurOp++)), CB);
1648 emitByte(BaseOpcode, CB);
1649 unsigned SrcRegNum = CurOp + 1;
1659 emitRegModRMByte(
MI.getOperand(CurOp),
1660 getX86RegNum(
MI.getOperand(SrcRegNum)), CB);
1661 CurOp = SrcRegNum + 1;
1665 unsigned FirstOp = CurOp++;
1666 unsigned SecondOp = CurOp++;
1667 unsigned CC =
MI.getOperand(CurOp++).getImm();
1668 emitByte(BaseOpcode + CC, CB);
1669 emitRegModRMByte(
MI.getOperand(FirstOp),
1670 getX86RegNum(
MI.getOperand(SecondOp)), CB);
1674 unsigned CC =
MI.getOperand(8).getImm();
1675 emitByte(BaseOpcode + CC, CB);
1677 emitMemModRMByte(
MI, CurOp + 1, getX86RegNum(
MI.getOperand(0)), TSFlags,
1678 Kind, StartByte, CB, Fixups, STI,
false);
1679 CurOp = SrcRegNum + 3;
1684 emitByte(BaseOpcode, CB);
1697 emitMemModRMByte(
MI, CurOp, getX86RegNum(
MI.getOperand(SrcRegNum)), TSFlags,
1698 Kind, StartByte, CB, Fixups, STI, ForceSIB);
1699 CurOp = SrcRegNum + 1;
1703 unsigned MemOp = CurOp;
1705 unsigned RegOp = CurOp++;
1706 unsigned CC =
MI.getOperand(CurOp++).getImm();
1707 emitByte(BaseOpcode + CC, CB);
1708 emitMemModRMByte(
MI, MemOp, getX86RegNum(
MI.getOperand(RegOp)), TSFlags,
1709 Kind, StartByte, CB, Fixups, STI);
1713 emitByte(BaseOpcode, CB);
1714 unsigned SrcRegNum = CurOp + 1;
1725 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1726 getX86RegNum(
MI.getOperand(CurOp)), CB);
1727 CurOp = SrcRegNum + 1;
1729 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1736 emitByte(BaseOpcode, CB);
1737 unsigned SrcRegNum = CurOp + 1;
1739 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1740 getX86RegNum(
MI.getOperand(CurOp)), CB);
1741 CurOp = SrcRegNum + 1;
1746 emitByte(BaseOpcode, CB);
1747 unsigned SrcRegNum = CurOp + 1;
1753 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1754 I8RegNum = getX86RegEncoding(
MI, SrcRegNum++);
1756 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1757 getX86RegNum(
MI.getOperand(CurOp)), CB);
1758 CurOp = SrcRegNum + 1;
1764 unsigned FirstOp = CurOp++;
1765 unsigned SecondOp = CurOp++;
1767 unsigned CC =
MI.getOperand(CurOp++).getImm();
1768 emitByte(BaseOpcode + CC, CB);
1770 emitRegModRMByte(
MI.getOperand(SecondOp),
1771 getX86RegNum(
MI.getOperand(FirstOp)), CB);
1776 unsigned FirstMemOp = CurOp + 1;
1787 emitByte(BaseOpcode, CB);
1790 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1791 TSFlags, Kind, StartByte, CB, Fixups, STI, ForceSIB);
1794 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1798 unsigned FirstMemOp = CurOp + 1;
1800 emitByte(BaseOpcode, CB);
1802 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1803 TSFlags, Kind, StartByte, CB, Fixups, STI);
1809 unsigned FirstMemOp = CurOp + 1;
1814 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1815 I8RegNum = getX86RegEncoding(
MI, FirstMemOp++);
1817 emitByte(BaseOpcode, CB);
1819 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1820 TSFlags, Kind, StartByte, CB, Fixups, STI);
1827 unsigned RegOp = CurOp++;
1828 unsigned FirstMemOp = CurOp;
1831 unsigned CC =
MI.getOperand(CurOp++).getImm();
1832 emitByte(BaseOpcode + CC, CB);
1834 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(RegOp)),
1835 TSFlags, Kind, StartByte, CB, Fixups, STI);
1840 unsigned RegOp = CurOp++;
1842 unsigned CC =
MI.getOperand(CurOp++).getImm();
1843 emitByte(BaseOpcode + CC, CB);
1844 emitRegModRMByte(
MI.getOperand(RegOp), 0, CB);
1861 emitByte(BaseOpcode, CB);
1862 emitRegModRMByte(
MI.getOperand(CurOp++),
1866 emitByte(BaseOpcode, CB);
1867 emitByte(
modRMByte(3, getX86RegNum(
MI.getOperand(CurOp++)), 0), CB);
1871 unsigned FirstMemOp = CurOp;
1874 unsigned CC =
MI.getOperand(CurOp++).getImm();
1875 emitByte(BaseOpcode + CC, CB);
1877 emitMemModRMByte(
MI, FirstMemOp, 0, TSFlags, Kind, StartByte, CB, Fixups,
1895 emitByte(BaseOpcode, CB);
1896 emitMemModRMByte(
MI, CurOp,
1898 Kind, StartByte, CB, Fixups, STI);
1910 emitByte(BaseOpcode, CB);
1978 emitByte(BaseOpcode, CB);
1986 assert(I8RegNum < 16 &&
"Register encoding out of range");
1989 unsigned Val =
MI.getOperand(CurOp++).getImm();
1990 assert(Val < 16 &&
"Immediate operand value out of range");
1994 StartByte, CB, Fixups);
2001 unsigned RemainingOps =
NumOps - CurOp - 2 * HasTwoConditionalOps;
2002 while (RemainingOps) {
2003 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
2008 CurOp += 2 * HasTwoConditionalOps;
2014 if (CB.
size() - StartByte > 15)
2015 Ctx.
reportError(
MI.getLoc(),
"instruction length exceeds the limit of 15");
2019 errs() <<
"Cannot encode all operands of: ";
2029 return new X86MCCodeEmitter(MCII, Ctx);
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton 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.
@ C
The default llvm calling convention, compatible with C.
bool hasImm(uint64_t TSFlags)
bool hasNewDataDest(uint64_t TSFlags)
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)
int getMemoryOperandNo(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.