36#define DEBUG_TYPE "mccodeemitter"
40enum PrefixKind {
None, REX, XOP, VEX2, VEX3, EVEX };
42static void emitByte(uint8_t
C,
raw_ostream &
OS) { OS << static_cast<char>(
C); }
44class X86OpcodePrefixHelper {
128 unsigned EVEX_R2 : 1;
130 unsigned EVEX_L2 : 1;
132 unsigned EVEX_V2 : 1;
133 unsigned EVEX_aaa : 3;
134 PrefixKind Kind =
None;
137 unsigned getRegEncoding(
const MCInst &
MI,
unsigned OpNum)
const {
138 return MRI.getEncodingValue(
MI.getOperand(OpNum).getReg());
141 void setR(
unsigned Encoding) { R = Encoding >> 3 & 1; }
142 void setR2(
unsigned Encoding) { EVEX_R2 = Encoding >> 4 & 1; }
143 void set4V(
unsigned Encoding) { VEX_4V = Encoding & 0xf; }
144 void setV2(
unsigned Encoding) { EVEX_V2 = Encoding >> 4 & 1; }
147 void setW(
bool V) { W = V; }
148 void setR(
const MCInst &
MI,
unsigned OpNum) {
149 setR(getRegEncoding(
MI, OpNum));
151 void setX(
const MCInst &
MI,
unsigned OpNum,
unsigned Shift = 3) {
152 X = getRegEncoding(
MI, OpNum) >> Shift & 1;
154 void setB(
const MCInst &
MI,
unsigned OpNum) {
155 B = getRegEncoding(
MI, OpNum) >> 3 & 1;
157 void set4V(
const MCInst &
MI,
unsigned OpNum) {
158 set4V(getRegEncoding(
MI, OpNum));
160 void setL(
bool V) { VEX_L = V; }
161 void setPP(
unsigned V) { VEX_PP = V; }
162 void set5M(
unsigned V) { VEX_5M = V; }
163 void setR2(
const MCInst &
MI,
unsigned OpNum) {
164 setR2(getRegEncoding(
MI, OpNum));
166 void setRR2(
const MCInst &
MI,
unsigned OpNum) {
167 unsigned Encoding = getRegEncoding(
MI, OpNum);
171 void setZ(
bool V) { EVEX_z = V; }
172 void setL2(
bool V) { EVEX_L2 = V; }
173 void setEVEX_b(
bool V) { EVEX_b = V; }
174 void setV2(
const MCInst &
MI,
unsigned OpNum) {
175 setV2(getRegEncoding(
MI, OpNum));
177 void set4VV2(
const MCInst &
MI,
unsigned OpNum) {
178 unsigned Encoding = getRegEncoding(
MI, OpNum);
182 void setAAA(
const MCInst &
MI,
unsigned OpNum) {
183 EVEX_aaa = getRegEncoding(
MI, OpNum);
187 : W(0), R(0), X(0), B(0), VEX_4V(0), VEX_L(0), VEX_PP(0), VEX_5M(0),
188 EVEX_R2(0), EVEX_z(0), EVEX_L2(0), EVEX_b(0), EVEX_V2(0), EVEX_aaa(0),
191 void setLowerBound(PrefixKind K) { Kind = K; }
193 PrefixKind determineOptimalKind() {
196 Kind = (W | R | X | B) ? REX :
None;
204 Kind = (W | X | B | (VEX_5M != 1)) ? VEX3 : VEX2;
211 uint8_t FirstPayload =
212 ((~R) & 0x1) << 7 | ((~X) & 0x1) << 6 | ((~B) & 0x1) << 5;
213 uint8_t LastPayload = ((~VEX_4V) & 0xf) << 3 | VEX_L << 2 | VEX_PP;
218 emitByte(0x40 | W << 3 | R << 2 | X << 1 | B,
OS);
222 emitByte(((~R) & 1) << 7 | LastPayload,
OS);
226 emitByte(Kind == VEX3 ? 0xC4 : 0x8F,
OS);
227 emitByte(FirstPayload | VEX_5M,
OS);
228 emitByte(W << 7 | LastPayload,
OS);
231 assert(VEX_5M && !(VEX_5M & 0x8) &&
"invalid mmm fields for EVEX!");
233 emitByte(FirstPayload | ((~EVEX_R2) & 0x1) << 4 | VEX_5M,
OS);
234 emitByte(W << 7 | ((~VEX_4V) & 0xf) << 3 | 1 << 2 | VEX_PP,
OS);
235 emitByte(EVEX_z << 7 | EVEX_L2 << 6 | VEX_L << 5 | EVEX_b << 4 |
236 ((~EVEX_V2) & 0x1) << 3 | EVEX_aaa,
249 : MCII(mcii), Ctx(ctx) {}
250 X86MCCodeEmitter(
const X86MCCodeEmitter &) =
delete;
251 X86MCCodeEmitter &
operator=(
const X86MCCodeEmitter &) =
delete;
252 ~X86MCCodeEmitter()
override =
default;
262 unsigned getX86RegNum(
const MCOperand &MO)
const;
264 unsigned getX86RegEncoding(
const MCInst &
MI,
unsigned OpNum)
const;
266 void emitImmediate(
const MCOperand &Disp,
SMLoc Loc,
unsigned ImmSize,
270 void emitRegModRMByte(
const MCOperand &ModRMReg,
unsigned RegOpcodeFld,
273 void emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
276 void emitMemModRMByte(
const MCInst &
MI,
unsigned Op,
unsigned RegOpcodeField,
280 bool ForceSIB =
false)
const;
282 PrefixKind emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
285 PrefixKind emitVEXOpcodePrefix(
int MemOperand,
const MCInst &
MI,
288 void emitSegmentOverridePrefix(
unsigned SegOperand,
const MCInst &
MI,
291 PrefixKind emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
295 PrefixKind emitREXPrefix(
int MemOperand,
const MCInst &
MI,
301static uint8_t
modRMByte(
unsigned Mod,
unsigned RegOpcode,
unsigned RM) {
302 assert(
Mod < 4 && RegOpcode < 8 && RM < 8 &&
"ModRM Fields out of range!");
303 return RM | (RegOpcode << 3) | (
Mod << 6);
308 for (
unsigned i = 0; i !=
Size; ++i) {
309 emitByte(Val & 255,
OS);
322 if (!HasEVEX || CD8_Scale == 0)
323 return isInt<8>(
Value);
326 if (
Value & (CD8_Scale - 1))
329 int CDisp8 =
Value / CD8_Scale;
330 if (!isInt<8>(CDisp8))
334 ImmOffset = CDisp8 -
Value;
376 if (S.
getName() !=
"_GLOBAL_OFFSET_TABLE_")
392 unsigned Opcode =
MI.getOpcode();
394 if ((Opcode != X86::CALL64pcrel32 && Opcode != X86::JMP_4 &&
395 Opcode != X86::JCC_4) ||
408unsigned X86MCCodeEmitter::getX86RegNum(
const MCOperand &MO)
const {
409 return Ctx.getRegisterInfo()->getEncodingValue(MO.
getReg()) & 0x7;
412unsigned X86MCCodeEmitter::getX86RegEncoding(
const MCInst &
MI,
413 unsigned OpNum)
const {
414 return Ctx.getRegisterInfo()->getEncodingValue(
MI.getOperand(OpNum).getReg());
417void X86MCCodeEmitter::emitImmediate(
const MCOperand &DispOp,
SMLoc Loc,
421 int ImmOffset)
const {
422 const MCExpr *Expr =
nullptr;
423 if (DispOp.
isImm()) {
451 ImmOffset =
static_cast<int>(
OS.
tell() - StartByte);
491 Expr, FixupKind, Loc));
495void X86MCCodeEmitter::emitRegModRMByte(
const MCOperand &ModRMReg,
496 unsigned RegOpcodeFld,
498 emitByte(
modRMByte(3, RegOpcodeFld, getX86RegNum(ModRMReg)),
OS);
501void X86MCCodeEmitter::emitSIBByte(
unsigned SS,
unsigned Index,
unsigned Base,
507void X86MCCodeEmitter::emitMemModRMByte(
const MCInst &
MI,
unsigned Op,
508 unsigned RegOpcodeField,
513 bool ForceSIB)
const {
518 unsigned BaseReg =
Base.getReg();
521 if (BaseReg == X86::RIP ||
522 BaseReg == X86::EIP) {
524 "Rip-relative addressing requires 64-bit mode");
526 "Invalid rip-relative address");
529 unsigned Opcode =
MI.getOpcode();
533 if (!(Disp.
isExpr() && isa<MCSymbolRefExpr>(Disp.
getExpr())))
559 case X86::TAILJMPm64:
585 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte,
OS,
590 unsigned BaseRegNo = BaseReg ? getX86RegNum(
Base) : -1U;
607 static const unsigned R16Table[] = {0, 0, 0, 7, 0, 6, 4, 5};
608 unsigned RMfield = R16Table[BaseRegNo];
610 assert(RMfield &&
"invalid 16-bit base register");
613 unsigned IndexReg16 = R16Table[getX86RegNum(IndexReg)];
615 assert(IndexReg16 &&
"invalid 16-bit index register");
617 assert(((IndexReg16 ^ RMfield) & 2) &&
618 "invalid 16-bit base/index register combination");
620 "invalid scale for 16-bit memory reference");
624 RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);
626 RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);
630 if (Disp.
getImm() == 0 && RMfield != 6) {
632 emitByte(
modRMByte(0, RegOpcodeField, RMfield),
OS);
636 emitByte(
modRMByte(1, RegOpcodeField, RMfield),
OS);
637 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte,
OS, Fixups);
641 emitByte(
modRMByte(2, RegOpcodeField, RMfield),
OS);
643 assert(IndexReg.
getReg() == 0 &&
"Unexpected index register!");
649 emitImmediate(Disp,
MI.getLoc(), 2,
FK_Data_2, StartByte,
OS, Fixups);
658 bool AllowNoDisp = !UseDisp8 && !UseDisp32;
660 bool AllowDisp8 = !UseDisp32;
665 !ForceSIB && IndexReg.
getReg() == 0 &&
672 (!STI.
hasFeature(X86::Is64Bit) || BaseReg != 0)) {
676 emitImmediate(Disp,
MI.getLoc(), 4,
FK_Data_4, StartByte,
OS, Fixups);
685 if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp) {
686 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo),
OS);
692 auto *Sym = dyn_cast<MCSymbolRefExpr>(Disp.
getExpr());
697 emitByte(
modRMByte(0, RegOpcodeField, BaseRegNo),
OS);
707 if (Disp.
isImm() && AllowDisp8) {
710 emitByte(
modRMByte(1, RegOpcodeField, BaseRegNo),
OS);
711 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte,
OS, Fixups,
720 emitByte(
modRMByte(2, RegOpcodeField, BaseRegNo),
OS);
721 unsigned Opcode =
MI.getOpcode();
724 emitImmediate(Disp,
MI.getLoc(), 4,
MCFixupKind(FixupKind), StartByte,
OS,
731 "Cannot use ESP as index reg!");
733 bool ForceDisp32 =
false;
734 bool ForceDisp8 =
false;
742 }
else if (Disp.
isImm() && Disp.
getImm() == 0 && AllowNoDisp &&
750 }
else if (Disp.
isImm() && AllowDisp8 &&
764 static const unsigned SSTable[] = {~0
U, 0, 1, ~0
U, 2, ~0
U, ~0
U, ~0
U, 3};
765 unsigned SS = SSTable[Scale.
getImm()];
767 unsigned IndexRegNo = IndexReg.
getReg() ? getX86RegNum(IndexReg) : 4;
769 emitSIBByte(SS, IndexRegNo, BaseRegNo,
OS);
773 emitImmediate(Disp,
MI.getLoc(), 1,
FK_Data_1, StartByte,
OS, Fixups,
775 else if (ForceDisp32)
777 StartByte,
OS, Fixups);
784PrefixKind X86MCCodeEmitter::emitPrefixImpl(
unsigned &CurOp,
const MCInst &
MI,
791 if (MemoryOperand != -1) {
792 MemoryOperand += CurOp;
797 unsigned Flags =
MI.getFlags();
814 if (
MI.getOperand(2).getReg() != X86::DS)
815 emitSegmentOverridePrefix(2,
MI,
OS);
821 if (
MI.getOperand(1).getReg() != X86::DS)
822 emitSegmentOverridePrefix(1,
MI,
OS);
832 emitSegmentOverridePrefix(1,
MI,
OS);
840 ? emitVEXOpcodePrefix(MemoryOperand,
MI,
OS)
841 : emitOpcodePrefix(MemoryOperand,
MI, STI,
OS);
857PrefixKind X86MCCodeEmitter::emitVEXOpcodePrefix(
int MemOperand,
865 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
870 Prefix.setLowerBound(XOP);
877 Prefix.setLowerBound(EVEX);
933 bool EncodeRC =
false;
1064 unsigned RcOperand = NumOps - 1;
1065 assert(RcOperand >= CurOp);
1066 EVEX_rc =
MI.getOperand(RcOperand).getImm();
1067 assert(EVEX_rc <= 3 &&
"Invalid rounding control!");
1143 Prefix.setL(EVEX_rc & 0x1);
1144 Prefix.setL2(EVEX_rc & 0x2);
1146 PrefixKind
Kind =
Prefix.determineOptimalKind();
1157PrefixKind X86MCCodeEmitter::emitREXPrefix(
int MemOperand,
const MCInst &
MI,
1162 X86OpcodePrefixHelper
Prefix(*Ctx.getRegisterInfo());
1166 unsigned NumOps =
MI.getNumOperands();
1167 bool UsesHighByteReg =
false;
1169 bool HasRegOp =
false;
1172 for (
unsigned i = CurOp; i != NumOps; ++i) {
1179 if (Reg == X86::AH || Reg == X86::BH || Reg == X86::CH || Reg == X86::DH)
1180 UsesHighByteReg =
true;
1183 Prefix.setLowerBound(REX);
1190 const auto *
Ref = dyn_cast<MCSymbolRefExpr>(MO.
getExpr());
1193 Prefix.setLowerBound(REX);
1199 assert(!HasRegOp &&
"Unexpected form in emitREXPrefix!");
1258 PrefixKind
Kind =
Prefix.determineOptimalKind();
1259 if (Kind && UsesHighByteReg)
1261 "Cannot encode high byte register in REX-prefixed instruction");
1267void X86MCCodeEmitter::emitSegmentOverridePrefix(
unsigned SegOperand,
1271 if (
unsigned Reg =
MI.getOperand(SegOperand).getReg())
1281PrefixKind X86MCCodeEmitter::emitOpcodePrefix(
int MemOperand,
const MCInst &
MI,
1314 "REX.W requires 64bit mode.");
1315 PrefixKind
Kind = emitREXPrefix(MemOperand,
MI, STI,
OS);
1341 unsigned Opcode =
MI.getOpcode();
1351 emitPrefixImpl(CurOp,
MI, STI,
OS);
1357 unsigned Opcode =
MI.getOpcode();
1370 PrefixKind
Kind = emitPrefixImpl(CurOp,
MI, STI,
OS);
1381 unsigned I8RegNum = 0;
1388 unsigned OpcodeOffset = 0;
1393 errs() <<
"FORM: " <<
Form <<
"\n";
1401 emitByte(BaseOpcode,
OS);
1405 OpcodeOffset =
MI.getOperand(NumOps - 1).getImm();
1406 assert(OpcodeOffset < 16 &&
"Unexpected opcode offset!");
1410 emitByte(BaseOpcode + OpcodeOffset,
OS);
1422 emitByte(BaseOpcode,
OS);
1423 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1425 StartByte,
OS, Fixups);
1429 emitByte(BaseOpcode,
OS);
1430 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1432 StartByte,
OS, Fixups);
1433 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 1,
FK_Data_1, StartByte,
1437 emitByte(BaseOpcode,
OS);
1438 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1440 StartByte,
OS, Fixups);
1441 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(), 2,
FK_Data_2, StartByte,
1446 emitByte(BaseOpcode + getX86RegNum(
MI.getOperand(CurOp++)),
OS);
1450 emitByte(BaseOpcode,
OS);
1451 unsigned SrcRegNum = CurOp + 1;
1459 emitRegModRMByte(
MI.getOperand(CurOp),
1460 getX86RegNum(
MI.getOperand(SrcRegNum)),
OS);
1461 CurOp = SrcRegNum + 1;
1465 unsigned CC =
MI.getOperand(8).getImm();
1466 emitByte(BaseOpcode +
CC,
OS);
1468 emitMemModRMByte(
MI, CurOp + 1, getX86RegNum(
MI.getOperand(0)),
TSFlags,
1469 Kind, StartByte,
OS, Fixups, STI,
false);
1470 CurOp = SrcRegNum + 3;
1475 emitByte(BaseOpcode,
OS);
1485 emitMemModRMByte(
MI, CurOp, getX86RegNum(
MI.getOperand(SrcRegNum)),
TSFlags,
1486 Kind, StartByte,
OS, Fixups, STI, ForceSIB);
1487 CurOp = SrcRegNum + 1;
1491 emitByte(BaseOpcode,
OS);
1492 unsigned SrcRegNum = CurOp + 1;
1500 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1501 getX86RegNum(
MI.getOperand(CurOp)),
OS);
1502 CurOp = SrcRegNum + 1;
1504 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1511 emitByte(BaseOpcode,
OS);
1512 unsigned SrcRegNum = CurOp + 1;
1514 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1515 getX86RegNum(
MI.getOperand(CurOp)),
OS);
1516 CurOp = SrcRegNum + 1;
1521 emitByte(BaseOpcode,
OS);
1522 unsigned SrcRegNum = CurOp + 1;
1528 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1529 I8RegNum = getX86RegEncoding(
MI, SrcRegNum++);
1531 emitRegModRMByte(
MI.getOperand(SrcRegNum),
1532 getX86RegNum(
MI.getOperand(CurOp)),
OS);
1533 CurOp = SrcRegNum + 1;
1537 unsigned FirstOp = CurOp++;
1538 unsigned SecondOp = CurOp++;
1540 unsigned CC =
MI.getOperand(CurOp++).getImm();
1541 emitByte(BaseOpcode +
CC,
OS);
1543 emitRegModRMByte(
MI.getOperand(SecondOp),
1544 getX86RegNum(
MI.getOperand(FirstOp)),
OS);
1549 unsigned FirstMemOp = CurOp + 1;
1557 emitByte(BaseOpcode,
OS);
1560 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1561 TSFlags, Kind, StartByte,
OS, Fixups, STI, ForceSIB);
1564 I8RegNum = getX86RegEncoding(
MI, CurOp++);
1568 unsigned FirstMemOp = CurOp + 1;
1570 emitByte(BaseOpcode,
OS);
1572 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1573 TSFlags, Kind, StartByte,
OS, Fixups, STI);
1579 unsigned FirstMemOp = CurOp + 1;
1584 assert(HasVEX_I8Reg &&
"MRMSrcRegOp4 should imply VEX_I8Reg");
1585 I8RegNum = getX86RegEncoding(
MI, FirstMemOp++);
1587 emitByte(BaseOpcode,
OS);
1589 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(CurOp)),
1590 TSFlags, Kind, StartByte,
OS, Fixups, STI);
1595 unsigned RegOp = CurOp++;
1596 unsigned FirstMemOp = CurOp;
1599 unsigned CC =
MI.getOperand(CurOp++).getImm();
1600 emitByte(BaseOpcode +
CC,
OS);
1602 emitMemModRMByte(
MI, FirstMemOp, getX86RegNum(
MI.getOperand(RegOp)),
1603 TSFlags, Kind, StartByte,
OS, Fixups, STI);
1608 unsigned RegOp = CurOp++;
1610 unsigned CC =
MI.getOperand(CurOp++).getImm();
1611 emitByte(BaseOpcode +
CC,
OS);
1612 emitRegModRMByte(
MI.getOperand(RegOp), 0,
OS);
1629 emitByte(BaseOpcode,
OS);
1630 emitRegModRMByte(
MI.getOperand(CurOp++),
1634 emitByte(BaseOpcode,
OS);
1635 emitByte(
modRMByte(3, getX86RegNum(
MI.getOperand(CurOp++)),0),
OS);
1639 unsigned FirstMemOp = CurOp;
1642 unsigned CC =
MI.getOperand(CurOp++).getImm();
1643 emitByte(BaseOpcode +
CC,
OS);
1645 emitMemModRMByte(
MI, FirstMemOp, 0,
TSFlags, Kind, StartByte,
OS, Fixups,
1663 emitByte(BaseOpcode,
OS);
1664 emitMemModRMByte(
MI, CurOp,
1666 Kind, StartByte,
OS, Fixups, STI);
1678 emitByte(BaseOpcode,
OS);
1746 emitByte(BaseOpcode,
OS);
1754 assert(I8RegNum < 16 &&
"Register encoding out of range");
1756 if (CurOp != NumOps) {
1757 unsigned Val =
MI.getOperand(CurOp++).getImm();
1758 assert(Val < 16 &&
"Immediate operand value out of range");
1762 StartByte,
OS, Fixups);
1767 while (CurOp != NumOps && NumOps - CurOp <= 2) {
1768 emitImmediate(
MI.getOperand(CurOp++),
MI.getLoc(),
1770 StartByte,
OS, Fixups);
1778 "The size of instruction must be no longer than 15.");
1781 if ( CurOp != NumOps) {
1782 errs() <<
"Cannot encode all operands of: ";
1792 return new X86MCCodeEmitter(MCII, Ctx);
unsigned const MachineRegisterInfo * MRI
static bool isPCRel(unsigned Kind)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
static MCFixupKind getImmFixupKind(uint64_t TSFlags)
static bool isPCRel32Branch(const MCInst &MI, const MCInstrInfo &MCII)
static GlobalOffsetTableExprKind startsWithGlobalOffsetTable(const MCExpr *Expr)
Check if this expression starts with GLOBAL_OFFSET_TABLE and if it is of the form GLOBAL_OFFSET_TABLE...
static uint8_t modRMByte(unsigned Mod, unsigned RegOpcode, unsigned RM)
static bool isDispOrCDisp8(uint64_t TSFlags, int Value, int &ImmOffset)
Determine if this immediate can fit in a disp8 or a compressed disp8 for EVEX instructions.
GlobalOffsetTableExprKind
static void emitConstant(uint64_t Val, unsigned Size, raw_ostream &OS)
static bool hasSecRelSymbolRef(const MCExpr *Expr)
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, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
virtual void emitPrefix(const MCInst &Inst, raw_ostream &OS, const MCSubtargetInfo &STI) const
Emit the prefixes of given instruction on the output stream.
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.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
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...
bool isX32() const
Tests whether the target is X32.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
uint64_t tell() const
tell - Return the current offset with the file.
#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.
@ 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...
@ MRMSrcMemCC
MRMSrcMemCC - This form is used for instructions that use the Mod/RM byte to specify the operands and...
@ MRM_C0
MRM_XX - 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...
@ PrefixByte
PrefixByte - This form is used for instructions that represent a prefix byte like data16 or rep.
@ MRMr0
MRM[0-7][rm] - These forms are used to represent instructions that use a Mod/RM byte,...
@ MRMXm
MRMXm - This form is used for instructions that use the Mod/RM byte to specify a memory source,...
@ 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...
@ RawFrmImm8
RawFrmImm8 - This is used for the ENTER instruction, which has two immediates, the first of which is ...
@ 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....
@ 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,...
@ 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...
@ MRMSrcRegCC
MRMSrcRegCC - This form is used for instructions that use the Mod/RM byte to specify the operands and...
@ ThreeDNow
ThreeDNow - This indicates that the instruction uses the wacky 0x0F 0x0F prefix for 3DNow!...
@ 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 isX86_64NonExtLowByteReg(unsigned 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.
uint8_t getBaseOpcodeFor(uint64_t TSFlags)
int getMemoryOperandNo(uint64_t TSFlags)
The function returns the MCInst operand # for the first field of the memory operand.
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.
@ AddrSegmentReg
AddrSegmentReg - The operand # of the segment in the memory operand.
@ AddrNumOperands
AddrNumOperands - Total number of operands in a memory reference.
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.
constexpr std::nullopt_t None