43class X86AlignBranchKind {
45 uint8_t AlignBranchKind = 0;
48 void operator=(
const std::string &Val) {
52 StringRef(Val).split(BranchTypes,
'+', -1,
false);
53 for (
auto BranchType : BranchTypes) {
54 if (BranchType ==
"fused")
56 else if (BranchType ==
"jcc")
58 else if (BranchType ==
"jmp")
60 else if (BranchType ==
"call")
62 else if (BranchType ==
"ret")
64 else if (BranchType ==
"indirect")
68 <<
" to -x86-align-branch=; each element must be one of: fused, "
69 "jcc, jmp, call, ret, indirect.(plus separated)\n";
74 operator uint8_t()
const {
return AlignBranchKind; }
78X86AlignBranchKind X86AlignBranchKindLoc;
81 "x86-align-branch-boundary",
cl::init(0),
83 "Control how the assembler should align branches with NOP. If the "
84 "boundary's size is not 0, it should be a power of 2 and no less "
85 "than 32. Branches will be aligned to prevent from being across or "
86 "against the boundary of specified size. The default value 0 does not "
92 "Specify types of branches to align (plus separated list of types):"
93 "\njcc indicates conditional jumps"
94 "\nfused indicates fused conditional jumps"
95 "\njmp indicates direct unconditional jumps"
96 "\ncall indicates direct and indirect calls"
97 "\nret indicates rets"
98 "\nindirect indicates indirect unconditional jumps"),
102 "x86-branches-within-32B-boundaries",
cl::init(
false),
104 "Align selected instructions to mitigate negative performance impact "
105 "of Intel's micro code update for errata skx102. May break "
106 "assumptions about labels corresponding to particular instructions, "
107 "and should be used with caution."));
110 "x86-pad-max-prefix-size",
cl::init(0),
111 cl::desc(
"Maximum number of prefixes to use for padding"));
115 cl::desc(
"Pad previous instructions to implement align directives"));
119 cl::desc(
"Pad previous instructions to implement branch alignment"));
122 const MCSubtargetInfo &STI;
123 std::unique_ptr<const MCInstrInfo> MCII;
124 X86AlignBranchKind AlignBranchType;
126 unsigned TargetPrefixMax = 0;
129 unsigned PrevInstOpcode = 0;
130 bool PrefixEndsBundleLock =
false;
131 MCBoundaryAlignFragment *PendingBA =
nullptr;
132 std::pair<MCFragment *, size_t> PrevInstPosition;
134 uint8_t determinePaddingPrefix(
const MCInst &Inst)
const;
135 bool isMacroFused(
const MCInst &Cmp,
const MCInst &Jcc)
const;
136 bool needAlign(
const MCInst &Inst)
const;
137 bool canPadBranches(MCObjectStreamer &OS)
const;
138 bool canPadInst(
const MCInst &Inst, MCObjectStreamer &OS)
const;
139 void emitInstructionBeginBundle(MCObjectStreamer &OS);
140 void emitInstructionEndBundle(MCObjectStreamer &OS);
143 X86AsmBackend(
const Target &
T,
const MCSubtargetInfo &STI)
146 if (X86AlignBranchWithin32BBoundaries) {
157 if (X86AlignBranchBoundary.getNumOccurrences())
159 if (X86AlignBranch.getNumOccurrences())
160 AlignBranchType = X86AlignBranchKindLoc;
161 if (X86PadMaxPrefixSize.getNumOccurrences())
162 TargetPrefixMax = X86PadMaxPrefixSize;
166 AllowEnhancedRelaxation =
167 AllowAutoPadding && TargetPrefixMax != 0 && X86PadForBranchAlign;
168 AllowBundling =
true;
172 void reset()
override {
175 PrefixEndsBundleLock =
false;
177 PrevInstPosition = {};
180 void emitInstructionBegin(MCObjectStreamer &OS,
const MCInst &Inst,
181 const MCSubtargetInfo &STI);
182 void emitInstructionEnd(MCObjectStreamer &OS,
const MCInst &Inst);
185 std::optional<MCFixupKind>
getFixupKind(StringRef Name)
const override;
187 MCFixupKindInfo getFixupKindInfo(
MCFixupKind Kind)
const override;
189 std::optional<bool> evaluateFixup(
const MCFragment &, MCFixup &, MCValue &,
191 void applyFixup(
const MCFragment &,
const MCFixup &,
const MCValue &Target,
195 const MCSubtargetInfo &STI)
const override;
197 bool fixupNeedsRelaxationAdvanced(
const MCFragment &,
const MCFixup &,
199 bool)
const override;
201 void relaxInstruction(MCInst &Inst,
202 const MCSubtargetInfo &STI)
const override;
204 bool padInstructionViaRelaxation(MCFragment &RF, MCCodeEmitter &
Emitter,
205 unsigned &RemainingSize)
const;
207 bool padInstructionViaPrefix(MCFragment &RF, MCCodeEmitter &
Emitter,
208 unsigned &RemainingSize)
const;
210 bool padInstructionEncoding(MCFragment &RF, MCCodeEmitter &
Emitter,
211 unsigned &RemainingSize)
const;
213 bool finishLayout()
const override;
215 bool padInstsBackward(SmallVectorImpl<MCFragment *> &Relaxable,
216 unsigned &RemainingSize)
const;
217 bool foldBundlePad(
const MCAssembler &Asm, MCBoundaryAlignFragment &BF,
218 SmallVectorImpl<MCFragment *> &Relaxable)
const;
219 bool optimizeBundleNops(
const MCAssembler &Asm)
const;
221 unsigned getMaximumNopSize(
const MCSubtargetInfo &STI)
const override;
224 const MCSubtargetInfo *STI)
const override;
229 return Opcode == X86::JCC_1 || Opcode == X86::JMP_1;
233 bool Is16BitMode =
false) {
238 return (Is16BitMode) ? X86::JCC_2 : X86::JCC_4;
240 return (Is16BitMode) ? X86::JMP_2 : X86::JMP_4;
245 unsigned Opcode =
MI.getOpcode();
252 unsigned Opcode =
MI.getOpcode();
259 MI.getOperand(
Desc.getNumOperands() - 1).getImm());
267 return classifySecondCondCodeInMacroFusion(CC);
274 if (MemoryOperand < 0)
277 MCRegister BaseReg =
MI.getOperand(BaseRegNum).getReg();
278 return (BaseReg == X86::RIP);
306uint8_t X86AsmBackend::determinePaddingPrefix(
const MCInst &Inst)
const {
308 "Prefixes can be added only in 32-bit or 64-bit mode.");
315 MCRegister SegmentReg;
316 if (MemoryOperand >= 0) {
349 if (MemoryOperand >= 0) {
352 if (BaseReg == X86::ESP || BaseReg == X86::EBP)
359bool X86AsmBackend::isMacroFused(
const MCInst &Cmp,
const MCInst &Jcc)
const {
360 const MCInstrDesc &InstDesc = MCII->get(Jcc.
getOpcode());
374 for (
auto &Operand :
MI) {
375 if (!Operand.isExpr())
377 const MCExpr &Expr = *Operand.getExpr();
389 switch (InstOpcode) {
408bool X86AsmBackend::canPadInst(
const MCInst &Inst, MCObjectStreamer &OS)
const {
419 if (
isPrefix(PrevInstOpcode, *MCII))
433 Offset != PrevInstPosition.second))
439bool X86AsmBackend::canPadBranches(MCObjectStreamer &OS)
const {
442 assert(allowAutoPadding() &&
"incorrect initialization!");
456bool X86AsmBackend::needAlign(
const MCInst &Inst)
const {
458 return (
Desc.isConditionalBranch() &&
460 (
Desc.isUnconditionalBranch() &&
464 (
Desc.isIndirectBranch() &&
471 if (
LLVM_LIKELY(!AutoPadding && !X86PadForAlign)) {
472 S.MCObjectStreamer::emitInstruction(Inst, STI);
482 auto &Backend =
static_cast<X86AsmBackend &
>(S.
getAssembler().getBackend());
483 Backend.emitInstructionBegin(S, Inst, STI);
484 S.MCObjectStreamer::emitInstruction(Inst, STI);
485 Backend.emitInstructionEnd(S, Inst);
492 assert(Asm->isBundlingEnabled());
498 "instruction prefix cannot be the last "
499 "instruction of a .bundle_lock group");
512 Asm->getBundleAlign(), STI);
523void X86AsmBackend::emitInstructionEndBundle(MCObjectStreamer &OS) {
527 PrefixEndsBundleLock =
isPrefix(PrevInstOpcode, *MCII);
530 PrefixEndsBundleLock =
false;
531 assert(PendingBA &&
"MCBoundaryAlignFragment is expected for every "
532 "instruction if it is not bundle-locked");
536 if (!
isPrefix(PrevInstOpcode, *MCII))
541void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
543 const MCSubtargetInfo &STI) {
544 bool CanPadInst = canPadInst(Inst, OS);
545 if (
Asm->isBundlingEnabled()) {
546 emitInstructionBeginBundle(OS);
553 if (!canPadBranches(OS))
569 auto *NextFragment = PendingBA->
getNext();
570 assert(NextFragment &&
"NextFragment should not be null");
609void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
610 const MCInst &Inst) {
615 if (
Asm->isBundlingEnabled())
616 return emitInstructionEndBundle(OS);
618 if (!canPadBranches(OS))
624 if (!needAlign(Inst) || !PendingBA)
641std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name)
const {
645 Type = llvm::StringSwitch<unsigned>(Name)
646#define ELF_RELOC(X, Y) .Case(#X, Y)
647#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
649 .Case(
"BFD_RELOC_NONE", ELF::R_X86_64_NONE)
650 .Case(
"BFD_RELOC_8", ELF::R_X86_64_8)
651 .Case(
"BFD_RELOC_16", ELF::R_X86_64_16)
652 .Case(
"BFD_RELOC_32", ELF::R_X86_64_32)
653 .Case(
"BFD_RELOC_64", ELF::R_X86_64_64)
656 Type = llvm::StringSwitch<unsigned>(Name)
657#define ELF_RELOC(X, Y) .Case(#X, Y)
658#include "llvm/BinaryFormat/ELFRelocs/i386.def"
660 .Case(
"BFD_RELOC_NONE", ELF::R_386_NONE)
661 .Case(
"BFD_RELOC_8", ELF::R_386_8)
662 .Case(
"BFD_RELOC_16", ELF::R_386_16)
663 .Case(
"BFD_RELOC_32", ELF::R_386_32)
673MCFixupKindInfo X86AsmBackend::getFixupKindInfo(
MCFixupKind Kind)
const {
676 {
"reloc_riprel_4byte", 0, 32, 0},
677 {
"reloc_riprel_4byte_movq_load", 0, 32, 0},
678 {
"reloc_riprel_4byte_movq_load_rex2", 0, 32, 0},
679 {
"reloc_riprel_4byte_relax", 0, 32, 0},
680 {
"reloc_riprel_4byte_relax_rex", 0, 32, 0},
681 {
"reloc_riprel_4byte_relax_rex2", 0, 32, 0},
682 {
"reloc_riprel_4byte_relax_evex", 0, 32, 0},
683 {
"reloc_signed_4byte", 0, 32, 0},
684 {
"reloc_signed_4byte_relax", 0, 32, 0},
685 {
"reloc_global_offset_table", 0, 32, 0},
686 {
"reloc_branch_4byte_pcrel", 0, 32, 0},
740std::optional<bool> X86AsmBackend::evaluateFixup(
const MCFragment &,
743 if (
Fixup.isPCRel()) {
744 switch (
Fixup.getKind()) {
767void X86AsmBackend::applyFixup(
const MCFragment &
F,
const MCFixup &
Fixup,
768 const MCValue &Target, uint8_t *
Data,
772 if (
Target.getSpecifier())
774 maybeAddReloc(
F,
Fixup, Target,
Value, IsResolved);
797 "value of " + Twine(int64_t(
Value)) +
798 " is too large for field of " + Twine(
Size) +
799 (
Size == 1 ?
" byte" :
" bytes"));
802 for (
unsigned i = 0; i !=
Size; ++i)
806bool X86AsmBackend::mayNeedRelaxation(
unsigned Opcode,
808 const MCSubtargetInfo &STI)
const {
809 unsigned SkipOperands = X86::isCCMPCC(Opcode) ? 2 : 0;
815bool X86AsmBackend::fixupNeedsRelaxationAdvanced(
const MCFragment &
F,
816 const MCFixup &
Fixup,
817 const MCValue &Target,
819 bool Resolved)
const {
828 int64_t Slack =
Asm->isBundlingEnabled() && TargetPrefixMax != 0 &&
830 ?
Asm->getBundleAlign().value()
845void X86AsmBackend::relaxInstruction(MCInst &Inst,
846 const MCSubtargetInfo &STI)
const {
848 bool Is16BitMode = STI.
hasFeature(X86::Is16Bit);
854bool X86AsmBackend::padInstructionViaPrefix(MCFragment &RF,
856 unsigned &RemainingSize)
const {
871 const unsigned MaxPossiblePad = std::min(15 - OldSize, RemainingSize);
872 const unsigned RemainingPrefixSize = [&]() ->
unsigned {
873 SmallString<15>
Code;
875 assert(
Code.size() < 15 &&
"The number of prefixes must be less than 15.");
882 unsigned ExistingPrefixSize =
Code.size();
883 if (TargetPrefixMax <= ExistingPrefixSize)
885 return TargetPrefixMax - ExistingPrefixSize;
887 const unsigned PrefixBytesToAdd =
888 std::min(MaxPossiblePad, RemainingPrefixSize);
889 if (PrefixBytesToAdd == 0)
894 SmallString<256>
Code;
895 Code.append(PrefixBytesToAdd, Prefix);
901 F.setOffset(PrefixBytesToAdd +
F.getOffset());
903 RemainingSize -= PrefixBytesToAdd;
907bool X86AsmBackend::padInstructionViaRelaxation(MCFragment &RF,
909 unsigned &RemainingSize)
const {
920 SmallString<15>
Code;
923 const unsigned NewSize =
Code.size();
924 assert(NewSize >= OldSize &&
"size decrease during relaxation?");
925 unsigned Delta = NewSize - OldSize;
926 if (Delta > RemainingSize)
931 RemainingSize -= Delta;
935bool X86AsmBackend::padInstructionEncoding(MCFragment &RF,
937 unsigned &RemainingSize)
const {
939 if (RemainingSize != 0)
940 Changed |= padInstructionViaRelaxation(RF,
Emitter, RemainingSize);
941 if (RemainingSize != 0)
946bool X86AsmBackend::padInstsBackward(SmallVectorImpl<MCFragment *> &Relaxable,
947 unsigned &RemainingSize)
const {
949 while (!Relaxable.
empty() && RemainingSize != 0) {
954 Changed |= padInstructionEncoding(RF,
Asm->getEmitter(), RemainingSize);
974bool X86AsmBackend::foldBundlePad(
975 const MCAssembler &Asm, MCBoundaryAlignFragment &BF,
976 SmallVectorImpl<MCFragment *> &Relaxable)
const {
977 const uint64_t BundleSize =
Asm.getBundleAlign().value();
978 const uint64_t PadStart =
Asm.getFragmentOffset(BF);
979 unsigned Remaining = BF.
getSize();
984 std::min<uint64_t>(Remaining, BundleSize - PadStart % BundleSize);
985 unsigned Left = Budget;
987 Remaining -= Budget -
Left;
995 GroupSize +=
Asm.computeFragmentSize(*
F);
999 if (GroupSize < BundleSize) {
1000 Left = Budget = std::min<uint64_t>(Remaining, BundleSize - GroupSize);
1007 Remaining -= Budget -
Left;
1015bool X86AsmBackend::optimizeBundleNops(
const MCAssembler &Asm)
const {
1016 const uint64_t BundleSize =
Asm.getBundleAlign().value();
1018 for (MCSection &Sec : Asm) {
1026 const MCFragment *ResumeAfter =
nullptr;
1027 for (MCFragment &
F : Sec) {
1029 if (&
F == ResumeAfter)
1030 ResumeAfter =
nullptr;
1034 if (!Relaxable.
empty() &&
1035 Asm.getFragmentOffset(*Relaxable.
front()) / BundleSize !=
1039 switch (
F.getKind()) {
1041 auto &BF =
static_cast<MCBoundaryAlignFragment &
>(
F);
1044 Changed |= foldBundlePad(Asm, BF, Relaxable);
1064bool X86AsmBackend::finishLayout()
const {
1067 if (
Asm->isBundlingEnabled())
1068 return TargetPrefixMax != 0 && optimizeBundleNops(*Asm);
1075 if (!X86PadForAlign && !X86PadForBranchAlign)
1081 DenseSet<MCFragment *> LabeledFragments;
1082 for (
const MCSymbol &S :
Asm->symbols())
1083 LabeledFragments.
insert(S.getFragment());
1086 for (MCSection &Sec : *Asm) {
1091 for (MCSection::iterator
I = Sec.begin(), IE = Sec.end();
I != IE; ++
I) {
1094 if (LabeledFragments.
count(&
F))
1106 auto canHandle = [](MCFragment &
F) ->
bool {
1107 switch (
F.getKind()) {
1111 return X86PadForAlign;
1113 return X86PadForBranchAlign;
1117 if (!canHandle(
F)) {
1126 unsigned RemainingSize =
Asm->computeFragmentSize(
F) -
F.getFixedSize();
1127 Changed |= padInstsBackward(Relaxable, RemainingSize);
1138 while (&*
I != LastFragment)
1147unsigned X86AsmBackend::getMaximumNopSize(
const MCSubtargetInfo &STI)
const {
1154 if (STI.
hasFeature(X86::TuningFast15ByteNOP))
1156 if (STI.
hasFeature(X86::TuningFast11ByteNOP))
1167bool X86AsmBackend::writeNopData(raw_ostream &OS,
uint64_t Count,
1168 const MCSubtargetInfo *STI)
const {
1169 static const char Nops32Bit[10][11] = {
1179 "\x0f\x1f\x44\x00\x00",
1181 "\x66\x0f\x1f\x44\x00\x00",
1183 "\x0f\x1f\x80\x00\x00\x00\x00",
1185 "\x0f\x1f\x84\x00\x00\x00\x00\x00",
1187 "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
1189 "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
1193 static const char Nops16Bit[4][11] = {
1204 const char(*Nops)[11] =
1205 STI->
hasFeature(X86::Is16Bit) ? Nops16Bit : Nops32Bit;
1212 const uint8_t ThisNopLength = (uint8_t) std::min(
Count, MaxNopLength);
1213 const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
1214 for (uint8_t i = 0; i < Prefixes; i++)
1216 const uint8_t Rest = ThisNopLength - Prefixes;
1218 OS.
write(Nops[Rest - 1], Rest);
1219 Count -= ThisNopLength;
1220 }
while (
Count != 0);
1229class ELFX86AsmBackend :
public X86AsmBackend {
1232 ELFX86AsmBackend(
const Target &
T, uint8_t OSABI,
const MCSubtargetInfo &STI)
1233 : X86AsmBackend(
T, STI), OSABI(OSABI) {}
1236class ELFX86_32AsmBackend :
public ELFX86AsmBackend {
1238 ELFX86_32AsmBackend(
const Target &
T, uint8_t OSABI,
1239 const MCSubtargetInfo &STI)
1240 : ELFX86AsmBackend(
T, OSABI, STI) {}
1242 std::unique_ptr<MCObjectTargetWriter>
1243 createObjectTargetWriter()
const override {
1248class ELFX86_X32AsmBackend :
public ELFX86AsmBackend {
1250 ELFX86_X32AsmBackend(
const Target &
T, uint8_t OSABI,
1251 const MCSubtargetInfo &STI)
1252 : ELFX86AsmBackend(
T, OSABI, STI) {}
1254 std::unique_ptr<MCObjectTargetWriter>
1255 createObjectTargetWriter()
const override {
1261class ELFX86_IAMCUAsmBackend :
public ELFX86AsmBackend {
1263 ELFX86_IAMCUAsmBackend(
const Target &
T, uint8_t OSABI,
1264 const MCSubtargetInfo &STI)
1265 : ELFX86AsmBackend(
T, OSABI, STI) {}
1267 std::unique_ptr<MCObjectTargetWriter>
1268 createObjectTargetWriter()
const override {
1274class ELFX86_64AsmBackend :
public ELFX86AsmBackend {
1276 ELFX86_64AsmBackend(
const Target &
T, uint8_t OSABI,
1277 const MCSubtargetInfo &STI)
1278 : ELFX86AsmBackend(
T, OSABI, STI) {}
1280 std::unique_ptr<MCObjectTargetWriter>
1281 createObjectTargetWriter()
const override {
1286class WindowsX86AsmBackend :
public X86AsmBackend {
1290 WindowsX86AsmBackend(
const Target &
T,
bool is64Bit,
1291 const MCSubtargetInfo &STI)
1292 : X86AsmBackend(
T, STI)
1296 std::optional<MCFixupKind>
getFixupKind(StringRef Name)
const override {
1297 return StringSwitch<std::optional<MCFixupKind>>(
Name)
1304 std::unique_ptr<MCObjectTargetWriter>
1305 createObjectTargetWriter()
const override {
1313 enum CompactUnwindEncodings {
1316 UNWIND_MODE_BP_FRAME = 0x01000000,
1319 UNWIND_MODE_STACK_IMMD = 0x02000000,
1322 UNWIND_MODE_STACK_IND = 0x03000000,
1325 UNWIND_MODE_DWARF = 0x04000000,
1328 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
1331 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
1336class DarwinX86AsmBackend :
public X86AsmBackend {
1337 const MCRegisterInfo &MRI;
1340 enum { CU_NUM_SAVED_REGS = 6 };
1342 mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
1346 unsigned OffsetSize;
1347 unsigned MoveInstrSize;
1348 unsigned StackDivide;
1351 unsigned PushInstrSize(MCRegister
Reg)
const {
1374 int getCompactUnwindRegNum(
unsigned Reg)
const {
1375 static const MCPhysReg CU32BitRegs[7] = {
1376 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
1378 static const MCPhysReg CU64BitRegs[] = {
1379 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
1381 const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
1382 for (
int Idx = 1; *CURegs; ++CURegs, ++Idx)
1391 uint32_t encodeCompactUnwindRegistersWithFrame()
const {
1395 uint32_t RegEnc = 0;
1396 for (
int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
1397 unsigned Reg = SavedRegs[i];
1398 if (
Reg == 0)
break;
1400 int CURegNum = getCompactUnwindRegNum(
Reg);
1401 if (CURegNum == -1)
return ~0
U;
1405 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
1408 assert((RegEnc & 0x3FFFF) == RegEnc &&
1409 "Invalid compact register encoding!");
1416 uint32_t encodeCompactUnwindRegistersWithoutFrame(
unsigned RegCount)
const {
1430 for (
unsigned i = 0; i < RegCount; ++i) {
1431 int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
1432 if (CUReg == -1)
return ~0
U;
1433 SavedRegs[i] = CUReg;
1437 std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
1439 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
1440 for (
unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
1441 unsigned Countless = 0;
1442 for (
unsigned j = CU_NUM_SAVED_REGS - RegCount;
j < i; ++
j)
1443 if (SavedRegs[j] < SavedRegs[i])
1446 RenumRegs[i] = SavedRegs[i] - Countless - 1;
1450 uint32_t permutationEncoding = 0;
1453 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
1454 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
1458 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
1459 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
1463 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
1464 + 3 * RenumRegs[4] + RenumRegs[5];
1467 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
1471 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
1474 permutationEncoding |= RenumRegs[5];
1478 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
1479 "Invalid compact register encoding!");
1480 return permutationEncoding;
1484 DarwinX86AsmBackend(
const Target &
T,
const MCRegisterInfo &MRI,
1485 const MCSubtargetInfo &STI)
1486 : X86AsmBackend(
T, STI), MRI(MRI),
TT(STI.getTargetTriple()),
1487 Is64Bit(
TT.isX86_64()) {
1488 memset(SavedRegs, 0,
sizeof(SavedRegs));
1489 OffsetSize = Is64Bit ? 8 : 4;
1490 MoveInstrSize = Is64Bit ? 3 : 2;
1491 StackDivide = Is64Bit ? 8 : 4;
1494 std::unique_ptr<MCObjectTargetWriter>
1495 createObjectTargetWriter()
const override {
1503 uint64_t generateCompactUnwindEncoding(
const MCDwarfFrameInfo *FI,
1504 const MCContext *Ctxt)
const override {
1506 return CU::UNWIND_MODE_DWARF;
1510 return CU::UNWIND_MODE_DWARF;
1513 if (Instrs.
empty())
return 0;
1514 if (!isDarwinCanonicalPersonality(FI->
Personality) &&
1516 return CU::UNWIND_MODE_DWARF;
1519 unsigned SavedRegIdx = 0;
1520 memset(SavedRegs, 0,
sizeof(SavedRegs));
1525 uint64_t CompactUnwindEncoding = 0;
1527 unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
1528 unsigned InstrOffset = 0;
1529 unsigned StackAdjust = 0;
1531 int64_t MinAbsOffset = std::numeric_limits<int64_t>::max();
1533 for (
const MCCFIInstruction &Inst : Instrs) {
1534 switch (Inst.getOperation()) {
1538 return CU::UNWIND_MODE_DWARF;
1551 (Is64Bit ? X86::RBP : X86::EBP))
1552 return CU::UNWIND_MODE_DWARF;
1555 memset(SavedRegs, 0,
sizeof(SavedRegs));
1558 MinAbsOffset = std::numeric_limits<int64_t>::max();
1559 InstrOffset += MoveInstrSize;
1577 StackSize = Inst.getOffset() / StackDivide;
1593 if (SavedRegIdx == CU_NUM_SAVED_REGS)
1596 return CU::UNWIND_MODE_DWARF;
1599 SavedRegs[SavedRegIdx++] =
Reg.
id();
1600 StackAdjust += OffsetSize;
1601 MinAbsOffset = std::min(MinAbsOffset, std::abs(Inst.getOffset()));
1602 InstrOffset += PushInstrSize(
Reg);
1608 StackAdjust /= StackDivide;
1611 if ((StackAdjust & 0xFF) != StackAdjust)
1613 return CU::UNWIND_MODE_DWARF;
1617 if (SavedRegIdx != 0 && MinAbsOffset != 3 * (
int)OffsetSize)
1618 return CU::UNWIND_MODE_DWARF;
1621 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
1622 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
1624 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
1625 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
1626 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
1628 SubtractInstrIdx += InstrOffset;
1631 if ((StackSize & 0xFF) == StackSize) {
1633 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
1636 CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
1638 if ((StackAdjust & 0x7) != StackAdjust)
1640 return CU::UNWIND_MODE_DWARF;
1643 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
1647 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
1650 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
1654 std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]);
1655 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
1659 uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
1660 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
1663 CompactUnwindEncoding |=
1664 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
1667 return CompactUnwindEncoding;
1679 return new DarwinX86AsmBackend(
T, MRI, STI);
1682 return new WindowsX86AsmBackend(
T,
false, STI);
1687 return new ELFX86_IAMCUAsmBackend(
T, OSABI, STI);
1689 return new ELFX86_32AsmBackend(
T, OSABI, STI);
1698 return new DarwinX86AsmBackend(
T, MRI, STI);
1701 return new WindowsX86AsmBackend(
T,
true, STI);
1703 if (TheTriple.
isUEFI()) {
1705 "Only COFF format is supported in UEFI environment.");
1706 return new WindowsX86AsmBackend(
T,
true, STI);
1711 if (TheTriple.
isX32())
1712 return new ELFX86_X32AsmBackend(
T, OSABI, STI);
1713 return new ELFX86_64AsmBackend(
T, OSABI, STI);
1719 X86ELFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
1720 std::unique_ptr<MCObjectWriter> OW,
1721 std::unique_ptr<MCCodeEmitter>
Emitter)
1725 void emitInstruction(
const MCInst &Inst,
const MCSubtargetInfo &STI)
override;
1729void X86ELFStreamer::emitInstruction(
const MCInst &Inst,
1730 const MCSubtargetInfo &STI) {
1735 std::unique_ptr<MCAsmBackend> &&MAB,
1736 std::unique_ptr<MCObjectWriter> &&MOW,
1737 std::unique_ptr<MCCodeEmitter> &&MCE) {
1738 return new X86ELFStreamer(Context, std::move(MAB), std::move(MOW),
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_LIKELY(EXPR)
dxil DXContainer Global Emitter
static unsigned getRelaxedOpcode(unsigned Opcode)
This file declares the MCLFIRewriter class, an abstract class that encapsulates the rewriting logic f...
PowerPC TLS Dynamic Call Fixup
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static MCInstrInfo * createMCInstrInfo()
static unsigned getRelaxedOpcodeBranch(unsigned Opcode, bool Is16BitMode=false)
static X86::SecondMacroFusionInstKind classifySecondInstInMacroFusion(const MCInst &MI, const MCInstrInfo &MCII)
static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII)
Check if the instruction uses RIP relative addressing.
static bool mayHaveInterruptDelaySlot(unsigned InstOpcode)
X86 has certain instructions which enable interrupts exactly one instruction after the instruction wh...
static bool isFirstMacroFusibleInst(const MCInst &Inst, const MCInstrInfo &MCII)
Check if the instruction is valid as the first instruction in macro fusion.
constexpr char GotSymName[]
static X86::CondCode getCondFromBranch(const MCInst &MI, const MCInstrInfo &MCII)
static unsigned getRelaxedOpcode(const MCInst &MI, bool Is16BitMode)
static unsigned getFixupKindSize(unsigned Kind)
static bool isRelaxableBranch(unsigned Opcode)
static bool isPrefix(unsigned Opcode, const MCInstrInfo &MCII)
Check if the instruction is a prefix.
static bool hasVariantSymbol(const MCInst &MI)
Check if the instruction has a variant symbol operand.
static bool is64Bit(const char *name)
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
Generic interface to target specific assembler backends.
virtual MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const
Get information on a fixup kind.
virtual std::optional< MCFixupKind > getFixupKind(StringRef Name) const
Map a relocation name used in .reloc to a fixup kind.
Represents required padding such that a particular other set of fragments does not cross a particular...
void setSize(uint64_t Value)
const MCFragment * getLastFragment() const
bool isAlignToEnd() const
void setLastFragment(const MCFragment *F)
Context object for machine code objects.
LLVM_ABI bool emitCompactUnwindNonCanonical() const
LLVM_ABI EmitDwarfUnwindType emitDwarfUnwindInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
@ SymbolRef
References to labels and assigned expressions.
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
bool getAllowAutoPadding() const
void setAllowAutoPadding(bool V)
unsigned getOpcode() const
MCSection * getParent() const
LLVM_ABI void setVarFixups(ArrayRef< MCFixup > Fixups)
MCFragment * getNext() const
ArrayRef< MCOperand > getOperands() const
size_t getVarSize() const
LLVM_ABI void setVarContents(ArrayRef< char > Contents)
MutableArrayRef< char > getVarContents()
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
MutableArrayRef< MCFixup > getVarFixups()
void setInst(const MCInst &Inst)
Instances of this class represent a single low-level machine instruction.
unsigned getOpcode() const
void setOpcode(unsigned Op)
const MCOperand & getOperand(unsigned i) const
Describe properties that are true of each instruction in the target description file.
bool isConditionalBranch() const
Return true if this is a branch which may fall through to the next instruction or may transfer contro...
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.
virtual bool rewriteInst(const MCInst &Inst, MCStreamer &Out, const MCSubtargetInfo &STI)=0
Streaming object file generation interface.
FT * newSpecialFragment(Args &&...args)
MCAssembler & getAssembler()
bool isBundleLocked() const
MCRegister getReg() const
Returns the register number.
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
std::optional< MCRegister > getLLVMRegNum(uint64_t RegNum, bool isEH) const
Map a dwarf register back to a target register.
Wrapper class representing physical registers. Should be passed by value.
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Streaming machine code generation interface.
MCFragment * getCurrentFragment() const
SMLoc getStartTokLoc() const
MCLFIRewriter * getLFIRewriter()
size_t getCurFragSize() const
bool getAllowAutoPadding() const
MCSection * getCurrentSectionOnly() const
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
constexpr unsigned id() const
void push_back(const T &Elt)
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
bool isX86_64() const
Tests whether the target is x86 (64-bit).
bool isX32() const
Tests whether the target is X32.
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
OSType getOS() const
Get the parsed operating system type of this triple.
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
bool isUEFI() const
Tests whether the OS is UEFI.
bool isOSWindows() const
Tests whether the OS is Windows.
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
raw_ostream & write(unsigned char C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
LLVM_ABI Expected< uint32_t > getCPUSubType(const Triple &T)
LLVM_ABI Expected< uint32_t > getCPUType(const Triple &T)
VE::Fixups getFixupKind(uint8_t S)
bool isPrefix(uint64_t TSFlags)
int getMemoryOperandIdx(const MCInstrDesc &Desc)
@ RawFrmDstSrc
RawFrmDstSrc - This form is for instructions that use the source index register SI/ESI/RSI with a pos...
@ RawFrmSrc
RawFrmSrc - This form is for instructions that use the source index register SI/ESI/RSI with a possib...
@ RawFrmMemOffs
RawFrmMemOffs - This form is for instructions that store an absolute memory offset as an immediate wi...
void emitPrefix(MCCodeEmitter &MCE, const MCInst &MI, SmallVectorImpl< char > &CB, const MCSubtargetInfo &STI)
void emitInstruction(MCObjectStreamer &, const MCInst &Inst, const MCSubtargetInfo &STI)
FirstMacroFusionInstKind classifyFirstOpcodeInMacroFusion(unsigned Opcode)
AlignBranchBoundaryKind
Defines the possible values of the branch boundary alignment mask.
SecondMacroFusionInstKind
EncodingOfSegmentOverridePrefix getSegmentOverridePrefixForReg(MCRegister Reg)
Given a segment register, return the encoding of the segment override prefix for it.
unsigned getOpcodeForLongImmediateForm(unsigned Opcode)
bool isMacroFused(FirstMacroFusionInstKind FirstKind, SecondMacroFusionInstKind SecondKind)
@ 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
initializer< Ty > init(const Ty &Val)
LocationClass< Ty > location(Ty &L)
Error applyFixup(LinkGraph &G, Block &B, const Edge &E, const ArmConfig &ArmCfg)
Apply fixup expression for edge to block content.
bool isRelocation(MCFixupKind FixupKind)
NodeAddr< CodeNode * > Code
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.
MCAsmBackend * createX86_64AsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
std::unique_ptr< MCObjectTargetWriter > createX86WinCOFFObjectWriter(bool Is64Bit)
Construct an X86 Win COFF object writer.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
MCStreamer * createX86ELFStreamer(const Triple &T, MCContext &Context, std::unique_ptr< MCAsmBackend > &&MAB, std::unique_ptr< MCObjectWriter > &&MOW, std::unique_ptr< MCCodeEmitter > &&MCE)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ FK_SecRel_2
A two-byte section relative fixup.
@ FirstLiteralRelocationKind
@ FK_Data_8
A eight-byte fixup.
@ FK_Data_1
A one-byte fixup.
@ FK_Data_4
A four-byte fixup.
@ FK_SecRel_8
A eight-byte section relative fixup.
@ FK_SecRel_4
A four-byte section relative fixup.
@ FK_SecRel_1
A one-byte section relative fixup.
@ FK_Data_2
A two-byte fixup.
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
std::unique_ptr< MCObjectTargetWriter > createX86MachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
Construct an X86 Mach-O object writer.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
std::unique_ptr< MCObjectTargetWriter > createX86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine)
Construct an X86 ELF object writer.
Align assumeAligned(uint64_t Value)
Treats the value 0 as a 1, so Align is always at least 1.
MCAsmBackend * createX86_32AsmBackend(const Target &T, const MCSubtargetInfo &STI, const MCRegisterInfo &MRI, const MCTargetOptions &Options)
Implement std::hash so that hash_code can be used in STL containers.
const MCSymbol * Personality
std::vector< MCCFIInstruction > Instructions