43class X86AlignBranchKind {
45 uint8_t AlignBranchKind = 0;
48 X86AlignBranchKind() =
default;
49 explicit X86AlignBranchKind(StringRef Val) {
51 Val.
split(BranchTypes,
'+', -1,
false);
52 for (
auto BranchType : BranchTypes) {
53 if (BranchType ==
"fused")
55 else if (BranchType ==
"jcc")
57 else if (BranchType ==
"jmp")
59 else if (BranchType ==
"call")
61 else if (BranchType ==
"ret")
63 else if (BranchType ==
"indirect")
67 <<
" to -x86-align-branch=; each element must be one of: fused, "
68 "jcc, jmp, call, ret, indirect.(plus separated)\n";
73 operator uint8_t()
const {
return AlignBranchKind; }
78 const X86MCOptions &CLOpts;
79 const MCSubtargetInfo &STI;
80 std::unique_ptr<const MCInstrInfo> MCII;
81 X86AlignBranchKind AlignBranchType;
83 unsigned TargetPrefixMax = 0;
86 unsigned PrevInstOpcode = 0;
87 bool PrefixEndsBundleLock =
false;
88 MCBoundaryAlignFragment *PendingBA =
nullptr;
89 std::pair<MCFragment *, size_t> PrevInstPosition;
91 uint8_t determinePaddingPrefix(
const MCInst &Inst)
const;
92 bool isMacroFused(
const MCInst &Cmp,
const MCInst &Jcc)
const;
93 bool needAlign(
const MCInst &Inst)
const;
94 bool canPadBranches(MCObjectStreamer &OS)
const;
95 bool canPadInst(
const MCInst &Inst, MCObjectStreamer &OS)
const;
96 void emitInstructionBeginBundle(MCObjectStreamer &OS);
97 void emitInstructionEndBundle(MCObjectStreamer &OS);
100 X86AsmBackend(
const X86MCOptions &CLOpts,
const Target &
T,
101 const MCSubtargetInfo &STI)
104 if (CLOpts.branches_within_32B_boundaries) {
109 AlignBoundary = assumeAligned(32);
110 AlignBranchType.addKind(X86::AlignBranchFused);
111 AlignBranchType.addKind(X86::AlignBranchJcc);
112 AlignBranchType.addKind(X86::AlignBranchJmp);
115 if (CLOpts.align_branch_boundary)
116 AlignBoundary =
assumeAligned(*CLOpts.align_branch_boundary);
117 if (CLOpts.align_branch)
118 AlignBranchType = X86AlignBranchKind(*CLOpts.align_branch);
119 if (CLOpts.pad_max_prefix_size)
120 TargetPrefixMax = *CLOpts.pad_max_prefix_size;
124 AllowEnhancedRelaxation =
125 AllowAutoPadding && TargetPrefixMax != 0 && CLOpts.pad_for_branch_align;
126 AllowBundling =
true;
129 const X86MCOptions &
getCLOpts()
const {
return CLOpts; }
132 void reset()
override {
135 PrefixEndsBundleLock =
false;
137 PrevInstPosition = {};
140 void emitInstructionBegin(MCObjectStreamer &OS,
const MCInst &Inst,
141 const MCSubtargetInfo &STI);
142 void emitInstructionEnd(MCObjectStreamer &OS,
const MCInst &Inst);
145 std::optional<MCFixupKind>
getFixupKind(StringRef Name)
const override;
147 MCFixupKindInfo getFixupKindInfo(
MCFixupKind Kind)
const override;
149 std::optional<bool> evaluateFixup(
const MCFragment &, MCFixup &, MCValue &,
151 void applyFixup(
const MCFragment &,
const MCFixup &,
const MCValue &Target,
155 const MCSubtargetInfo &STI)
const override;
157 bool fixupNeedsRelaxationAdvanced(
const MCFragment &,
const MCFixup &,
159 bool)
const override;
161 void relaxInstruction(MCInst &Inst,
162 const MCSubtargetInfo &STI)
const override;
164 bool padInstructionViaRelaxation(MCFragment &RF, MCCodeEmitter &
Emitter,
165 unsigned &RemainingSize)
const;
167 bool padInstructionViaPrefix(MCFragment &RF, MCCodeEmitter &
Emitter,
168 unsigned &RemainingSize)
const;
170 bool padInstructionEncoding(MCFragment &RF, MCCodeEmitter &
Emitter,
171 unsigned &RemainingSize)
const;
173 bool finishLayout()
const override;
175 bool padInstsBackward(SmallVectorImpl<MCFragment *> &Relaxable,
176 unsigned &RemainingSize)
const;
177 bool foldBundlePad(
const MCAssembler &Asm, MCBoundaryAlignFragment &BF,
178 SmallVectorImpl<MCFragment *> &Relaxable)
const;
179 bool optimizeBundleNops(
const MCAssembler &Asm)
const;
181 unsigned getMaximumNopSize(
const MCSubtargetInfo &STI)
const override;
184 const MCSubtargetInfo *STI)
const override;
189 return Opcode == X86::JCC_1 || Opcode == X86::JMP_1;
193 bool Is16BitMode =
false) {
198 return (Is16BitMode) ? X86::JCC_2 : X86::JCC_4;
200 return (Is16BitMode) ? X86::JMP_2 : X86::JMP_4;
205 unsigned Opcode =
MI.getOpcode();
212 unsigned Opcode =
MI.getOpcode();
219 MI.getOperand(
Desc.getNumOperands() - 1).getImm());
227 return classifySecondCondCodeInMacroFusion(CC);
234 if (MemoryOperand < 0)
237 MCRegister BaseReg =
MI.getOperand(BaseRegNum).getReg();
238 return (BaseReg == X86::RIP);
266uint8_t X86AsmBackend::determinePaddingPrefix(
const MCInst &Inst)
const {
268 "Prefixes can be added only in 32-bit or 64-bit mode.");
275 MCRegister SegmentReg;
276 if (MemoryOperand >= 0) {
309 if (MemoryOperand >= 0) {
312 if (BaseReg == X86::ESP || BaseReg == X86::EBP)
319bool X86AsmBackend::isMacroFused(
const MCInst &Cmp,
const MCInst &Jcc)
const {
320 const MCInstrDesc &InstDesc = MCII->get(Jcc.
getOpcode());
334 for (
auto &Operand :
MI) {
335 if (!Operand.isExpr())
337 const MCExpr &Expr = *Operand.getExpr();
349 switch (InstOpcode) {
368bool X86AsmBackend::canPadInst(
const MCInst &Inst, MCObjectStreamer &OS)
const {
379 if (
isPrefix(PrevInstOpcode, *MCII))
393 Offset != PrevInstPosition.second))
399bool X86AsmBackend::canPadBranches(MCObjectStreamer &OS)
const {
402 assert(allowAutoPadding() &&
"incorrect initialization!");
416bool X86AsmBackend::needAlign(
const MCInst &Inst)
const {
418 return (
Desc.isConditionalBranch() &&
420 (
Desc.isUnconditionalBranch() &&
424 (
Desc.isIndirectBranch() &&
430 auto &Backend =
static_cast<X86AsmBackend &
>(S.
getAssembler().getBackend());
432 if (
LLVM_LIKELY(!AutoPadding && !Backend.getCLOpts().pad_for_align)) {
433 S.MCObjectStreamer::emitInstruction(Inst, STI);
443 Backend.emitInstructionBegin(S, Inst, STI);
444 S.MCObjectStreamer::emitInstruction(Inst, STI);
445 Backend.emitInstructionEnd(S, Inst);
452 assert(Asm->isBundlingEnabled());
458 "instruction prefix cannot be the last "
459 "instruction of a .bundle_lock group");
472 Asm->getBundleAlign(), STI);
483void X86AsmBackend::emitInstructionEndBundle(MCObjectStreamer &OS) {
487 PrefixEndsBundleLock =
isPrefix(PrevInstOpcode, *MCII);
490 PrefixEndsBundleLock =
false;
491 assert(PendingBA &&
"MCBoundaryAlignFragment is expected for every "
492 "instruction if it is not bundle-locked");
496 if (!
isPrefix(PrevInstOpcode, *MCII))
501void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
503 const MCSubtargetInfo &STI) {
504 bool CanPadInst = canPadInst(Inst, OS);
505 if (
Asm->isBundlingEnabled()) {
506 emitInstructionBeginBundle(OS);
513 if (!canPadBranches(OS))
529 auto *NextFragment = PendingBA->
getNext();
530 assert(NextFragment &&
"NextFragment should not be null");
569void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
570 const MCInst &Inst) {
575 if (
Asm->isBundlingEnabled())
576 return emitInstructionEndBundle(OS);
578 if (!canPadBranches(OS))
584 if (!needAlign(Inst) || !PendingBA)
601std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name)
const {
605 Type = llvm::StringSwitch<unsigned>(Name)
606#define ELF_RELOC(X, Y) .Case(#X, Y)
607#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
609 .Case(
"BFD_RELOC_NONE", ELF::R_X86_64_NONE)
610 .Case(
"BFD_RELOC_8", ELF::R_X86_64_8)
611 .Case(
"BFD_RELOC_16", ELF::R_X86_64_16)
612 .Case(
"BFD_RELOC_32", ELF::R_X86_64_32)
613 .Case(
"BFD_RELOC_64", ELF::R_X86_64_64)
616 Type = llvm::StringSwitch<unsigned>(Name)
617#define ELF_RELOC(X, Y) .Case(#X, Y)
618#include "llvm/BinaryFormat/ELFRelocs/i386.def"
620 .Case(
"BFD_RELOC_NONE", ELF::R_386_NONE)
621 .Case(
"BFD_RELOC_8", ELF::R_386_8)
622 .Case(
"BFD_RELOC_16", ELF::R_386_16)
623 .Case(
"BFD_RELOC_32", ELF::R_386_32)
633MCFixupKindInfo X86AsmBackend::getFixupKindInfo(
MCFixupKind Kind)
const {
636 {
"reloc_riprel_4byte", 0, 32, 0},
637 {
"reloc_riprel_4byte_movq_load", 0, 32, 0},
638 {
"reloc_riprel_4byte_movq_load_rex2", 0, 32, 0},
639 {
"reloc_riprel_4byte_relax", 0, 32, 0},
640 {
"reloc_riprel_4byte_relax_rex", 0, 32, 0},
641 {
"reloc_riprel_4byte_relax_rex2", 0, 32, 0},
642 {
"reloc_riprel_4byte_relax_evex", 0, 32, 0},
643 {
"reloc_signed_4byte", 0, 32, 0},
644 {
"reloc_signed_4byte_relax", 0, 32, 0},
645 {
"reloc_global_offset_table", 0, 32, 0},
646 {
"reloc_branch_4byte_pcrel", 0, 32, 0},
700std::optional<bool> X86AsmBackend::evaluateFixup(
const MCFragment &,
703 if (
Fixup.isPCRel()) {
704 switch (
Fixup.getKind()) {
727void X86AsmBackend::applyFixup(
const MCFragment &
F,
const MCFixup &
Fixup,
728 const MCValue &Target, uint8_t *
Data,
732 if (
Target.getSpecifier())
734 maybeAddReloc(
F,
Fixup, Target,
Value, IsResolved);
757 "value of " + Twine(int64_t(
Value)) +
758 " is too large for field of " + Twine(
Size) +
759 (
Size == 1 ?
" byte" :
" bytes"));
762 for (
unsigned i = 0; i !=
Size; ++i)
766bool X86AsmBackend::mayNeedRelaxation(
unsigned Opcode,
768 const MCSubtargetInfo &STI)
const {
769 unsigned SkipOperands = X86::isCCMPCC(Opcode) ? 2 : 0;
775bool X86AsmBackend::fixupNeedsRelaxationAdvanced(
const MCFragment &
F,
776 const MCFixup &
Fixup,
777 const MCValue &Target,
779 bool Resolved)
const {
788 int64_t Slack =
Asm->isBundlingEnabled() && TargetPrefixMax != 0 &&
790 ?
Asm->getBundleAlign().value()
805void X86AsmBackend::relaxInstruction(MCInst &Inst,
806 const MCSubtargetInfo &STI)
const {
808 bool Is16BitMode = STI.
hasFeature(X86::Is16Bit);
814bool X86AsmBackend::padInstructionViaPrefix(MCFragment &RF,
816 unsigned &RemainingSize)
const {
831 const unsigned MaxPossiblePad = std::min(15 - OldSize, RemainingSize);
832 const unsigned RemainingPrefixSize = [&]() ->
unsigned {
833 SmallString<15>
Code;
835 assert(
Code.size() < 15 &&
"The number of prefixes must be less than 15.");
842 unsigned ExistingPrefixSize =
Code.size();
843 if (TargetPrefixMax <= ExistingPrefixSize)
845 return TargetPrefixMax - ExistingPrefixSize;
847 const unsigned PrefixBytesToAdd =
848 std::min(MaxPossiblePad, RemainingPrefixSize);
849 if (PrefixBytesToAdd == 0)
854 SmallString<256>
Code;
855 Code.append(PrefixBytesToAdd, Prefix);
861 F.setOffset(PrefixBytesToAdd +
F.getOffset());
863 RemainingSize -= PrefixBytesToAdd;
867bool X86AsmBackend::padInstructionViaRelaxation(MCFragment &RF,
869 unsigned &RemainingSize)
const {
880 SmallString<15>
Code;
883 const unsigned NewSize =
Code.size();
884 assert(NewSize >= OldSize &&
"size decrease during relaxation?");
885 unsigned Delta = NewSize - OldSize;
886 if (Delta > RemainingSize)
891 RemainingSize -= Delta;
895bool X86AsmBackend::padInstructionEncoding(MCFragment &RF,
897 unsigned &RemainingSize)
const {
899 if (RemainingSize != 0)
900 Changed |= padInstructionViaRelaxation(RF,
Emitter, RemainingSize);
901 if (RemainingSize != 0)
906bool X86AsmBackend::padInstsBackward(SmallVectorImpl<MCFragment *> &Relaxable,
907 unsigned &RemainingSize)
const {
909 while (!Relaxable.
empty() && RemainingSize != 0) {
914 Changed |= padInstructionEncoding(RF,
Asm->getEmitter(), RemainingSize);
934bool X86AsmBackend::foldBundlePad(
935 const MCAssembler &Asm, MCBoundaryAlignFragment &BF,
936 SmallVectorImpl<MCFragment *> &Relaxable)
const {
937 const uint64_t BundleSize =
Asm.getBundleAlign().value();
938 const uint64_t PadStart =
Asm.getFragmentOffset(BF);
939 unsigned Remaining = BF.
getSize();
944 std::min<uint64_t>(Remaining, BundleSize - PadStart % BundleSize);
945 unsigned Left = Budget;
947 Remaining -= Budget -
Left;
955 GroupSize +=
Asm.computeFragmentSize(*
F);
959 if (GroupSize < BundleSize) {
960 Left = Budget = std::min<uint64_t>(Remaining, BundleSize - GroupSize);
967 Remaining -= Budget -
Left;
975bool X86AsmBackend::optimizeBundleNops(
const MCAssembler &Asm)
const {
976 const uint64_t BundleSize =
Asm.getBundleAlign().value();
978 for (MCSection &Sec : Asm) {
986 const MCFragment *ResumeAfter =
nullptr;
987 for (MCFragment &
F : Sec) {
989 if (&
F == ResumeAfter)
990 ResumeAfter =
nullptr;
994 if (!Relaxable.
empty() &&
995 Asm.getFragmentOffset(*Relaxable.
front()) / BundleSize !=
999 switch (
F.getKind()) {
1001 auto &BF =
static_cast<MCBoundaryAlignFragment &
>(
F);
1004 Changed |= foldBundlePad(Asm, BF, Relaxable);
1024bool X86AsmBackend::finishLayout()
const {
1027 if (
Asm->isBundlingEnabled())
1028 return TargetPrefixMax != 0 && optimizeBundleNops(*Asm);
1035 if (!CLOpts.pad_for_align && !CLOpts.pad_for_branch_align)
1041 DenseSet<MCFragment *> LabeledFragments;
1042 for (
const MCSymbol &S :
Asm->symbols())
1043 LabeledFragments.
insert(S.getFragment());
1046 for (MCSection &Sec : *Asm) {
1051 for (MCSection::iterator
I = Sec.begin(), IE = Sec.end();
I != IE; ++
I) {
1054 if (LabeledFragments.
count(&
F))
1066 auto canHandle = [&](MCFragment &
F) ->
bool {
1067 switch (
F.getKind()) {
1071 return CLOpts.pad_for_align;
1073 return CLOpts.pad_for_branch_align;
1077 if (!canHandle(
F)) {
1086 unsigned RemainingSize =
Asm->computeFragmentSize(
F) -
F.getFixedSize();
1087 Changed |= padInstsBackward(Relaxable, RemainingSize);
1098 while (&*
I != LastFragment)
1107unsigned X86AsmBackend::getMaximumNopSize(
const MCSubtargetInfo &STI)
const {
1114 if (STI.
hasFeature(X86::TuningFast15ByteNOP))
1116 if (STI.
hasFeature(X86::TuningFast11ByteNOP))
1127bool X86AsmBackend::writeNopData(raw_ostream &OS,
uint64_t Count,
1128 const MCSubtargetInfo *STI)
const {
1129 static const char Nops32Bit[10][11] = {
1139 "\x0f\x1f\x44\x00\x00",
1141 "\x66\x0f\x1f\x44\x00\x00",
1143 "\x0f\x1f\x80\x00\x00\x00\x00",
1145 "\x0f\x1f\x84\x00\x00\x00\x00\x00",
1147 "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
1149 "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
1153 static const char Nops16Bit[4][11] = {
1164 const char(*Nops)[11] =
1165 STI->
hasFeature(X86::Is16Bit) ? Nops16Bit : Nops32Bit;
1172 const uint8_t ThisNopLength = (uint8_t) std::min(
Count, MaxNopLength);
1173 const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
1174 for (uint8_t i = 0; i < Prefixes; i++)
1176 const uint8_t Rest = ThisNopLength - Prefixes;
1178 OS.
write(Nops[Rest - 1], Rest);
1179 Count -= ThisNopLength;
1180 }
while (
Count != 0);
1189class ELFX86AsmBackend :
public X86AsmBackend {
1192 ELFX86AsmBackend(
const X86MCOptions &CLOpts,
const Target &
T, uint8_t OSABI,
1193 const MCSubtargetInfo &STI)
1194 : X86AsmBackend(CLOpts,
T, STI), OSABI(OSABI) {}
1197class ELFX86_32AsmBackend :
public ELFX86AsmBackend {
1199 using ELFX86AsmBackend::ELFX86AsmBackend;
1201 std::unique_ptr<MCObjectTargetWriter>
1202 createObjectTargetWriter()
const override {
1207class ELFX86_X32AsmBackend :
public ELFX86AsmBackend {
1209 using ELFX86AsmBackend::ELFX86AsmBackend;
1211 std::unique_ptr<MCObjectTargetWriter>
1212 createObjectTargetWriter()
const override {
1218class ELFX86_IAMCUAsmBackend :
public ELFX86AsmBackend {
1220 using ELFX86AsmBackend::ELFX86AsmBackend;
1222 std::unique_ptr<MCObjectTargetWriter>
1223 createObjectTargetWriter()
const override {
1229class ELFX86_64AsmBackend :
public ELFX86AsmBackend {
1231 using ELFX86AsmBackend::ELFX86AsmBackend;
1233 std::unique_ptr<MCObjectTargetWriter>
1234 createObjectTargetWriter()
const override {
1239class WindowsX86AsmBackend :
public X86AsmBackend {
1243 WindowsX86AsmBackend(
const X86MCOptions &CLOpts,
const Target &
T,
1244 bool is64Bit,
const MCSubtargetInfo &STI)
1245 : X86AsmBackend(CLOpts,
T, STI), Is64Bit(
is64Bit) {}
1247 std::optional<MCFixupKind>
getFixupKind(StringRef Name)
const override {
1248 return StringSwitch<std::optional<MCFixupKind>>(
Name)
1255 std::unique_ptr<MCObjectTargetWriter>
1256 createObjectTargetWriter()
const override {
1264 enum CompactUnwindEncodings {
1267 UNWIND_MODE_BP_FRAME = 0x01000000,
1270 UNWIND_MODE_STACK_IMMD = 0x02000000,
1273 UNWIND_MODE_STACK_IND = 0x03000000,
1276 UNWIND_MODE_DWARF = 0x04000000,
1279 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
1282 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
1287class DarwinX86AsmBackend :
public X86AsmBackend {
1288 const MCRegisterInfo &MRI;
1291 enum { CU_NUM_SAVED_REGS = 6 };
1293 mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
1297 unsigned OffsetSize;
1298 unsigned MoveInstrSize;
1299 unsigned StackDivide;
1302 unsigned PushInstrSize(MCRegister
Reg)
const {
1325 int getCompactUnwindRegNum(
unsigned Reg)
const {
1326 static const MCPhysReg CU32BitRegs[7] = {
1327 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
1329 static const MCPhysReg CU64BitRegs[] = {
1330 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
1332 const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
1333 for (
int Idx = 1; *CURegs; ++CURegs, ++
Idx)
1342 uint32_t encodeCompactUnwindRegistersWithFrame()
const {
1346 uint32_t RegEnc = 0;
1347 for (
int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
1348 unsigned Reg = SavedRegs[i];
1349 if (
Reg == 0)
break;
1351 int CURegNum = getCompactUnwindRegNum(
Reg);
1352 if (CURegNum == -1)
return ~0
U;
1356 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
1359 assert((RegEnc & 0x3FFFF) == RegEnc &&
1360 "Invalid compact register encoding!");
1367 uint32_t encodeCompactUnwindRegistersWithoutFrame(
unsigned RegCount)
const {
1381 for (
unsigned i = 0; i < RegCount; ++i) {
1382 int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
1383 if (CUReg == -1)
return ~0
U;
1384 SavedRegs[i] = CUReg;
1388 std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
1390 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
1391 for (
unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
1392 unsigned Countless = 0;
1393 for (
unsigned j = CU_NUM_SAVED_REGS - RegCount;
j < i; ++
j)
1394 if (SavedRegs[j] < SavedRegs[i])
1397 RenumRegs[i] = SavedRegs[i] - Countless - 1;
1401 uint32_t permutationEncoding = 0;
1404 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
1405 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
1409 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
1410 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
1414 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
1415 + 3 * RenumRegs[4] + RenumRegs[5];
1418 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
1422 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
1425 permutationEncoding |= RenumRegs[5];
1429 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
1430 "Invalid compact register encoding!");
1431 return permutationEncoding;
1435 DarwinX86AsmBackend(
const X86MCOptions &CLOpts,
const Target &
T,
1436 const MCRegisterInfo &MRI,
const MCSubtargetInfo &STI)
1437 : X86AsmBackend(CLOpts,
T, STI), MRI(MRI),
TT(STI.getTargetTriple()),
1438 Is64Bit(
TT.isX86_64()) {
1439 memset(SavedRegs, 0,
sizeof(SavedRegs));
1440 OffsetSize = Is64Bit ? 8 : 4;
1441 MoveInstrSize = Is64Bit ? 3 : 2;
1442 StackDivide = Is64Bit ? 8 : 4;
1445 std::unique_ptr<MCObjectTargetWriter>
1446 createObjectTargetWriter()
const override {
1454 uint64_t generateCompactUnwindEncoding(
const MCDwarfFrameInfo *FI,
1455 const MCContext *Ctxt)
const override {
1457 return CU::UNWIND_MODE_DWARF;
1461 return CU::UNWIND_MODE_DWARF;
1464 if (Instrs.
empty())
return 0;
1465 if (!isDarwinCanonicalPersonality(FI->
Personality) &&
1467 return CU::UNWIND_MODE_DWARF;
1470 unsigned SavedRegIdx = 0;
1471 memset(SavedRegs, 0,
sizeof(SavedRegs));
1476 uint64_t CompactUnwindEncoding = 0;
1478 unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
1479 unsigned InstrOffset = 0;
1480 unsigned StackAdjust = 0;
1482 int64_t MinAbsOffset = std::numeric_limits<int64_t>::max();
1484 for (
const MCCFIInstruction &Inst : Instrs) {
1485 switch (Inst.getOperation()) {
1489 return CU::UNWIND_MODE_DWARF;
1502 (Is64Bit ? X86::RBP : X86::EBP))
1503 return CU::UNWIND_MODE_DWARF;
1506 memset(SavedRegs, 0,
sizeof(SavedRegs));
1509 MinAbsOffset = std::numeric_limits<int64_t>::max();
1510 InstrOffset += MoveInstrSize;
1528 StackSize = Inst.getOffset() / StackDivide;
1544 if (SavedRegIdx == CU_NUM_SAVED_REGS)
1547 return CU::UNWIND_MODE_DWARF;
1550 SavedRegs[SavedRegIdx++] =
Reg.
id();
1551 StackAdjust += OffsetSize;
1552 MinAbsOffset = std::min(MinAbsOffset, std::abs(Inst.getOffset()));
1553 InstrOffset += PushInstrSize(
Reg);
1559 StackAdjust /= StackDivide;
1562 if ((StackAdjust & 0xFF) != StackAdjust)
1564 return CU::UNWIND_MODE_DWARF;
1568 if (SavedRegIdx != 0 && MinAbsOffset != 3 * (
int)OffsetSize)
1569 return CU::UNWIND_MODE_DWARF;
1572 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
1573 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
1575 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
1576 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
1577 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
1579 SubtractInstrIdx += InstrOffset;
1582 if ((StackSize & 0xFF) == StackSize) {
1584 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
1587 CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
1589 if ((StackAdjust & 0x7) != StackAdjust)
1591 return CU::UNWIND_MODE_DWARF;
1594 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
1598 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
1601 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
1605 std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]);
1606 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
1610 uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
1611 if (RegEnc == ~0U)
return CU::UNWIND_MODE_DWARF;
1614 CompactUnwindEncoding |=
1615 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
1618 return CompactUnwindEncoding;
1631 return new DarwinX86AsmBackend(CLOpts,
T, MRI, STI);
1634 return new WindowsX86AsmBackend(CLOpts,
T,
false, STI);
1639 return new ELFX86_IAMCUAsmBackend(CLOpts,
T, OSABI, STI);
1641 return new ELFX86_32AsmBackend(CLOpts,
T, OSABI, STI);
1651 return new DarwinX86AsmBackend(CLOpts,
T, MRI, STI);
1654 return new WindowsX86AsmBackend(CLOpts,
T,
true, STI);
1656 if (TheTriple.
isUEFI()) {
1658 "Only COFF format is supported in UEFI environment.");
1659 return new WindowsX86AsmBackend(CLOpts,
T,
true, STI);
1664 if (TheTriple.
isX32())
1665 return new ELFX86_X32AsmBackend(CLOpts,
T, OSABI, STI);
1666 return new ELFX86_64AsmBackend(CLOpts,
T, OSABI, STI);
1672 X86ELFStreamer(
MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
1673 std::unique_ptr<MCObjectWriter> OW,
1674 std::unique_ptr<MCCodeEmitter>
Emitter)
1678 void emitInstruction(
const MCInst &Inst,
const MCSubtargetInfo &STI)
override;
1682void X86ELFStreamer::emitInstruction(
const MCInst &Inst,
1683 const MCSubtargetInfo &STI) {
1688 std::unique_ptr<MCAsmBackend> &&MAB,
1689 std::unique_ptr<MCObjectWriter> &&MOW,
1690 std::unique_ptr<MCCodeEmitter> &&MCE) {
1691 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)
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
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.
const MipsMCOptions & getCLOpts(const MCTargetOptions &Options)
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...
const X86MCOptions & getCLOpts(const MCTargetOptions &Options)
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
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.
constexpr MCFixupKind FirstTargetFixupKind
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.
@ 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)
constexpr MCFixupKind FirstLiteralRelocationKind
Implement std::hash so that hash_code can be used in STL containers.
const MCSymbol * Personality
std::vector< MCCFIInstruction > Instructions