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) {
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) {
224 unsigned Encoding =
MRI.getEncodingValue(Reg);
230 void setBB2(
const MCInst &
MI,
unsigned OpNum) {
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) {
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;
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,
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);
596 Expr, FixupKind, Loc));
600void X86MCCodeEmitter::emitRegModRMByte(
const MCOperand &ModRMReg,
601 unsigned RegOpcodeFld,
603 emitByte(
modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)), CB);
606void X86MCCodeEmitter::emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
612void X86MCCodeEmitter::emitMemModRMByte(
616 bool ForceSIB)
const {
624 if (BaseReg == X86::RIP ||
625 BaseReg == X86::EIP) {
627 "Rip-relative addressing requires 64-bit mode");
628 assert(!IndexReg.
getReg() && !ForceSIB &&
"Invalid rip-relative address");
629 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
631 unsigned Opcode =
MI.getOpcode();
635 if (!(Disp.
isExpr() && isa<MCSymbolRefExpr>(Disp.
getExpr())))
661 case X86::TAILJMPm64:
675 case X86::ADD64rm_NF:
676 case X86::ADD64rm_ND:
677 case X86::ADD64mr_ND:
678 case X86::ADD64mr_NF_ND:
679 case X86::ADD64rm_NF_ND:
695 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte, CB,
700 unsigned BaseRegNo = BaseReg ? getX86RegNum(
Base) : -1U;
702 bool IsAdSize16 = STI.
hasFeature(X86::Is32Bit) &&
720 static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
721 unsigned RMfield = R16Table[BaseRegNo];
723 assert(RMfield &&
"invalid 16-bit base register");
726 unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];
728 assert(IndexReg16 &&
"invalid 16-bit index register");
730 assert(((IndexReg16 ^ RMfield) & 2) &&
731 "invalid 16-bit base/index register combination");
733 "invalid scale for 16-bit memory reference");
737 RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
739 RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
743 if (Disp.
getImm() == 0 && RMfield != 6) {
745 emitByte(
modRMByte(0, RegOpcodeField, RMfield), CB);
749 emitByte(
modRMByte(1, RegOpcodeField, RMfield), CB);
750 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups);
754 emitByte(
modRMByte(2, RegOpcodeField, RMfield), CB);
756 assert(!IndexReg.
getReg() &&
"Unexpected index register!");
758 emitByte(
modRMByte(0, RegOpcodeField, 6), CB);
762 emitImmediate(Disp,
MI.getLoc(), 2,
FK_Data_2, StartByte, CB, Fixups);
771 bool AllowNoDisp = !UseDisp8 && !UseDisp32;
773 bool AllowDisp8 = !UseDisp32;
779 emitByte(
modRMByte(0, RegOpcodeField, 5), CB);
780 emitImmediate(Disp,
MI.getLoc(), 4,
FK_Data_4, StartByte, CB, Fixups);
790 if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp) {
791 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
797 auto *
Sym = dyn_cast<MCSymbolRefExpr>(Disp.
getExpr());
802 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo), CB);
812 if (Disp.
isImm() && AllowDisp8) {
815 emitByte(
modRMByte(1, RegOpcodeField, BaseRegNo), CB);
816 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups,
825 emitByte(
modRMByte(2, RegOpcodeField, BaseRegNo), CB);
826 unsigned Opcode =
MI.getOpcode();
829 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte, CB,
836 "Cannot use ESP as index reg!");
838 bool ForceDisp32 =
false;
839 bool ForceDisp8 =
false;
845 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
847 }
else if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp &&
854 emitByte(
modRMByte(0, RegOpcodeField, 4), CB);
855 }
else if (Disp.
isImm() && AllowDisp8 &&
860 emitByte(
modRMByte(1, RegOpcodeField, 4), CB);
864 emitByte(
modRMByte(2, RegOpcodeField, 4), CB);
869 static const unsigned SSTable[] = {~0
U, 0, 1, ~0
U, 2, ~0
U, ~0
U, ~0
U, 3};
870 unsigned SS = SSTable[Scale.
getImm()];
872 unsigned IndexRegNo = IndexReg.
getReg() ? getX86RegNum(IndexReg) : 4;
874 emitSIBByte(SS, IndexRegNo, BaseRegNo, CB);
878 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte, CB, Fixups,
880 else if (ForceDisp32)
882 StartByte, CB, Fixups);
889PrefixKind X86MCCodeEmitter::emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
892 uint64_t TSFlags = MCII.get(
MI.getOpcode()).TSFlags;
896 if (MemoryOperand != -1) {
897 MemoryOperand += CurOp;
902 unsigned Flags =
MI.getFlags();
919 if (
MI.getOperand(2).getReg() != X86::DS)
920 emitSegmentOverridePrefix(2,
MI, CB);
926 if (
MI.getOperand(1).getReg() != X86::DS)
927 emitSegmentOverridePrefix(1,
MI, CB);
937 emitSegmentOverridePrefix(1,
MI, CB);
945 ? emitVEXOpcodePrefix(MemoryOperand,
MI, STI, CB)
946 : emitOpcodePrefix(MemoryOperand,
MI, STI, CB);
963X86MCCodeEmitter::emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
972 unsigned NumOps =
MI.getNumOperands();
979 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
981 "Cannot encode high byte register in VEX/EVEX-prefixed instruction");
985 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
990 Prefix.setLowerBound(XOP);
997 Prefix.setLowerBound(EVEX);
1065 bool EncodeRC =
false;
1108 if (!IsND && HasVEX_4V)
1112 if (HasTwoConditionalOps) {
1140 if (!IsND && HasVEX_4V)
1147 if (HasTwoConditionalOps) {
1192 if (HasTwoConditionalOps) {
1217 if (!IsND && HasVEX_4V)
1224 if (HasTwoConditionalOps) {
1231 unsigned NumOps =
Desc.getNumOperands();
1232 unsigned RcOperand = NumOps - 1;
1233 assert(RcOperand >= CurOp);
1234 EVEX_rc =
MI.getOperand(RcOperand).getImm();
1235 assert(EVEX_rc <= 3 &&
"Invalid rounding control!");
1279 if (!IsND && HasVEX_4V)
1283 if (HasTwoConditionalOps) {
1318 if (HasTwoConditionalOps) {
1326 Prefix.setL(EVEX_rc & 0x1);
1327 Prefix.setL2(EVEX_rc & 0x2);
1329 PrefixKind
Kind =
Prefix.determineOptimalKind();
1340PrefixKind X86MCCodeEmitter::emitREXPrefix(
int MemOperand,
const MCInst &
MI,
1345 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
1349 unsigned NumOps =
MI.getNumOperands();
1350 bool UsesHighByteReg =
false;
1352 bool HasRegOp =
false;
1355 for (
unsigned i = CurOp; i != NumOps; ++i) {
1362 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
1363 UsesHighByteReg =
true;
1366 Prefix.setLowerBound(REX);
1373 const auto *
Ref = dyn_cast<MCSymbolRefExpr>(MO.
getExpr());
1376 Prefix.setLowerBound(REX);
1381 Prefix.setLowerBound(REX);
1384 Prefix.setLowerBound(REX2);
1387 assert(!HasRegOp &&
"Unexpected form in emitREXPrefix!");
1447 PrefixKind
Kind =
Prefix.determineOptimalKind();
1448 if (Kind && UsesHighByteReg)
1450 "Cannot encode high byte register in REX-prefixed instruction");
1456void X86MCCodeEmitter::emitSegmentOverridePrefix(
1459 if (
MCRegister Reg =
MI.getOperand(SegOperand).getReg())
1469PrefixKind X86MCCodeEmitter::emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
1502 "REX.W requires 64bit mode.");
1503 PrefixKind
Kind = emitREXPrefix(MemOperand,
MI, STI, CB);
1533 unsigned Opcode =
MI.getOpcode();
1543 emitPrefixImpl(CurOp,
MI, STI, CB);
1548 static_cast<X86MCCodeEmitter &
>(MCE).
emitPrefix(
MI, CB, STI);
1551void X86MCCodeEmitter::encodeInstruction(
const MCInst &
MI,
1555 unsigned Opcode =
MI.getOpcode();
1563 unsigned NumOps =
Desc.getNumOperands();
1568 PrefixKind Kind = emitPrefixImpl(CurOp,
MI, STI, CB);
1579 unsigned I8RegNum = 0;
1586 unsigned OpcodeOffset = 0;
1594 errs() <<
"FORM: " << Form <<
"\n";
1602 emitByte(BaseOpcode, CB);
1606 OpcodeOffset =
MI.getOperand(NumOps - 1).getImm();
1607 assert(OpcodeOffset < 16 &&
"Unexpected opcode offset!");
1611 emitByte(BaseOpcode + OpcodeOffset, CB);
1623 emitByte(BaseOpcode, CB);
1624 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1626 StartByte, CB, Fixups);
1630 emitByte(BaseOpcode, CB);
1631 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1633 StartByte, CB, Fixups);
1634 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 1,
FK_Data_1, StartByte,
1638 emitByte(BaseOpcode, CB);
1639 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1641 StartByte, CB, Fixups);
1642 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 2,
FK_Data_2, StartByte,
1647 emitByte(BaseOpcode + getX86RegNum(
MI.getOperand(CurOp++)), CB);
1651 emitByte(BaseOpcode, CB);
1652 unsigned SrcRegNum = CurOp + 1;
1662 emitRegModRMByte(
MI.getOperand(CurOp),
1663 getX86RegNum(
MI.getOperand(SrcRegNum)), CB);
1664 CurOp = SrcRegNum + 1;
1668 unsigned FirstOp = CurOp++;
1669 unsigned SecondOp = CurOp++;
1670 unsigned CC =
MI.getOperand(CurOp++).getImm();
1671 emitByte(BaseOpcode +
CC, CB);
1672 emitRegModRMByte(
MI.getOperand(FirstOp),
1673 getX86RegNum(
MI.getOperand(SecondOp)), CB);
1677 unsigned CC =
MI.getOperand(8).getImm();
1678 emitByte(BaseOpcode +
CC, CB);
1680 emitMemModRMByte(
MI, CurOp + 1, getX86RegNum(
MI.getOperand(0)), TSFlags,
1681 Kind, StartByte, CB, Fixups, STI,
false);
1682 CurOp = SrcRegNum + 3;
1687 emitByte(BaseOpcode, CB);
1700 emitMemModRMByte(
MI, CurOp, getX86RegNum(
MI.getOperand(SrcRegNum)), TSFlags,
1701 Kind, StartByte, CB, Fixups, STI, ForceSIB);
1702 CurOp = SrcRegNum + 1;
1706 unsigned MemOp = CurOp;
1708 unsigned RegOp = CurOp++;
1709 unsigned CC =
MI.getOperand(CurOp++).getImm();
1710 emitByte(BaseOpcode +
CC, CB);
1711 emitMemModRMByte(
MI,
MemOp, getX86RegNum(
MI.getOperand(RegOp)), TSFlags,
1712 Kind, StartByte, CB, Fixups, STI);
1716 emitByte(BaseOpcode, CB);
1717 unsigned SrcRegNum = CurOp + 1;
1728 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1729 getX86RegNum(
MI.getOperand(CurOp)), CB);
1730 CurOp = SrcRegNum + 1;
1732 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1739 emitByte(BaseOpcode, CB);
1740 unsigned SrcRegNum = CurOp + 1;
1742 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1743 getX86RegNum(
MI.getOperand(CurOp)), CB);
1744 CurOp = SrcRegNum + 1;
1749 emitByte(BaseOpcode, CB);
1750 unsigned SrcRegNum = CurOp + 1;
1756 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1757 I8RegNum = getX86RegEncoding(
MI, SrcRegNum++);
1759 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1760 getX86RegNum(
MI.getOperand(CurOp)), CB);
1761 CurOp = SrcRegNum + 1;
1767 unsigned FirstOp = CurOp++;
1768 unsigned SecondOp = CurOp++;
1770 unsigned CC =
MI.getOperand(CurOp++).getImm();
1771 emitByte(BaseOpcode +
CC, CB);
1773 emitRegModRMByte(
MI.getOperand(SecondOp),
1774 getX86RegNum(
MI.getOperand(FirstOp)), CB);
1779 unsigned FirstMemOp = CurOp + 1;
1790 emitByte(BaseOpcode, CB);
1793 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1794 TSFlags, Kind, StartByte, CB, Fixups, STI, ForceSIB);
1797 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1801 unsigned FirstMemOp = CurOp + 1;
1803 emitByte(BaseOpcode, CB);
1805 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1806 TSFlags, Kind, StartByte, CB, Fixups, STI);
1812 unsigned FirstMemOp = CurOp + 1;
1817 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1818 I8RegNum = getX86RegEncoding(
MI, FirstMemOp++);
1820 emitByte(BaseOpcode, CB);
1822 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1823 TSFlags, Kind, StartByte, CB, Fixups, STI);
1830 unsigned RegOp = CurOp++;
1831 unsigned FirstMemOp = CurOp;
1834 unsigned CC =
MI.getOperand(CurOp++).getImm();
1835 emitByte(BaseOpcode +
CC, CB);
1837 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(RegOp)),
1838 TSFlags, Kind, StartByte, CB, Fixups, STI);
1843 unsigned RegOp = CurOp++;
1845 unsigned CC =
MI.getOperand(CurOp++).getImm();
1846 emitByte(BaseOpcode +
CC, CB);
1847 emitRegModRMByte(
MI.getOperand(RegOp), 0, CB);
1864 emitByte(BaseOpcode, CB);
1865 emitRegModRMByte(
MI.getOperand(CurOp++),
1869 emitByte(BaseOpcode, CB);
1870 emitByte(
modRMByte(3, getX86RegNum(
MI.getOperand(CurOp++)), 0), CB);
1874 unsigned FirstMemOp = CurOp;
1877 unsigned CC =
MI.getOperand(CurOp++).getImm();
1878 emitByte(BaseOpcode +
CC, CB);
1880 emitMemModRMByte(
MI, FirstMemOp, 0, TSFlags, Kind, StartByte, CB, Fixups,
1898 emitByte(BaseOpcode, CB);
1899 emitMemModRMByte(
MI, CurOp,
1901 Kind, StartByte, CB, Fixups, STI);
1913 emitByte(BaseOpcode, CB);
1981 emitByte(BaseOpcode, CB);
1989 assert(I8RegNum < 16 &&
"Register encoding out of range");
1991 if (CurOp != NumOps) {
1992 unsigned Val =
MI.getOperand(CurOp++).getImm();
1993 assert(Val < 16 &&
"Immediate operand value out of range");
1997 StartByte, CB, Fixups);
2004 unsigned RemaningOps = NumOps - CurOp - 2 * HasTwoConditionalOps;
2005 while (RemaningOps) {
2006 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
2008 StartByte, CB, Fixups);
2011 CurOp += 2 * HasTwoConditionalOps;
2017 if (CB.
size() - StartByte > 15)
2018 Ctx.reportError(
MI.getLoc(),
"instruction length exceeds the limit of 15");
2021 if ( CurOp != NumOps) {
2022 errs() <<
"Cannot encode all operands of: ";
2032 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)
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...
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.
Reg
All possible values of the reg field in the ModR/M byte.
@ 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 hasImm(uint64_t TSFlags)
bool hasNewDataDest(uint64_t TSFlags)
bool isX86_64NonExtLowByteReg(MCRegister Reg)
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_global_offset_table8
@ 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
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.