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 setEVEX_U(
bool V) { X2 = V; }
242 void setV2(
const MCInst &
MI,
unsigned OpNum,
bool HasVEX_4V) {
246 unsigned Reg =
MI.getOperand(OpNum).getReg();
249 setV2(
MRI.getEncodingValue(Reg));
251 void set4VV2(
const MCInst &
MI,
unsigned OpNum) {
252 unsigned Encoding = getRegEncoding(
MI, OpNum);
256 void setAAA(
const MCInst &
MI,
unsigned OpNum) {
257 EVEX_aaa = getRegEncoding(
MI, OpNum);
259 void setNF(
bool V) { EVEX_aaa |= V << 2; }
260 void setSC(
const MCInst &
MI,
unsigned OpNum) {
261 unsigned Encoding =
MI.getOperand(OpNum).getImm();
262 EVEX_V2 = ~(Encoding >> 3) & 0x1;
263 EVEX_aaa = Encoding & 0x7;
267 : W(0), R(0), X(0), B(0), M(0),
R2(0), X2(0), B2(0), VEX_4V(0), VEX_L(0),
268 VEX_PP(0), VEX_5M(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0),
271 void setLowerBound(PrefixKind K) { Kind = K; }
273 PrefixKind determineOptimalKind() {
279 Kind = (
R2 | X2 | B2) ? REX2 : (W | R | X | B) ? REX :
None;
282 Kind = (
R2 | X2 | B2) ? REX2 : REX;
290 Kind = (W | X | B | (VEX_5M != 1)) ? VEX3 : VEX2;
297 uint8_t FirstPayload =
298 ((~R) & 0x1) << 7 | ((~X) & 0x1) << 6 | ((~B) & 0x1) << 5;
299 uint8_t LastPayload = ((~VEX_4V) & 0xf) << 3 | VEX_L << 2 | VEX_PP;
304 emitByte(0x40 | W << 3 | R << 2 | X << 1 | B, CB);
308 emitByte(M << 7 |
R2 << 6 | X2 << 5 | B2 << 4 | W << 3 | R << 2 | X << 1 |
314 emitByte(((~R) & 1) << 7 | LastPayload, CB);
318 emitByte(Kind == VEX3 ? 0xC4 : 0x8F, CB);
319 emitByte(FirstPayload | VEX_5M, CB);
320 emitByte(W << 7 | LastPayload, CB);
323 assert(VEX_5M && !(VEX_5M & 0x8) &&
"invalid mmm fields for EVEX!");
325 emitByte(FirstPayload | ((~
R2) & 0x1) << 4 | B2 << 3 | VEX_5M, CB);
326 emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | ((~X2) & 0x1) << 2 | VEX_PP,
328 emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 |
329 ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa,
342 : MCII(mcii), Ctx(ctx) {}
343 X86MCCodeEmitter(
const X86MCCodeEmitter &) =
delete;
344 X86MCCodeEmitter &
operator=(
const X86MCCodeEmitter &) =
delete;
345 ~X86MCCodeEmitter()
override =
default;
355 unsigned getX86RegNum(
const MCOperand &MO)
const;
357 unsigned getX86RegEncoding(
const MCInst &
MI,
unsigned OpNum)
const;
359 void emitImmediate(
const MCOperand &Disp,
SMLoc Loc,
unsigned ImmSize,
364 void emitRegModRMByte(
const MCOperand &ModRMReg,
unsigned RegOpcodeFld,
367 void emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
370 void emitMemModRMByte(
const MCInst &
MI,
unsigned Op,
unsigned RegOpcodeField,
375 bool ForceSIB =
false)
const;
377 PrefixKind emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
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,
399static uint8_t
modRMByte(
unsigned Mod,
unsigned RegOpcode,
unsigned RM) {
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)
423 return isInt<8>(
Value);
426 if (
Value & (CD8_Scale - 1))
429 int CDisp8 =
Value /
static_cast<int>(CD8_Scale);
430 if (!isInt<8>(CDisp8))
434 ImmOffset = CDisp8 -
Value;
476 if (S.
getName() !=
"_GLOBAL_OFFSET_TABLE_")
492 unsigned Opcode =
MI.getOpcode();
494 if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4 &&
495 Opcode != X86::JCC_4) ||
508unsigned X86MCCodeEmitter::getX86RegNum(
const MCOperand &MO)
const {
509 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg()) & 0x7;
512unsigned X86MCCodeEmitter::getX86RegEncoding(
const MCInst &
MI,
513 unsigned OpNum)
const {
514 return Ctx.getRegisterInfo()->getEncodingValue(
MI.getOperand(OpNum).getReg());
517void X86MCCodeEmitter::emitImmediate(
const MCOperand &DispOp,
SMLoc Loc,
522 int ImmOffset)
const {
523 const MCExpr *Expr =
nullptr;
524 if (DispOp.
isImm()) {
552 ImmOffset =
static_cast<int>(CB.
size() - StartByte);
592 Expr, FixupKind, Loc));
596void X86MCCodeEmitter::emitRegModRMByte(
const MCOperand &ModRMReg,
597 unsigned RegOpcodeFld,
599 emitByte(
modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), CB);
602void X86MCCodeEmitter::emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
608void X86MCCodeEmitter::emitMemModRMByte(
612 bool ForceSIB)
const {
617 unsigned BaseReg =
Base.getReg();
620 if (BaseReg == X86::RIP ||
621 BaseReg == X86::EIP) {
623 "Rip-relative addressing requires 64-bit mode");
625 "Invalid rip-relative address");
626 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
628 unsigned Opcode =
MI.getOpcode();
632 if (!(Disp.
isExpr() && isa<MCSymbolRefExpr>(Disp.
getExpr())))
645 assert(Kind == REX || Kind == REX2);
659 case X86::TAILJMPm64:
688 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte, CB,
693 unsigned BaseRegNo = BaseReg ? getX86RegNum(
Base) : -1U;
695 bool IsAdSize16 = STI.
hasFeature(X86::Is32Bit) &&
713 static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
714 unsigned RMfield = R16Table[BaseRegNo];
716 assert(RMfield &&
"invalid 16-bit base register");
719 unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];
721 assert(IndexReg16 &&
"invalid 16-bit index register");
723 assert(((IndexReg16 ^ RMfield) & 2) &&
724 "invalid 16-bit base/index register combination");
726 "invalid scale for 16-bit memory reference");
730 RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
732 RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
736 if (Disp.
getImm() == 0 && RMfield != 6) {
738 emitByte(
modRMByte(0, RegOpcodeField, RMfield), CB);
742 emitByte(
modRMByte(1, RegOpcodeField, RMfield), CB);
743 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups);
747 emitByte(
modRMByte(2, RegOpcodeField, RMfield), CB);
749 assert(IndexReg.
getReg() == 0 &&
"Unexpected index register!");
751 emitByte(
modRMByte(0, RegOpcodeField, 6), CB);
755 emitImmediate(Disp,
MI.getLoc(), 2,
FK_Data_2, StartByte, CB, Fixups);
764 bool AllowNoDisp = !UseDisp8 && !UseDisp32;
766 bool AllowDisp8 = !UseDisp32;
772 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
773 emitImmediate(Disp,
MI.getLoc(), 4,
FK_Data_4, StartByte, CB, Fixups);
783 if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp) {
784 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
790 auto *
Sym = dyn_cast<MCSymbolRefExpr>(Disp.
getExpr());
795 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
805 if (Disp.
isImm() && AllowDisp8) {
808 emitByte(
modRMByte(1, RegOpcodeField, BaseRegNo), CB);
809 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups,
818 emitByte(
modRMByte(2, RegOpcodeField, BaseRegNo), CB);
819 unsigned Opcode =
MI.getOpcode();
822 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte, CB,
829 "Cannot use ESP as index reg!");
831 bool ForceDisp32 =
false;
832 bool ForceDisp8 =
false;
838 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
840 }
else if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp &&
847 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
848 }
else if (Disp.
isImm() && AllowDisp8 &&
853 emitByte(
modRMByte(1, RegOpcodeField, 4), CB);
857 emitByte(
modRMByte(2, RegOpcodeField, 4), CB);
862 static const unsigned SSTable[] = {~0
U, 0, 1, ~0
U, 2, ~0
U, ~0
U, ~0
U, 3};
863 unsigned SS = SSTable[Scale.
getImm()];
865 unsigned IndexRegNo = IndexReg.
getReg() ? getX86RegNum(IndexReg) : 4;
867 emitSIBByte(SS, IndexRegNo, BaseRegNo, CB);
871 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups,
873 else if (ForceDisp32)
875 StartByte, CB, Fixups);
882PrefixKind X86MCCodeEmitter::emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
885 uint64_t TSFlags = MCII.get(
MI.getOpcode()).TSFlags;
889 if (MemoryOperand != -1) {
890 MemoryOperand += CurOp;
895 unsigned Flags =
MI.getFlags();
912 if (
MI.getOperand(2).getReg() != X86::DS)
913 emitSegmentOverridePrefix(2,
MI, CB);
919 if (
MI.getOperand(1).getReg() != X86::DS)
920 emitSegmentOverridePrefix(1,
MI, CB);
930 emitSegmentOverridePrefix(1,
MI, CB);
938 ? emitVEXOpcodePrefix(MemoryOperand,
MI, STI, CB)
939 : emitOpcodePrefix(MemoryOperand,
MI, STI, CB);
956X86MCCodeEmitter::emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
965 unsigned NumOps =
MI.getNumOperands();
972 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
974 "Cannot encode high byte register in VEX/EVEX-prefixed instruction");
978 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
983 Prefix.setLowerBound(XOP);
990 Prefix.setLowerBound(EVEX);
1058 bool EncodeRC =
false;
1059 uint8_t EVEX_rc = 0;
1101 if (!IsND && HasVEX_4V)
1105 if (HasTwoConditionalOps) {
1133 if (!IsND && HasVEX_4V)
1140 if (HasTwoConditionalOps) {
1185 if (HasTwoConditionalOps) {
1210 if (!IsND && HasVEX_4V)
1217 if (HasTwoConditionalOps) {
1224 unsigned NumOps =
Desc.getNumOperands();
1225 unsigned RcOperand = NumOps - 1;
1226 assert(RcOperand >= CurOp);
1227 EVEX_rc =
MI.getOperand(RcOperand).getImm();
1228 assert(EVEX_rc <= 3 &&
"Invalid rounding control!");
1272 if (!IsND && HasVEX_4V)
1276 if (HasTwoConditionalOps) {
1311 if (HasTwoConditionalOps) {
1319 Prefix.setL(EVEX_rc & 0x1);
1320 Prefix.setL2(EVEX_rc & 0x2);
1322 PrefixKind
Kind =
Prefix.determineOptimalKind();
1333PrefixKind X86MCCodeEmitter::emitREXPrefix(
int MemOperand,
const MCInst &
MI,
1338 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
1342 unsigned NumOps =
MI.getNumOperands();
1343 bool UsesHighByteReg =
false;
1345 bool HasRegOp =
false;
1348 for (
unsigned i = CurOp; i != NumOps; ++i) {
1355 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
1356 UsesHighByteReg =
true;
1359 Prefix.setLowerBound(REX);
1366 const auto *
Ref = dyn_cast<MCSymbolRefExpr>(MO.
getExpr());
1369 Prefix.setLowerBound(REX);
1374 Prefix.setLowerBound(REX);
1377 Prefix.setLowerBound(REX2);
1380 assert(!HasRegOp &&
"Unexpected form in emitREXPrefix!");
1440 PrefixKind
Kind =
Prefix.determineOptimalKind();
1441 if (Kind && UsesHighByteReg)
1443 "Cannot encode high byte register in REX-prefixed instruction");
1449void X86MCCodeEmitter::emitSegmentOverridePrefix(
1452 if (
unsigned Reg =
MI.getOperand(SegOperand).getReg())
1462PrefixKind X86MCCodeEmitter::emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
1495 "REX.W requires 64bit mode.");
1496 PrefixKind
Kind = emitREXPrefix(MemOperand,
MI, STI, CB);
1526 unsigned Opcode =
MI.getOpcode();
1536 emitPrefixImpl(CurOp,
MI, STI, CB);
1541 static_cast<X86MCCodeEmitter &
>(MCE).
emitPrefix(
MI, CB, STI);
1544void X86MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
1548 unsigned Opcode =
MI.getOpcode();
1556 unsigned NumOps =
Desc.getNumOperands();
1561 PrefixKind Kind = emitPrefixImpl(CurOp,
MI, STI, CB);
1572 unsigned I8RegNum = 0;
1579 unsigned OpcodeOffset = 0;
1587 errs() <<
"FORM: " <<
Form <<
"\n";
1595 emitByte(BaseOpcode, CB);
1599 OpcodeOffset =
MI.getOperand(NumOps - 1).getImm();
1600 assert(OpcodeOffset < 16 &&
"Unexpected opcode offset!");
1604 emitByte(BaseOpcode + OpcodeOffset, CB);
1616 emitByte(BaseOpcode, CB);
1617 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1619 StartByte, CB, Fixups);
1623 emitByte(BaseOpcode, CB);
1624 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1626 StartByte, CB, Fixups);
1627 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 1,
FK_Data_1, StartByte,
1631 emitByte(BaseOpcode, CB);
1632 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1634 StartByte, CB, Fixups);
1635 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 2,
FK_Data_2, StartByte,
1640 emitByte(BaseOpcode + getX86RegNum(
MI.getOperand(CurOp++)), CB);
1644 emitByte(BaseOpcode, CB);
1645 unsigned SrcRegNum = CurOp + 1;
1655 emitRegModRMByte(
MI.getOperand(CurOp),
1656 getX86RegNum(
MI.getOperand(SrcRegNum)), CB);
1657 CurOp = SrcRegNum + 1;
1661 unsigned FirstOp = CurOp++;
1662 unsigned SecondOp = CurOp++;
1663 unsigned CC =
MI.getOperand(CurOp++).getImm();
1664 emitByte(BaseOpcode +
CC, CB);
1665 emitRegModRMByte(
MI.getOperand(FirstOp),
1666 getX86RegNum(
MI.getOperand(SecondOp)), CB);
1670 unsigned CC =
MI.getOperand(8).getImm();
1671 emitByte(BaseOpcode +
CC, CB);
1673 emitMemModRMByte(
MI, CurOp + 1, getX86RegNum(
MI.getOperand(0)), TSFlags,
1674 Kind, StartByte, CB, Fixups, STI,
false);
1675 CurOp = SrcRegNum + 3;
1680 emitByte(BaseOpcode, CB);
1693 emitMemModRMByte(
MI, CurOp, getX86RegNum(
MI.getOperand(SrcRegNum)), TSFlags,
1694 Kind, StartByte, CB, Fixups, STI, ForceSIB);
1695 CurOp = SrcRegNum + 1;
1699 unsigned MemOp = CurOp;
1701 unsigned RegOp = CurOp++;
1702 unsigned CC =
MI.getOperand(CurOp++).getImm();
1703 emitByte(BaseOpcode +
CC, CB);
1704 emitMemModRMByte(
MI,
MemOp, getX86RegNum(
MI.getOperand(RegOp)), TSFlags,
1705 Kind, StartByte, CB, Fixups, STI);
1709 emitByte(BaseOpcode, CB);
1710 unsigned SrcRegNum = CurOp + 1;
1721 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1722 getX86RegNum(
MI.getOperand(CurOp)), CB);
1723 CurOp = SrcRegNum + 1;
1725 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1732 emitByte(BaseOpcode, CB);
1733 unsigned SrcRegNum = CurOp + 1;
1735 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1736 getX86RegNum(
MI.getOperand(CurOp)), CB);
1737 CurOp = SrcRegNum + 1;
1742 emitByte(BaseOpcode, CB);
1743 unsigned SrcRegNum = CurOp + 1;
1749 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1750 I8RegNum = getX86RegEncoding(
MI, SrcRegNum++);
1752 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1753 getX86RegNum(
MI.getOperand(CurOp)), CB);
1754 CurOp = SrcRegNum + 1;
1760 unsigned FirstOp = CurOp++;
1761 unsigned SecondOp = CurOp++;
1763 unsigned CC =
MI.getOperand(CurOp++).getImm();
1764 emitByte(BaseOpcode +
CC, CB);
1766 emitRegModRMByte(
MI.getOperand(SecondOp),
1767 getX86RegNum(
MI.getOperand(FirstOp)), CB);
1772 unsigned FirstMemOp = CurOp + 1;
1783 emitByte(BaseOpcode, CB);
1786 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1787 TSFlags, Kind, StartByte, CB, Fixups, STI, ForceSIB);
1790 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1794 unsigned FirstMemOp = CurOp + 1;
1796 emitByte(BaseOpcode, CB);
1798 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1799 TSFlags, Kind, StartByte, CB, Fixups, STI);
1805 unsigned FirstMemOp = CurOp + 1;
1810 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1811 I8RegNum = getX86RegEncoding(
MI, FirstMemOp++);
1813 emitByte(BaseOpcode, CB);
1815 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1816 TSFlags, Kind, StartByte, CB, Fixups, STI);
1823 unsigned RegOp = CurOp++;
1824 unsigned FirstMemOp = CurOp;
1827 unsigned CC =
MI.getOperand(CurOp++).getImm();
1828 emitByte(BaseOpcode +
CC, CB);
1830 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(RegOp)),
1831 TSFlags, Kind, StartByte, CB, Fixups, STI);
1836 unsigned RegOp = CurOp++;
1838 unsigned CC =
MI.getOperand(CurOp++).getImm();
1839 emitByte(BaseOpcode +
CC, CB);
1840 emitRegModRMByte(
MI.getOperand(RegOp), 0, CB);
1857 emitByte(BaseOpcode, CB);
1858 emitRegModRMByte(
MI.getOperand(CurOp++),
1862 emitByte(BaseOpcode, CB);
1863 emitByte(
modRMByte(3, getX86RegNum(
MI.getOperand(CurOp++)), 0), CB);
1867 unsigned FirstMemOp = CurOp;
1870 unsigned CC =
MI.getOperand(CurOp++).getImm();
1871 emitByte(BaseOpcode +
CC, CB);
1873 emitMemModRMByte(
MI, FirstMemOp, 0, TSFlags, Kind, StartByte, CB, Fixups,
1891 emitByte(BaseOpcode, CB);
1892 emitMemModRMByte(
MI, CurOp,
1894 Kind, StartByte, CB, Fixups, STI);
1906 emitByte(BaseOpcode, CB);
1974 emitByte(BaseOpcode, CB);
1982 assert(I8RegNum < 16 &&
"Register encoding out of range");
1984 if (CurOp != NumOps) {
1985 unsigned Val =
MI.getOperand(CurOp++).getImm();
1986 assert(Val < 16 &&
"Immediate operand value out of range");
1990 StartByte, CB, Fixups);
1997 unsigned RemaningOps = NumOps - CurOp - 2 * HasTwoConditionalOps;
1998 while (RemaningOps) {
1999 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
2001 StartByte, CB, Fixups);
2004 CurOp += 2 * HasTwoConditionalOps;
2010 if (CB.
size() - StartByte > 15)
2011 Ctx.reportError(
MI.getLoc(),
"instruction length exceeds the limit of 15");
2014 if ( CurOp != NumOps) {
2015 errs() <<
"Cannot encode all operands of: ";
2025 return new X86MCCodeEmitter(MCII, Ctx);
unsigned const MachineRegisterInfo * MRI
static bool isPCRel(unsigned Kind)
if(auto Err=PB.parsePassPipeline(MPM, Passes)) return wrap(std MPM run * Mod
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
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)
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.
@ 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 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(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.