LLVM 24.0.0git
X86AsmBackend.cpp
Go to the documentation of this file.
1//===-- X86AsmBackend.cpp - X86 Assembler Backend -------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
17#include "llvm/MC/MCAssembler.h"
19#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCDwarf.h"
23#include "llvm/MC/MCExpr.h"
24#include "llvm/MC/MCInst.h"
25#include "llvm/MC/MCInstrInfo.h"
29#include "llvm/MC/MCSection.h"
32#include "llvm/MC/MCValue.h"
37
38using namespace llvm;
39
40namespace {
41/// A wrapper for holding a mask of the values from X86::AlignBranchBoundaryKind
42class X86AlignBranchKind {
43private:
44 uint8_t AlignBranchKind = 0;
45
46public:
47 void operator=(const std::string &Val) {
48 if (Val.empty())
49 return;
50 SmallVector<StringRef, 6> BranchTypes;
51 StringRef(Val).split(BranchTypes, '+', -1, false);
52 for (auto BranchType : BranchTypes) {
53 if (BranchType == "fused")
54 addKind(X86::AlignBranchFused);
55 else if (BranchType == "jcc")
56 addKind(X86::AlignBranchJcc);
57 else if (BranchType == "jmp")
58 addKind(X86::AlignBranchJmp);
59 else if (BranchType == "call")
60 addKind(X86::AlignBranchCall);
61 else if (BranchType == "ret")
62 addKind(X86::AlignBranchRet);
63 else if (BranchType == "indirect")
65 else {
66 errs() << "invalid argument " << BranchType.str()
67 << " to -x86-align-branch=; each element must be one of: fused, "
68 "jcc, jmp, call, ret, indirect.(plus separated)\n";
69 }
70 }
71 }
72
73 operator uint8_t() const { return AlignBranchKind; }
74 void addKind(X86::AlignBranchBoundaryKind Value) { AlignBranchKind |= Value; }
75};
76
77X86AlignBranchKind X86AlignBranchKindLoc;
78
79cl::opt<unsigned> X86AlignBranchBoundary(
80 "x86-align-branch-boundary", cl::init(0),
82 "Control how the assembler should align branches with NOP. If the "
83 "boundary's size is not 0, it should be a power of 2 and no less "
84 "than 32. Branches will be aligned to prevent from being across or "
85 "against the boundary of specified size. The default value 0 does not "
86 "align branches."));
87
89 "x86-align-branch",
91 "Specify types of branches to align (plus separated list of types):"
92 "\njcc indicates conditional jumps"
93 "\nfused indicates fused conditional jumps"
94 "\njmp indicates direct unconditional jumps"
95 "\ncall indicates direct and indirect calls"
96 "\nret indicates rets"
97 "\nindirect indicates indirect unconditional jumps"),
98 cl::location(X86AlignBranchKindLoc));
99
100cl::opt<bool> X86AlignBranchWithin32BBoundaries(
101 "x86-branches-within-32B-boundaries", cl::init(false),
102 cl::desc(
103 "Align selected instructions to mitigate negative performance impact "
104 "of Intel's micro code update for errata skx102. May break "
105 "assumptions about labels corresponding to particular instructions, "
106 "and should be used with caution."));
107
108cl::opt<unsigned> X86PadMaxPrefixSize(
109 "x86-pad-max-prefix-size", cl::init(0),
110 cl::desc("Maximum number of prefixes to use for padding"));
111
112cl::opt<bool> X86PadForAlign(
113 "x86-pad-for-align", cl::init(false), cl::Hidden,
114 cl::desc("Pad previous instructions to implement align directives"));
115
116cl::opt<bool> X86PadForBranchAlign(
117 "x86-pad-for-branch-align", cl::init(true), cl::Hidden,
118 cl::desc("Pad previous instructions to implement branch alignment"));
119
120class X86AsmBackend : public MCAsmBackend {
121 const MCSubtargetInfo &STI;
122 std::unique_ptr<const MCInstrInfo> MCII;
123 X86AlignBranchKind AlignBranchType;
124 Align AlignBoundary;
125 unsigned TargetPrefixMax = 0;
126
127 MCInst PrevInst;
128 unsigned PrevInstOpcode = 0;
129 bool PrefixEndsBundleLock = false;
130 MCBoundaryAlignFragment *PendingBA = nullptr;
131 std::pair<MCFragment *, size_t> PrevInstPosition;
132
133 uint8_t determinePaddingPrefix(const MCInst &Inst) const;
134 bool isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const;
135 bool needAlign(const MCInst &Inst) const;
136 bool canPadBranches(MCObjectStreamer &OS) const;
137 bool canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const;
138 void emitInstructionBeginBundle(MCObjectStreamer &OS);
139 void emitInstructionEndBundle(MCObjectStreamer &OS);
140
141public:
142 X86AsmBackend(const Target &T, const MCSubtargetInfo &STI)
143 : MCAsmBackend(llvm::endianness::little), STI(STI),
144 MCII(T.createMCInstrInfo()) {
145 if (X86AlignBranchWithin32BBoundaries) {
146 // At the moment, this defaults to aligning fused branches, unconditional
147 // jumps, and (unfused) conditional jumps with nops. Both the
148 // instructions aligned and the alignment method (nop vs prefix) may
149 // change in the future.
150 AlignBoundary = assumeAligned(32);
151 AlignBranchType.addKind(X86::AlignBranchFused);
152 AlignBranchType.addKind(X86::AlignBranchJcc);
153 AlignBranchType.addKind(X86::AlignBranchJmp);
154 }
155 // Allow overriding defaults set by main flag
156 if (X86AlignBranchBoundary.getNumOccurrences())
157 AlignBoundary = assumeAligned(X86AlignBranchBoundary);
158 if (X86AlignBranch.getNumOccurrences())
159 AlignBranchType = X86AlignBranchKindLoc;
160 if (X86PadMaxPrefixSize.getNumOccurrences())
161 TargetPrefixMax = X86PadMaxPrefixSize;
162
163 AllowAutoPadding =
164 AlignBoundary != Align(1) && AlignBranchType != X86::AlignBranchNone;
165 AllowEnhancedRelaxation =
166 AllowAutoPadding && TargetPrefixMax != 0 && X86PadForBranchAlign;
167 AllowBundling = true;
168 }
169
170 // The streamer frees the fragments these point into.
171 void reset() override {
172 PrevInst = MCInst();
173 PrevInstOpcode = 0;
174 PrefixEndsBundleLock = false;
175 PendingBA = nullptr;
176 PrevInstPosition = {};
177 }
178
179 void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
180 const MCSubtargetInfo &STI);
181 void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst);
182
183
184 std::optional<MCFixupKind> getFixupKind(StringRef Name) const override;
185
186 MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
187
188 std::optional<bool> evaluateFixup(const MCFragment &, MCFixup &, MCValue &,
189 uint64_t &) override;
190 void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target,
191 uint8_t *Data, uint64_t Value, bool IsResolved) override;
192
193 bool mayNeedRelaxation(unsigned Opcode, ArrayRef<MCOperand> Operands,
194 const MCSubtargetInfo &STI) const override;
195
196 bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &,
197 const MCValue &, uint64_t,
198 bool) const override;
199
200 void relaxInstruction(MCInst &Inst,
201 const MCSubtargetInfo &STI) const override;
202
203 bool padInstructionViaRelaxation(MCFragment &RF, MCCodeEmitter &Emitter,
204 unsigned &RemainingSize) const;
205
206 bool padInstructionViaPrefix(MCFragment &RF, MCCodeEmitter &Emitter,
207 unsigned &RemainingSize) const;
208
209 bool padInstructionEncoding(MCFragment &RF, MCCodeEmitter &Emitter,
210 unsigned &RemainingSize) const;
211
212 bool finishLayout() const override;
213
214 bool padInstsBackward(SmallVectorImpl<MCFragment *> &Relaxable,
215 unsigned &RemainingSize) const;
216 bool foldBundlePad(const MCAssembler &Asm, MCBoundaryAlignFragment &BF,
217 SmallVectorImpl<MCFragment *> &Relaxable) const;
218 bool optimizeBundleNops(const MCAssembler &Asm) const;
219
220 unsigned getMaximumNopSize(const MCSubtargetInfo &STI) const override;
221
222 bool writeNopData(raw_ostream &OS, uint64_t Count,
223 const MCSubtargetInfo *STI) const override;
224};
225} // end anonymous namespace
226
227static bool isRelaxableBranch(unsigned Opcode) {
228 return Opcode == X86::JCC_1 || Opcode == X86::JMP_1;
229}
230
231static unsigned getRelaxedOpcodeBranch(unsigned Opcode,
232 bool Is16BitMode = false) {
233 switch (Opcode) {
234 default:
235 llvm_unreachable("invalid opcode for branch");
236 case X86::JCC_1:
237 return (Is16BitMode) ? X86::JCC_2 : X86::JCC_4;
238 case X86::JMP_1:
239 return (Is16BitMode) ? X86::JMP_2 : X86::JMP_4;
240 }
241}
242
243static unsigned getRelaxedOpcode(const MCInst &MI, bool Is16BitMode) {
244 unsigned Opcode = MI.getOpcode();
245 return isRelaxableBranch(Opcode) ? getRelaxedOpcodeBranch(Opcode, Is16BitMode)
247}
248
250 const MCInstrInfo &MCII) {
251 unsigned Opcode = MI.getOpcode();
252 switch (Opcode) {
253 default:
254 return X86::COND_INVALID;
255 case X86::JCC_1: {
256 const MCInstrDesc &Desc = MCII.get(Opcode);
257 return static_cast<X86::CondCode>(
258 MI.getOperand(Desc.getNumOperands() - 1).getImm());
259 }
260 }
261}
262
266 return classifySecondCondCodeInMacroFusion(CC);
267}
268
269/// Check if the instruction uses RIP relative addressing.
270static bool isRIPRelative(const MCInst &MI, const MCInstrInfo &MCII) {
271 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
272 int MemoryOperand = X86II::getMemoryOperandIdx(Desc);
273 if (MemoryOperand < 0)
274 return false;
275 unsigned BaseRegNum = MemoryOperand + X86::AddrBaseReg;
276 MCRegister BaseReg = MI.getOperand(BaseRegNum).getReg();
277 return (BaseReg == X86::RIP);
278}
279
280/// Check if the instruction is a prefix.
281static bool isPrefix(unsigned Opcode, const MCInstrInfo &MCII) {
282 return X86II::isPrefix(MCII.get(Opcode).TSFlags);
283}
284
285/// Check if the instruction is valid as the first instruction in macro fusion.
286static bool isFirstMacroFusibleInst(const MCInst &Inst,
287 const MCInstrInfo &MCII) {
288 // An Intel instruction with RIP relative addressing is not macro fusible.
289 if (isRIPRelative(Inst, MCII))
290 return false;
294}
295
296/// X86 can reduce the bytes of NOP by padding instructions with prefixes to
297/// get a better peformance in some cases. Here, we determine which prefix is
298/// the most suitable.
299///
300/// If the instruction has a segment override prefix, use the existing one.
301/// If the target is 64-bit, use the CS.
302/// If the target is 32-bit,
303/// - If the instruction has a ESP/EBP base register, use SS.
304/// - Otherwise use DS.
305uint8_t X86AsmBackend::determinePaddingPrefix(const MCInst &Inst) const {
306 assert((STI.hasFeature(X86::Is32Bit) || STI.hasFeature(X86::Is64Bit)) &&
307 "Prefixes can be added only in 32-bit or 64-bit mode.");
308 const MCInstrDesc &Desc = MCII->get(Inst.getOpcode());
309 uint64_t TSFlags = Desc.TSFlags;
310
311 // Determine where the memory operand starts, if present.
312 int MemoryOperand = X86II::getMemoryOperandIdx(Desc);
313
314 MCRegister SegmentReg;
315 if (MemoryOperand >= 0) {
316 // Check for explicit segment override on memory operand.
317 SegmentReg = Inst.getOperand(MemoryOperand + X86::AddrSegmentReg).getReg();
318 }
319
320 switch (TSFlags & X86II::FormMask) {
321 default:
322 break;
323 case X86II::RawFrmDstSrc: {
324 // Check segment override opcode prefix as needed (not for %ds).
325 if (Inst.getOperand(2).getReg() != X86::DS)
326 SegmentReg = Inst.getOperand(2).getReg();
327 break;
328 }
329 case X86II::RawFrmSrc: {
330 // Check segment override opcode prefix as needed (not for %ds).
331 if (Inst.getOperand(1).getReg() != X86::DS)
332 SegmentReg = Inst.getOperand(1).getReg();
333 break;
334 }
336 // Check segment override opcode prefix as needed.
337 SegmentReg = Inst.getOperand(1).getReg();
338 break;
339 }
340 }
341
342 if (SegmentReg)
343 return X86::getSegmentOverridePrefixForReg(SegmentReg);
344
345 if (STI.hasFeature(X86::Is64Bit))
346 return X86::CS_Encoding;
347
348 if (MemoryOperand >= 0) {
349 unsigned BaseRegNum = MemoryOperand + X86::AddrBaseReg;
350 MCRegister BaseReg = Inst.getOperand(BaseRegNum).getReg();
351 if (BaseReg == X86::ESP || BaseReg == X86::EBP)
352 return X86::SS_Encoding;
353 }
354 return X86::DS_Encoding;
355}
356
357/// Check if the two instructions will be macro-fused on the target cpu.
358bool X86AsmBackend::isMacroFused(const MCInst &Cmp, const MCInst &Jcc) const {
359 const MCInstrDesc &InstDesc = MCII->get(Jcc.getOpcode());
360 if (!InstDesc.isConditionalBranch())
361 return false;
362 if (!isFirstMacroFusibleInst(Cmp, *MCII))
363 return false;
364 const X86::FirstMacroFusionInstKind CmpKind =
366 const X86::SecondMacroFusionInstKind BranchKind =
368 return X86::isMacroFused(CmpKind, BranchKind);
369}
370
371/// Check if the instruction has a variant symbol operand.
372static bool hasVariantSymbol(const MCInst &MI) {
373 for (auto &Operand : MI) {
374 if (!Operand.isExpr())
375 continue;
376 const MCExpr &Expr = *Operand.getExpr();
377 if (Expr.getKind() == MCExpr::SymbolRef &&
378 cast<MCSymbolRefExpr>(&Expr)->getSpecifier())
379 return true;
380 }
381 return false;
382}
383
384/// X86 has certain instructions which enable interrupts exactly one
385/// instruction *after* the instruction which stores to SS. Return true if the
386/// given instruction may have such an interrupt delay slot.
387static bool mayHaveInterruptDelaySlot(unsigned InstOpcode) {
388 switch (InstOpcode) {
389 case X86::POPSS16:
390 case X86::POPSS32:
391 case X86::STI:
392 return true;
393
394 case X86::MOV16sr:
395 case X86::MOV32sr:
396 case X86::MOV64sr:
397 case X86::MOV16sm:
398 // In fact, this is only the case if the first operand is SS. However, as
399 // segment moves occur extremely rarely, this is just a minor pessimization.
400 return true;
401 }
402 return false;
403}
404
405/// Return true if we can insert NOP or prefixes automatically before the
406/// the instruction to be emitted.
407bool X86AsmBackend::canPadInst(const MCInst &Inst, MCObjectStreamer &OS) const {
408 if (hasVariantSymbol(Inst))
409 // Linker may rewrite the instruction with variant symbol operand(e.g.
410 // TLSCALL).
411 return false;
412
413 if (mayHaveInterruptDelaySlot(PrevInstOpcode))
414 // If this instruction follows an interrupt enabling instruction with a one
415 // instruction delay, inserting a nop would change behavior.
416 return false;
417
418 if (isPrefix(PrevInstOpcode, *MCII))
419 // If this instruction follows a prefix, inserting a nop/prefix would change
420 // semantic.
421 return false;
422
423 if (isPrefix(Inst.getOpcode(), *MCII))
424 // If this instruction is a prefix, inserting a prefix would change
425 // semantic.
426 return false;
427
428 // If this instruction follows any data, there is no clear instruction
429 // boundary, inserting a nop/prefix would change semantic.
430 auto Offset = OS.getCurFragSize();
431 if (Offset && (OS.getCurrentFragment() != PrevInstPosition.first ||
432 Offset != PrevInstPosition.second))
433 return false;
434
435 return true;
436}
437
438bool X86AsmBackend::canPadBranches(MCObjectStreamer &OS) const {
439 if (!OS.getAllowAutoPadding())
440 return false;
441 assert(allowAutoPadding() && "incorrect initialization!");
442
443 // We only pad in text section.
444 if (!OS.getCurrentSectionOnly()->isText())
445 return false;
446
447 // Branches only need to be aligned in 32-bit or 64-bit mode.
448 if (!(STI.hasFeature(X86::Is64Bit) || STI.hasFeature(X86::Is32Bit)))
449 return false;
450
451 return true;
452}
453
454/// Check if the instruction operand needs to be aligned.
455bool X86AsmBackend::needAlign(const MCInst &Inst) const {
456 const MCInstrDesc &Desc = MCII->get(Inst.getOpcode());
457 return (Desc.isConditionalBranch() &&
458 (AlignBranchType & X86::AlignBranchJcc)) ||
459 (Desc.isUnconditionalBranch() &&
460 (AlignBranchType & X86::AlignBranchJmp)) ||
461 (Desc.isCall() && (AlignBranchType & X86::AlignBranchCall)) ||
462 (Desc.isReturn() && (AlignBranchType & X86::AlignBranchRet)) ||
463 (Desc.isIndirectBranch() &&
464 (AlignBranchType & X86::AlignBranchIndirect));
465}
466
468 const MCSubtargetInfo &STI) {
469 bool AutoPadding = S.getAllowAutoPadding();
470 if (LLVM_LIKELY(!AutoPadding && !X86PadForAlign)) {
471 S.MCObjectStreamer::emitInstruction(Inst, STI);
472 return;
473 }
474
475 auto &Backend = static_cast<X86AsmBackend &>(S.getAssembler().getBackend());
476 Backend.emitInstructionBegin(S, Inst, STI);
477 S.MCObjectStreamer::emitInstruction(Inst, STI);
478 Backend.emitInstructionEnd(S, Inst);
479}
480
481/// Open a MCBoundaryAlignFragment for the upcoming instruction so that layout
482/// can pad it into the next bundle. Within .bundle_lock the group's fragment
483/// already covers it.
484void X86AsmBackend::emitInstructionBeginBundle(MCObjectStreamer &OS) {
485 assert(Asm->isBundlingEnabled());
486
487 // The prefix stays in the group while this instruction gets its own
488 // fragment, so padding may land between the two.
489 if (PrefixEndsBundleLock && OS.getCurrentFragment() != PrevInstPosition.first)
490 getContext().reportError(OS.getStartTokLoc(),
491 "instruction prefix cannot be the last "
492 "instruction of a .bundle_lock group");
493
494 if (OS.isBundleLocked())
495 return;
496 // A pending fragment means the previous MCInst was a prefix, which must stay
497 // with this one: extend its range. Adjacency rejects a fragment left stale by
498 // an intervening .bundle_lock group.
499 if (PendingBA &&
500 PendingBA->getLastFragment()->getNext() == OS.getCurrentFragment()) {
501 PendingBA->setLastFragment(OS.getCurrentFragment());
502 return;
503 }
505 Asm->getBundleAlign(), STI);
506 // We can set LastFragment now, before the instruction is emitted, as bundling
507 // emits one fragment per instruction. Deferring setLastFragment to
508 // post-emitInstruction would risk capturing a fragment that a subsequent
509 // emitCodeAlignment repurposes in-place to FT_Align, corrupting the BA's
510 // boundary range.
511 PendingBA->setLastFragment(OS.getCurrentFragment());
512}
513
514/// Close the fragment opened by emitInstructionBeginBundle, unless the
515/// instruction was a prefix, in which case the next one extends it.
516void X86AsmBackend::emitInstructionEndBundle(MCObjectStreamer &OS) {
517 assert(Asm->isBundlingEnabled());
518
519 if (OS.isBundleLocked()) {
520 PrefixEndsBundleLock = isPrefix(PrevInstOpcode, *MCII);
521 return;
522 }
523 PrefixEndsBundleLock = false;
524 assert(PendingBA && "MCBoundaryAlignFragment is expected for every "
525 "instruction if it is not bundle-locked");
526
527 OS.getCurrentSectionOnly()->ensureMinAlignment(Asm->getBundleAlign());
528
529 if (!isPrefix(PrevInstOpcode, *MCII))
530 PendingBA = nullptr;
531}
532
533/// Insert BoundaryAlignFragment before instructions to align branches.
534void X86AsmBackend::emitInstructionBegin(MCObjectStreamer &OS,
535 const MCInst &Inst,
536 const MCSubtargetInfo &STI) {
537 bool CanPadInst = canPadInst(Inst, OS);
538 if (Asm->isBundlingEnabled()) {
539 emitInstructionBeginBundle(OS);
540 OS.getCurrentFragment()->setAllowAutoPadding(CanPadInst);
541 return;
542 }
543 if (CanPadInst)
545
546 if (!canPadBranches(OS))
547 return;
548
549 // NB: PrevInst only valid if canPadBranches is true.
550 if (!isMacroFused(PrevInst, Inst))
551 // Macro fusion doesn't happen indeed, clear the pending.
552 PendingBA = nullptr;
553
554 // When branch padding is enabled (basically the skx102 erratum => unlikely),
555 // we call canPadInst (not cheap) twice. However, in the common case, we can
556 // avoid unnecessary calls to that, as this is otherwise only used for
557 // relaxable fragments.
558 if (!CanPadInst)
559 return;
560
561 if (PendingBA) {
562 auto *NextFragment = PendingBA->getNext();
563 assert(NextFragment && "NextFragment should not be null");
564 if (NextFragment == OS.getCurrentFragment())
565 return;
566 // We eagerly create an empty fragment when inserting a fragment
567 // with a variable-size tail.
568 if (NextFragment->getNext() == OS.getCurrentFragment())
569 return;
570
571 // Macro fusion actually happens and there is no other fragment inserted
572 // after the previous instruction.
573 //
574 // Do nothing here since we already inserted a BoudaryAlign fragment when
575 // we met the first instruction in the fused pair and we'll tie them
576 // together in emitInstructionEnd.
577 //
578 // Note: When there is at least one fragment, such as MCAlignFragment,
579 // inserted after the previous instruction, e.g.
580 //
581 // \code
582 // cmp %rax %rcx
583 // .align 16
584 // je .Label0
585 // \ endcode
586 //
587 // We will treat the JCC as a unfused branch although it may be fused
588 // with the CMP.
589 return;
590 }
591
592 if (needAlign(Inst) || ((AlignBranchType & X86::AlignBranchFused) &&
593 isFirstMacroFusibleInst(Inst, *MCII))) {
594 // If we meet a unfused branch or the first instuction in a fusiable pair,
595 // insert a BoundaryAlign fragment.
596 PendingBA =
597 OS.newSpecialFragment<MCBoundaryAlignFragment>(AlignBoundary, STI);
598 }
599}
600
601/// Set the last fragment to be aligned for the BoundaryAlignFragment.
602void X86AsmBackend::emitInstructionEnd(MCObjectStreamer &OS,
603 const MCInst &Inst) {
604 // Update PrevInstOpcode here, canPadInst() reads that.
605 MCFragment *CF = OS.getCurrentFragment();
606 PrevInstOpcode = Inst.getOpcode();
607 PrevInstPosition = std::make_pair(CF, OS.getCurFragSize());
608 if (Asm->isBundlingEnabled())
609 return emitInstructionEndBundle(OS);
610
611 if (!canPadBranches(OS))
612 return;
613
614 // PrevInst is only needed if canPadBranches. Copying an MCInst isn't cheap.
615 PrevInst = Inst;
616
617 if (!needAlign(Inst) || !PendingBA)
618 return;
619
620 // Tie the aligned instructions into a pending BoundaryAlign.
621 PendingBA->setLastFragment(CF);
622 PendingBA = nullptr;
623
624 // We need to ensure that further data isn't added to the current
625 // DataFragment, so that we can get the size of instructions later in
626 // MCAssembler::relaxBoundaryAlign. The easiest way is to insert a new empty
627 // DataFragment.
628 OS.newFragment();
629
630 // Update the maximum alignment on the current section if necessary.
631 CF->getParent()->ensureMinAlignment(AlignBoundary);
632}
633
634std::optional<MCFixupKind> X86AsmBackend::getFixupKind(StringRef Name) const {
635 if (STI.getTargetTriple().isOSBinFormatELF()) {
636 unsigned Type;
637 if (STI.getTargetTriple().isX86_64()) {
638 Type = llvm::StringSwitch<unsigned>(Name)
639#define ELF_RELOC(X, Y) .Case(#X, Y)
640#include "llvm/BinaryFormat/ELFRelocs/x86_64.def"
641#undef ELF_RELOC
642 .Case("BFD_RELOC_NONE", ELF::R_X86_64_NONE)
643 .Case("BFD_RELOC_8", ELF::R_X86_64_8)
644 .Case("BFD_RELOC_16", ELF::R_X86_64_16)
645 .Case("BFD_RELOC_32", ELF::R_X86_64_32)
646 .Case("BFD_RELOC_64", ELF::R_X86_64_64)
647 .Default(-1u);
648 } else {
649 Type = llvm::StringSwitch<unsigned>(Name)
650#define ELF_RELOC(X, Y) .Case(#X, Y)
651#include "llvm/BinaryFormat/ELFRelocs/i386.def"
652#undef ELF_RELOC
653 .Case("BFD_RELOC_NONE", ELF::R_386_NONE)
654 .Case("BFD_RELOC_8", ELF::R_386_8)
655 .Case("BFD_RELOC_16", ELF::R_386_16)
656 .Case("BFD_RELOC_32", ELF::R_386_32)
657 .Default(-1u);
658 }
659 if (Type == -1u)
660 return std::nullopt;
661 return static_cast<MCFixupKind>(FirstLiteralRelocationKind + Type);
662 }
663 return MCAsmBackend::getFixupKind(Name);
664}
665
666MCFixupKindInfo X86AsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
667 const static MCFixupKindInfo Infos[X86::NumTargetFixupKinds] = {
668 // clang-format off
669 {"reloc_riprel_4byte", 0, 32, 0},
670 {"reloc_riprel_4byte_movq_load", 0, 32, 0},
671 {"reloc_riprel_4byte_movq_load_rex2", 0, 32, 0},
672 {"reloc_riprel_4byte_relax", 0, 32, 0},
673 {"reloc_riprel_4byte_relax_rex", 0, 32, 0},
674 {"reloc_riprel_4byte_relax_rex2", 0, 32, 0},
675 {"reloc_riprel_4byte_relax_evex", 0, 32, 0},
676 {"reloc_signed_4byte", 0, 32, 0},
677 {"reloc_signed_4byte_relax", 0, 32, 0},
678 {"reloc_global_offset_table", 0, 32, 0},
679 {"reloc_branch_4byte_pcrel", 0, 32, 0},
680 // clang-format on
681 };
682
683 // Fixup kinds from .reloc directive are like R_386_NONE/R_X86_64_NONE. They
684 // do not require any extra processing.
685 if (mc::isRelocation(Kind))
686 return {};
687
688 if (Kind < FirstTargetFixupKind)
690
692 "Invalid kind!");
693 assert(Infos[Kind - FirstTargetFixupKind].Name && "Empty fixup name!");
694 return Infos[Kind - FirstTargetFixupKind];
695}
696
697static unsigned getFixupKindSize(unsigned Kind) {
698 switch (Kind) {
699 default:
700 llvm_unreachable("invalid fixup kind!");
701 case FK_NONE:
702 return 0;
703 case FK_SecRel_1:
704 case FK_Data_1:
705 return 1;
706 case FK_SecRel_2:
707 case FK_Data_2:
708 return 2;
720 case FK_SecRel_4:
721 case FK_Data_4:
722 return 4;
723 case FK_SecRel_8:
724 case FK_Data_8:
725 return 8;
726 }
727}
728
729constexpr char GotSymName[] = "_GLOBAL_OFFSET_TABLE_";
730
731// Adjust PC-relative fixup offsets, which are calculated from the start of the
732// next instruction.
733std::optional<bool> X86AsmBackend::evaluateFixup(const MCFragment &,
734 MCFixup &Fixup,
735 MCValue &Target, uint64_t &) {
736 if (Fixup.isPCRel()) {
737 switch (Fixup.getKind()) {
738 case FK_Data_1:
739 Target.setConstant(Target.getConstant() - 1);
740 break;
741 case FK_Data_2:
742 Target.setConstant(Target.getConstant() - 2);
743 break;
744 default: {
745 Target.setConstant(Target.getConstant() - 4);
746 auto *Add = Target.getAddSym();
747 // If this is a pc-relative load off _GLOBAL_OFFSET_TABLE_:
748 // leaq _GLOBAL_OFFSET_TABLE_(%rip), %r15
749 // this needs to be a GOTPC32 relocation.
750 if (Add && Add->getName() == GotSymName)
751 Fixup = MCFixup::create(Fixup.getOffset(), Fixup.getValue(),
753 } break;
754 }
755 }
756 // Use default handling for `Value` and `IsResolved`.
757 return {};
758}
759
760void X86AsmBackend::applyFixup(const MCFragment &F, const MCFixup &Fixup,
761 const MCValue &Target, uint8_t *Data,
762 uint64_t Value, bool IsResolved) {
763 // Force relocation when there is a specifier. This might be too conservative
764 // - GAS doesn't emit a relocation for call local@plt; local:.
765 if (Target.getSpecifier())
766 IsResolved = false;
767 maybeAddReloc(F, Fixup, Target, Value, IsResolved);
768
769 auto Kind = Fixup.getKind();
770 if (mc::isRelocation(Kind))
771 return;
772 unsigned Size = getFixupKindSize(Kind);
773
774 assert(Fixup.getOffset() + Size <= F.getSize() && "Invalid fixup offset!");
775
776 // Check fixup value overflow similar to GAS (fixups emitted as RELA
777 // relocations have a value of 0).
778 // - Unknown signedness: the range (-2^N, 2^N) is allowed,
779 // accommodating intN_t, uintN_t, and a non-positive value type.
780 // - Signed (intN_t): the range [-2^(N-1), 2^(N-1)) is allowed.
781 //
782 // Currently only resolved PC-relative fixups are treated as signed. GAS
783 // treats more as signed (e.g. unresolved R_X86_64_32S).
784 // Unresolved fixups have unknown signedness to allow `jmp foo+0xffffffff`.
785 if (Size && Size < 8) {
786 bool Signed = IsResolved && Fixup.isPCRel();
787 uint64_t Mask = ~uint64_t(0) << (Size * 8 - (Signed ? 1 : 0));
788 if ((Value & Mask) && (Signed ? (Value & Mask) != Mask : (-Value & Mask)))
789 getContext().reportError(Fixup.getLoc(),
790 "value of " + Twine(int64_t(Value)) +
791 " is too large for field of " + Twine(Size) +
792 (Size == 1 ? " byte" : " bytes"));
793 }
794
795 for (unsigned i = 0; i != Size; ++i)
796 Data[i] = uint8_t(Value >> (i * 8));
797}
798
799bool X86AsmBackend::mayNeedRelaxation(unsigned Opcode,
801 const MCSubtargetInfo &STI) const {
802 unsigned SkipOperands = X86::isCCMPCC(Opcode) ? 2 : 0;
803 return isRelaxableBranch(Opcode) ||
804 (X86::getOpcodeForLongImmediateForm(Opcode) != Opcode &&
805 Operands[Operands.size() - 1 - SkipOperands].isExpr());
806}
807
808bool X86AsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &F,
809 const MCFixup &Fixup,
810 const MCValue &Target,
811 uint64_t Value,
812 bool Resolved) const {
813 // If resolved, relax if the value is too big for a (signed) i8.
814 //
815 // Currently, `jmp local@plt` relaxes JMP even if the offset is small,
816 // different from gas.
817 if (Resolved) {
818 // finishLayout folds padding into encodings after relaxation, shifting a
819 // branch and its target within their bundles. Keep a bundle of headroom.
820 // Immediates do not shift.
821 int64_t Slack = Asm->isBundlingEnabled() && TargetPrefixMax != 0 &&
822 isRelaxableBranch(F.getOpcode())
823 ? Asm->getBundleAlign().value()
824 : 0;
825 return !isInt<8>(int64_t(Value) + Slack) ||
826 !isInt<8>(int64_t(Value) - Slack) || Target.getSpecifier();
827 }
828
829 // Otherwise, relax unless there is a @ABS8 specifier.
830 if (Fixup.getKind() == FK_Data_1 && Target.getAddSym() &&
831 Target.getSpecifier() == X86::S_ABS8)
832 return false;
833 return true;
834}
835
836// FIXME: Can tblgen help at all here to verify there aren't other instructions
837// we can relax?
838void X86AsmBackend::relaxInstruction(MCInst &Inst,
839 const MCSubtargetInfo &STI) const {
840 // The only relaxations X86 does is from a 1byte pcrel to a 4byte pcrel.
841 bool Is16BitMode = STI.hasFeature(X86::Is16Bit);
842 unsigned RelaxedOp = getRelaxedOpcode(Inst, Is16BitMode);
843 assert(RelaxedOp != Inst.getOpcode());
844 Inst.setOpcode(RelaxedOp);
845}
846
847bool X86AsmBackend::padInstructionViaPrefix(MCFragment &RF,
848 MCCodeEmitter &Emitter,
849 unsigned &RemainingSize) const {
850 if (!RF.getAllowAutoPadding())
851 return false;
852 // If the instruction isn't fully relaxed, shifting it around might require a
853 // larger value for one of the fixups then can be encoded. The outer loop
854 // will also catch this before moving to the next instruction, but we need to
855 // prevent padding this single instruction as well.
856 if (mayNeedRelaxation(RF.getOpcode(), RF.getOperands(),
857 *RF.getSubtargetInfo()))
858 return false;
859
860 const unsigned OldSize = RF.getVarSize();
861 if (OldSize == 15)
862 return false;
863
864 const unsigned MaxPossiblePad = std::min(15 - OldSize, RemainingSize);
865 const unsigned RemainingPrefixSize = [&]() -> unsigned {
866 SmallString<15> Code;
867 X86_MC::emitPrefix(Emitter, RF.getInst(), Code, STI);
868 assert(Code.size() < 15 && "The number of prefixes must be less than 15.");
869
870 // TODO: It turns out we need a decent amount of plumbing for the target
871 // specific bits to determine number of prefixes its safe to add. Various
872 // targets (older chips mostly, but also Atom family) encounter decoder
873 // stalls with too many prefixes. For testing purposes, we set the value
874 // externally for the moment.
875 unsigned ExistingPrefixSize = Code.size();
876 if (TargetPrefixMax <= ExistingPrefixSize)
877 return 0;
878 return TargetPrefixMax - ExistingPrefixSize;
879 }();
880 const unsigned PrefixBytesToAdd =
881 std::min(MaxPossiblePad, RemainingPrefixSize);
882 if (PrefixBytesToAdd == 0)
883 return false;
884
885 const uint8_t Prefix = determinePaddingPrefix(RF.getInst());
886
887 SmallString<256> Code;
888 Code.append(PrefixBytesToAdd, Prefix);
889 Code.append(RF.getVarContents().begin(), RF.getVarContents().end());
890 RF.setVarContents(Code);
891
892 // Adjust the fixups for the change in offsets
893 for (auto &F : RF.getVarFixups())
894 F.setOffset(PrefixBytesToAdd + F.getOffset());
895
896 RemainingSize -= PrefixBytesToAdd;
897 return true;
898}
899
900bool X86AsmBackend::padInstructionViaRelaxation(MCFragment &RF,
901 MCCodeEmitter &Emitter,
902 unsigned &RemainingSize) const {
903 if (!mayNeedRelaxation(RF.getOpcode(), RF.getOperands(),
904 *RF.getSubtargetInfo()))
905 // TODO: There are lots of other tricks we could apply for increasing
906 // encoding size without impacting performance.
907 return false;
908
909 MCInst Relaxed = RF.getInst();
910 relaxInstruction(Relaxed, *RF.getSubtargetInfo());
911
913 SmallString<15> Code;
914 Emitter.encodeInstruction(Relaxed, Code, Fixups, *RF.getSubtargetInfo());
915 const unsigned OldSize = RF.getVarContents().size();
916 const unsigned NewSize = Code.size();
917 assert(NewSize >= OldSize && "size decrease during relaxation?");
918 unsigned Delta = NewSize - OldSize;
919 if (Delta > RemainingSize)
920 return false;
921 RF.setInst(Relaxed);
922 RF.setVarContents(Code);
923 RF.setVarFixups(Fixups);
924 RemainingSize -= Delta;
925 return true;
926}
927
928bool X86AsmBackend::padInstructionEncoding(MCFragment &RF,
929 MCCodeEmitter &Emitter,
930 unsigned &RemainingSize) const {
931 bool Changed = false;
932 if (RemainingSize != 0)
933 Changed |= padInstructionViaRelaxation(RF, Emitter, RemainingSize);
934 if (RemainingSize != 0)
935 Changed |= padInstructionViaPrefix(RF, Emitter, RemainingSize);
936 return Changed;
937}
938
939bool X86AsmBackend::padInstsBackward(SmallVectorImpl<MCFragment *> &Relaxable,
940 unsigned &RemainingSize) const {
941 bool Changed = false;
942 while (!Relaxable.empty() && RemainingSize != 0) {
943 auto &RF = *Relaxable.pop_back_val();
944 // Give the backend a chance to play any tricks it wishes to increase
945 // the encoding size of the given instruction. Target independent code
946 // will try further relaxation, but target's may play further tricks.
947 Changed |= padInstructionEncoding(RF, Asm->getEmitter(), RemainingSize);
948
949 // If we have an instruction which hasn't been fully relaxed, we can't
950 // skip past it and insert bytes before it. Changing its starting
951 // offset might require a larger negative offset than it can encode.
952 // We don't need to worry about larger positive offsets as none of the
953 // possible offsets between this and our align are visible, and the
954 // ones afterwards aren't changing.
955 if (mayNeedRelaxation(RF.getOpcode(), RF.getOperands(),
956 *RF.getSubtargetInfo()))
957 break;
958 }
959 Relaxable.clear();
960 return Changed;
961}
962
963/// Trade the padding held by \p BF for ignored prefixes on the instructions
964/// around it. Padding never leaves its own bundle, so no instruction or
965/// bundle-locked group moves across a boundary. \p Relaxable holds the
966/// preceding instructions in that bundle and is consumed.
967bool X86AsmBackend::foldBundlePad(
968 const MCAssembler &Asm, MCBoundaryAlignFragment &BF,
969 SmallVectorImpl<MCFragment *> &Relaxable) const {
970 const uint64_t BundleSize = Asm.getBundleAlign().value();
971 const uint64_t PadStart = Asm.getFragmentOffset(BF);
972 unsigned Remaining = BF.getSize();
973
974 // Only padding in PadStart's own bundle may move backward; an align_to_end
975 // group can push the rest into the next bundle.
976 unsigned Budget =
977 std::min<uint64_t>(Remaining, BundleSize - PadStart % BundleSize);
978 unsigned Left = Budget;
979 bool Changed = padInstsBackward(Relaxable, Left);
980 Remaining -= Budget - Left;
981
982 // Absorbing padding moves the group's start earlier while its end is pinned,
983 // so it may only grow into the slack in its bundle: BundleSize - GroupSize
984 // for align_to_end, zero for a group that already starts on a boundary.
985 if (BF.isAlignToEnd() && Remaining) {
986 uint64_t GroupSize = 0;
987 for (const MCFragment *F = BF.getNext();; F = F->getNext()) {
988 GroupSize += Asm.computeFragmentSize(*F);
989 if (F == BF.getLastFragment())
990 break;
991 }
992 if (GroupSize < BundleSize) {
993 Left = Budget = std::min<uint64_t>(Remaining, BundleSize - GroupSize);
994 for (MCFragment *F = BF.getNext(); F; F = F->getNext()) {
995 if (F->getKind() == MCFragment::FT_Relaxable)
996 Changed |= padInstructionEncoding(*F, Asm.getEmitter(), Left);
997 if (F == BF.getLastFragment() || Left == 0)
998 break;
999 }
1000 Remaining -= Budget - Left;
1001 }
1002 }
1003
1004 BF.setSize(Remaining);
1005 return Changed;
1006}
1007
1008bool X86AsmBackend::optimizeBundleNops(const MCAssembler &Asm) const {
1009 const uint64_t BundleSize = Asm.getBundleAlign().value();
1010 bool Changed = false;
1011 for (MCSection &Sec : Asm) {
1012 if (!Sec.isText())
1013 continue;
1014
1015 // Instructions preceding the next padding and sharing its bundle.
1017 // Folding leaves stale offsets until the next layout, so skip the
1018 // rewritten range.
1019 const MCFragment *ResumeAfter = nullptr;
1020 for (MCFragment &F : Sec) {
1021 if (ResumeAfter) {
1022 if (&F == ResumeAfter)
1023 ResumeAfter = nullptr;
1024 continue;
1025 }
1026 uint64_t Offset = Asm.getFragmentOffset(F);
1027 if (!Relaxable.empty() &&
1028 Asm.getFragmentOffset(*Relaxable.front()) / BundleSize !=
1029 Offset / BundleSize)
1030 Relaxable.clear();
1031
1032 switch (F.getKind()) {
1034 auto &BF = static_cast<MCBoundaryAlignFragment &>(F);
1035 if (!BF.getSize())
1036 break; // Nothing to fold, and not a barrier.
1037 Changed |= foldBundlePad(Asm, BF, Relaxable);
1038 ResumeAfter = BF.getLastFragment();
1039 break;
1040 }
1042 Relaxable.push_back(&F);
1043 break;
1045 break; // Fixed bytes, safe to shift.
1046 default:
1047 // Other kinds may change size when shifted (.p2align, .org, LEBs).
1048 Relaxable.clear();
1049 break;
1050 }
1051 }
1052 }
1053
1054 return Changed;
1055}
1056
1057bool X86AsmBackend::finishLayout() const {
1058 // With bundling, padding is fully determined during layout and the only
1059 // post-layout optimization is prefix padding.
1060 if (Asm->isBundlingEnabled())
1061 return TargetPrefixMax != 0 && optimizeBundleNops(*Asm);
1062 // See if we can further relax some instructions to cut down on the number of
1063 // nop bytes required for code alignment. The actual win is in reducing
1064 // instruction count, not number of bytes. Modern X86-64 can easily end up
1065 // decode limited. It is often better to reduce the number of instructions
1066 // (i.e. eliminate nops) even at the cost of increasing the size and
1067 // complexity of others.
1068 if (!X86PadForAlign && !X86PadForBranchAlign)
1069 return false;
1070
1071 // The processed regions are delimitered by LabeledFragments. -g may have more
1072 // MCSymbols and therefore different relaxation results. X86PadForAlign is
1073 // disabled by default to eliminate the -g vs non -g difference.
1074 DenseSet<MCFragment *> LabeledFragments;
1075 for (const MCSymbol &S : Asm->symbols())
1076 LabeledFragments.insert(S.getFragment());
1077
1078 bool Changed = false;
1079 for (MCSection &Sec : *Asm) {
1080 if (!Sec.isText())
1081 continue;
1082
1084 for (MCSection::iterator I = Sec.begin(), IE = Sec.end(); I != IE; ++I) {
1085 MCFragment &F = *I;
1086
1087 if (LabeledFragments.count(&F))
1088 Relaxable.clear();
1089
1090 if (F.getKind() == MCFragment::FT_Data) // Skip and ignore
1091 continue;
1092
1093 if (F.getKind() == MCFragment::FT_Relaxable) {
1094 auto &RF = cast<MCFragment>(*I);
1095 Relaxable.push_back(&RF);
1096 continue;
1097 }
1098
1099 auto canHandle = [](MCFragment &F) -> bool {
1100 switch (F.getKind()) {
1101 default:
1102 return false;
1104 return X86PadForAlign;
1106 return X86PadForBranchAlign;
1107 }
1108 };
1109 // For any unhandled kind, assume we can't change layout.
1110 if (!canHandle(F)) {
1111 Relaxable.clear();
1112 continue;
1113 }
1114
1115 // To keep the effects local, prefer to relax instructions closest to
1116 // the align directive. This is purely about human understandability
1117 // of the resulting code. If we later find a reason to expand
1118 // particular instructions over others, we can adjust.
1119 unsigned RemainingSize = Asm->computeFragmentSize(F) - F.getFixedSize();
1120 Changed |= padInstsBackward(Relaxable, RemainingSize);
1121
1122 // If we're looking at a boundary align, make sure we don't try to pad
1123 // its target instructions for some following directive. Doing so would
1124 // break the alignment of the current boundary align.
1125 if (auto *BF = dyn_cast<MCBoundaryAlignFragment>(&F)) {
1126 cast<MCBoundaryAlignFragment>(F).setSize(RemainingSize);
1127 Changed = true;
1128 const MCFragment *LastFragment = BF->getLastFragment();
1129 if (!LastFragment)
1130 continue;
1131 while (&*I != LastFragment)
1132 ++I;
1133 }
1134 }
1135 }
1136
1137 return Changed;
1138}
1139
1140unsigned X86AsmBackend::getMaximumNopSize(const MCSubtargetInfo &STI) const {
1141 if (STI.hasFeature(X86::Is16Bit))
1142 return 4;
1143 if (!STI.hasFeature(X86::FeatureNOPL) && !STI.hasFeature(X86::Is64Bit))
1144 return 1;
1145 if (STI.hasFeature(X86::TuningFast7ByteNOP))
1146 return 7;
1147 if (STI.hasFeature(X86::TuningFast15ByteNOP))
1148 return 15;
1149 if (STI.hasFeature(X86::TuningFast11ByteNOP))
1150 return 11;
1151 // FIXME: handle 32-bit mode
1152 // 15-bytes is the longest single NOP instruction, but 10-bytes is
1153 // commonly the longest that can be efficiently decoded.
1154 return 10;
1155}
1156
1157/// Write a sequence of optimal nops to the output, covering \p Count
1158/// bytes.
1159/// \return - true on success, false on failure
1160bool X86AsmBackend::writeNopData(raw_ostream &OS, uint64_t Count,
1161 const MCSubtargetInfo *STI) const {
1162 static const char Nops32Bit[10][11] = {
1163 // nop
1164 "\x90",
1165 // xchg %ax,%ax
1166 "\x66\x90",
1167 // nopl (%[re]ax)
1168 "\x0f\x1f\x00",
1169 // nopl 0(%[re]ax)
1170 "\x0f\x1f\x40\x00",
1171 // nopl 0(%[re]ax,%[re]ax,1)
1172 "\x0f\x1f\x44\x00\x00",
1173 // nopw 0(%[re]ax,%[re]ax,1)
1174 "\x66\x0f\x1f\x44\x00\x00",
1175 // nopl 0L(%[re]ax)
1176 "\x0f\x1f\x80\x00\x00\x00\x00",
1177 // nopl 0L(%[re]ax,%[re]ax,1)
1178 "\x0f\x1f\x84\x00\x00\x00\x00\x00",
1179 // nopw 0L(%[re]ax,%[re]ax,1)
1180 "\x66\x0f\x1f\x84\x00\x00\x00\x00\x00",
1181 // nopw %cs:0L(%[re]ax,%[re]ax,1)
1182 "\x66\x2e\x0f\x1f\x84\x00\x00\x00\x00\x00",
1183 };
1184
1185 // 16-bit mode uses different nop patterns than 32-bit.
1186 static const char Nops16Bit[4][11] = {
1187 // nop
1188 "\x90",
1189 // xchg %eax,%eax
1190 "\x66\x90",
1191 // lea 0(%si),%si
1192 "\x8d\x74\x00",
1193 // lea 0w(%si),%si
1194 "\x8d\xb4\x00\x00",
1195 };
1196
1197 const char(*Nops)[11] =
1198 STI->hasFeature(X86::Is16Bit) ? Nops16Bit : Nops32Bit;
1199
1200 uint64_t MaxNopLength = (uint64_t)getMaximumNopSize(*STI);
1201
1202 // Emit as many MaxNopLength NOPs as needed, then emit a NOP of the remaining
1203 // length.
1204 do {
1205 const uint8_t ThisNopLength = (uint8_t) std::min(Count, MaxNopLength);
1206 const uint8_t Prefixes = ThisNopLength <= 10 ? 0 : ThisNopLength - 10;
1207 for (uint8_t i = 0; i < Prefixes; i++)
1208 OS << '\x66';
1209 const uint8_t Rest = ThisNopLength - Prefixes;
1210 if (Rest != 0)
1211 OS.write(Nops[Rest - 1], Rest);
1212 Count -= ThisNopLength;
1213 } while (Count != 0);
1214
1215 return true;
1216}
1217
1218/* *** */
1219
1220namespace {
1221
1222class ELFX86AsmBackend : public X86AsmBackend {
1223public:
1224 uint8_t OSABI;
1225 ELFX86AsmBackend(const Target &T, uint8_t OSABI, const MCSubtargetInfo &STI)
1226 : X86AsmBackend(T, STI), OSABI(OSABI) {}
1227};
1228
1229class ELFX86_32AsmBackend : public ELFX86AsmBackend {
1230public:
1231 ELFX86_32AsmBackend(const Target &T, uint8_t OSABI,
1232 const MCSubtargetInfo &STI)
1233 : ELFX86AsmBackend(T, OSABI, STI) {}
1234
1235 std::unique_ptr<MCObjectTargetWriter>
1236 createObjectTargetWriter() const override {
1237 return createX86ELFObjectWriter(/*IsELF64*/ false, OSABI, ELF::EM_386);
1238 }
1239};
1240
1241class ELFX86_X32AsmBackend : public ELFX86AsmBackend {
1242public:
1243 ELFX86_X32AsmBackend(const Target &T, uint8_t OSABI,
1244 const MCSubtargetInfo &STI)
1245 : ELFX86AsmBackend(T, OSABI, STI) {}
1246
1247 std::unique_ptr<MCObjectTargetWriter>
1248 createObjectTargetWriter() const override {
1249 return createX86ELFObjectWriter(/*IsELF64*/ false, OSABI,
1251 }
1252};
1253
1254class ELFX86_IAMCUAsmBackend : public ELFX86AsmBackend {
1255public:
1256 ELFX86_IAMCUAsmBackend(const Target &T, uint8_t OSABI,
1257 const MCSubtargetInfo &STI)
1258 : ELFX86AsmBackend(T, OSABI, STI) {}
1259
1260 std::unique_ptr<MCObjectTargetWriter>
1261 createObjectTargetWriter() const override {
1262 return createX86ELFObjectWriter(/*IsELF64*/ false, OSABI,
1264 }
1265};
1266
1267class ELFX86_64AsmBackend : public ELFX86AsmBackend {
1268public:
1269 ELFX86_64AsmBackend(const Target &T, uint8_t OSABI,
1270 const MCSubtargetInfo &STI)
1271 : ELFX86AsmBackend(T, OSABI, STI) {}
1272
1273 std::unique_ptr<MCObjectTargetWriter>
1274 createObjectTargetWriter() const override {
1275 return createX86ELFObjectWriter(/*IsELF64*/ true, OSABI, ELF::EM_X86_64);
1276 }
1277};
1278
1279class WindowsX86AsmBackend : public X86AsmBackend {
1280 bool Is64Bit;
1281
1282public:
1283 WindowsX86AsmBackend(const Target &T, bool is64Bit,
1284 const MCSubtargetInfo &STI)
1285 : X86AsmBackend(T, STI)
1286 , Is64Bit(is64Bit) {
1287 }
1288
1289 std::optional<MCFixupKind> getFixupKind(StringRef Name) const override {
1290 return StringSwitch<std::optional<MCFixupKind>>(Name)
1291 .Case("dir32", FK_Data_4)
1292 .Case("secrel32", FK_SecRel_4)
1293 .Case("secidx", FK_SecRel_2)
1294 .Default(MCAsmBackend::getFixupKind(Name));
1295 }
1296
1297 std::unique_ptr<MCObjectTargetWriter>
1298 createObjectTargetWriter() const override {
1299 return createX86WinCOFFObjectWriter(Is64Bit);
1300 }
1301};
1302
1303namespace CU {
1304
1305 /// Compact unwind encoding values.
1306 enum CompactUnwindEncodings {
1307 /// [RE]BP based frame where [RE]BP is pused on the stack immediately after
1308 /// the return address, then [RE]SP is moved to [RE]BP.
1309 UNWIND_MODE_BP_FRAME = 0x01000000,
1310
1311 /// A frameless function with a small constant stack size.
1312 UNWIND_MODE_STACK_IMMD = 0x02000000,
1313
1314 /// A frameless function with a large constant stack size.
1315 UNWIND_MODE_STACK_IND = 0x03000000,
1316
1317 /// No compact unwind encoding is available.
1318 UNWIND_MODE_DWARF = 0x04000000,
1319
1320 /// Mask for encoding the frame registers.
1321 UNWIND_BP_FRAME_REGISTERS = 0x00007FFF,
1322
1323 /// Mask for encoding the frameless registers.
1324 UNWIND_FRAMELESS_STACK_REG_PERMUTATION = 0x000003FF
1325 };
1326
1327} // namespace CU
1328
1329class DarwinX86AsmBackend : public X86AsmBackend {
1330 const MCRegisterInfo &MRI;
1331
1332 /// Number of registers that can be saved in a compact unwind encoding.
1333 enum { CU_NUM_SAVED_REGS = 6 };
1334
1335 mutable unsigned SavedRegs[CU_NUM_SAVED_REGS];
1336 Triple TT;
1337 bool Is64Bit;
1338
1339 unsigned OffsetSize; ///< Offset of a "push" instruction.
1340 unsigned MoveInstrSize; ///< Size of a "move" instruction.
1341 unsigned StackDivide; ///< Amount to adjust stack size by.
1342protected:
1343 /// Size of a "push" instruction for the given register.
1344 unsigned PushInstrSize(MCRegister Reg) const {
1345 switch (Reg.id()) {
1346 case X86::EBX:
1347 case X86::ECX:
1348 case X86::EDX:
1349 case X86::EDI:
1350 case X86::ESI:
1351 case X86::EBP:
1352 case X86::RBX:
1353 case X86::RBP:
1354 return 1;
1355 case X86::R12:
1356 case X86::R13:
1357 case X86::R14:
1358 case X86::R15:
1359 return 2;
1360 }
1361 return 1;
1362 }
1363
1364private:
1365 /// Get the compact unwind number for a given register. The number
1366 /// corresponds to the enum lists in compact_unwind_encoding.h.
1367 int getCompactUnwindRegNum(unsigned Reg) const {
1368 static const MCPhysReg CU32BitRegs[7] = {
1369 X86::EBX, X86::ECX, X86::EDX, X86::EDI, X86::ESI, X86::EBP, 0
1370 };
1371 static const MCPhysReg CU64BitRegs[] = {
1372 X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0
1373 };
1374 const MCPhysReg *CURegs = Is64Bit ? CU64BitRegs : CU32BitRegs;
1375 for (int Idx = 1; *CURegs; ++CURegs, ++Idx)
1376 if (*CURegs == Reg)
1377 return Idx;
1378
1379 return -1;
1380 }
1381
1382 /// Return the registers encoded for a compact encoding with a frame
1383 /// pointer.
1384 uint32_t encodeCompactUnwindRegistersWithFrame() const {
1385 // Encode the registers in the order they were saved --- 3-bits per
1386 // register. The list of saved registers is assumed to be in reverse
1387 // order. The registers are numbered from 1 to CU_NUM_SAVED_REGS.
1388 uint32_t RegEnc = 0;
1389 for (int i = 0, Idx = 0; i != CU_NUM_SAVED_REGS; ++i) {
1390 unsigned Reg = SavedRegs[i];
1391 if (Reg == 0) break;
1392
1393 int CURegNum = getCompactUnwindRegNum(Reg);
1394 if (CURegNum == -1) return ~0U;
1395
1396 // Encode the 3-bit register number in order, skipping over 3-bits for
1397 // each register.
1398 RegEnc |= (CURegNum & 0x7) << (Idx++ * 3);
1399 }
1400
1401 assert((RegEnc & 0x3FFFF) == RegEnc &&
1402 "Invalid compact register encoding!");
1403 return RegEnc;
1404 }
1405
1406 /// Create the permutation encoding used with frameless stacks. It is
1407 /// passed the number of registers to be saved and an array of the registers
1408 /// saved.
1409 uint32_t encodeCompactUnwindRegistersWithoutFrame(unsigned RegCount) const {
1410 // The saved registers are numbered from 1 to 6. In order to encode the
1411 // order in which they were saved, we re-number them according to their
1412 // place in the register order. The re-numbering is relative to the last
1413 // re-numbered register. E.g., if we have registers {6, 2, 4, 5} saved in
1414 // that order:
1415 //
1416 // Orig Re-Num
1417 // ---- ------
1418 // 6 6
1419 // 2 2
1420 // 4 3
1421 // 5 3
1422 //
1423 for (unsigned i = 0; i < RegCount; ++i) {
1424 int CUReg = getCompactUnwindRegNum(SavedRegs[i]);
1425 if (CUReg == -1) return ~0U;
1426 SavedRegs[i] = CUReg;
1427 }
1428
1429 // Reverse the list.
1430 std::reverse(&SavedRegs[0], &SavedRegs[CU_NUM_SAVED_REGS]);
1431
1432 uint32_t RenumRegs[CU_NUM_SAVED_REGS];
1433 for (unsigned i = CU_NUM_SAVED_REGS - RegCount; i < CU_NUM_SAVED_REGS; ++i){
1434 unsigned Countless = 0;
1435 for (unsigned j = CU_NUM_SAVED_REGS - RegCount; j < i; ++j)
1436 if (SavedRegs[j] < SavedRegs[i])
1437 ++Countless;
1438
1439 RenumRegs[i] = SavedRegs[i] - Countless - 1;
1440 }
1441
1442 // Take the renumbered values and encode them into a 10-bit number.
1443 uint32_t permutationEncoding = 0;
1444 switch (RegCount) {
1445 case 6:
1446 permutationEncoding |= 120 * RenumRegs[0] + 24 * RenumRegs[1]
1447 + 6 * RenumRegs[2] + 2 * RenumRegs[3]
1448 + RenumRegs[4];
1449 break;
1450 case 5:
1451 permutationEncoding |= 120 * RenumRegs[1] + 24 * RenumRegs[2]
1452 + 6 * RenumRegs[3] + 2 * RenumRegs[4]
1453 + RenumRegs[5];
1454 break;
1455 case 4:
1456 permutationEncoding |= 60 * RenumRegs[2] + 12 * RenumRegs[3]
1457 + 3 * RenumRegs[4] + RenumRegs[5];
1458 break;
1459 case 3:
1460 permutationEncoding |= 20 * RenumRegs[3] + 4 * RenumRegs[4]
1461 + RenumRegs[5];
1462 break;
1463 case 2:
1464 permutationEncoding |= 5 * RenumRegs[4] + RenumRegs[5];
1465 break;
1466 case 1:
1467 permutationEncoding |= RenumRegs[5];
1468 break;
1469 }
1470
1471 assert((permutationEncoding & 0x3FF) == permutationEncoding &&
1472 "Invalid compact register encoding!");
1473 return permutationEncoding;
1474 }
1475
1476public:
1477 DarwinX86AsmBackend(const Target &T, const MCRegisterInfo &MRI,
1478 const MCSubtargetInfo &STI)
1479 : X86AsmBackend(T, STI), MRI(MRI), TT(STI.getTargetTriple()),
1480 Is64Bit(TT.isX86_64()) {
1481 memset(SavedRegs, 0, sizeof(SavedRegs));
1482 OffsetSize = Is64Bit ? 8 : 4;
1483 MoveInstrSize = Is64Bit ? 3 : 2;
1484 StackDivide = Is64Bit ? 8 : 4;
1485 }
1486
1487 std::unique_ptr<MCObjectTargetWriter>
1488 createObjectTargetWriter() const override {
1489 uint32_t CPUType = cantFail(MachO::getCPUType(TT));
1490 uint32_t CPUSubType = cantFail(MachO::getCPUSubType(TT));
1491 return createX86MachObjectWriter(Is64Bit, CPUType, CPUSubType);
1492 }
1493
1494 /// Implementation of algorithm to generate the compact unwind encoding
1495 /// for the CFI instructions.
1496 uint64_t generateCompactUnwindEncoding(const MCDwarfFrameInfo *FI,
1497 const MCContext *Ctxt) const override {
1498 if (Ctxt->emitDwarfUnwindInfo() == EmitDwarfUnwindType::DwarfOnly)
1499 return CU::UNWIND_MODE_DWARF;
1500
1501 // Signal frames cannot be encoded in compact unwind.
1502 if (FI->IsSignalFrame)
1503 return CU::UNWIND_MODE_DWARF;
1504
1506 if (Instrs.empty()) return 0;
1507 if (!isDarwinCanonicalPersonality(FI->Personality) &&
1509 return CU::UNWIND_MODE_DWARF;
1510
1511 // Reset the saved registers.
1512 unsigned SavedRegIdx = 0;
1513 memset(SavedRegs, 0, sizeof(SavedRegs));
1514
1515 bool HasFP = false;
1516
1517 // Encode that we are using EBP/RBP as the frame pointer.
1518 uint64_t CompactUnwindEncoding = 0;
1519
1520 unsigned SubtractInstrIdx = Is64Bit ? 3 : 2;
1521 unsigned InstrOffset = 0;
1522 unsigned StackAdjust = 0;
1523 uint64_t StackSize = 0;
1524 int64_t MinAbsOffset = std::numeric_limits<int64_t>::max();
1525
1526 for (const MCCFIInstruction &Inst : Instrs) {
1527 switch (Inst.getOperation()) {
1528 default:
1529 // Any other CFI directives indicate a frame that we aren't prepared
1530 // to represent via compact unwind, so just bail out.
1531 return CU::UNWIND_MODE_DWARF;
1533 // Defines a frame pointer. E.g.
1534 //
1535 // movq %rsp, %rbp
1536 // L0:
1537 // .cfi_def_cfa_register %rbp
1538 //
1539 HasFP = true;
1540
1541 // If the frame pointer is other than esp/rsp, we do not have a way to
1542 // generate a compact unwinding representation, so bail out.
1543 if (*MRI.getLLVMRegNum(Inst.getRegister(), true) !=
1544 (Is64Bit ? X86::RBP : X86::EBP))
1545 return CU::UNWIND_MODE_DWARF;
1546
1547 // Reset the counts.
1548 memset(SavedRegs, 0, sizeof(SavedRegs));
1549 StackAdjust = 0;
1550 SavedRegIdx = 0;
1551 MinAbsOffset = std::numeric_limits<int64_t>::max();
1552 InstrOffset += MoveInstrSize;
1553 break;
1554 }
1556 // Defines a new offset for the CFA. E.g.
1557 //
1558 // With frame:
1559 //
1560 // pushq %rbp
1561 // L0:
1562 // .cfi_def_cfa_offset 16
1563 //
1564 // Without frame:
1565 //
1566 // subq $72, %rsp
1567 // L0:
1568 // .cfi_def_cfa_offset 80
1569 //
1570 StackSize = Inst.getOffset() / StackDivide;
1571 break;
1572 }
1574 // Defines a "push" of a callee-saved register. E.g.
1575 //
1576 // pushq %r15
1577 // pushq %r14
1578 // pushq %rbx
1579 // L0:
1580 // subq $120, %rsp
1581 // L1:
1582 // .cfi_offset %rbx, -40
1583 // .cfi_offset %r14, -32
1584 // .cfi_offset %r15, -24
1585 //
1586 if (SavedRegIdx == CU_NUM_SAVED_REGS)
1587 // If there are too many saved registers, we cannot use a compact
1588 // unwind encoding.
1589 return CU::UNWIND_MODE_DWARF;
1590
1591 MCRegister Reg = *MRI.getLLVMRegNum(Inst.getRegister(), true);
1592 SavedRegs[SavedRegIdx++] = Reg.id();
1593 StackAdjust += OffsetSize;
1594 MinAbsOffset = std::min(MinAbsOffset, std::abs(Inst.getOffset()));
1595 InstrOffset += PushInstrSize(Reg);
1596 break;
1597 }
1598 }
1599 }
1600
1601 StackAdjust /= StackDivide;
1602
1603 if (HasFP) {
1604 if ((StackAdjust & 0xFF) != StackAdjust)
1605 // Offset was too big for a compact unwind encoding.
1606 return CU::UNWIND_MODE_DWARF;
1607
1608 // We don't attempt to track a real StackAdjust, so if the saved registers
1609 // aren't adjacent to rbp we can't cope.
1610 if (SavedRegIdx != 0 && MinAbsOffset != 3 * (int)OffsetSize)
1611 return CU::UNWIND_MODE_DWARF;
1612
1613 // Get the encoding of the saved registers when we have a frame pointer.
1614 uint32_t RegEnc = encodeCompactUnwindRegistersWithFrame();
1615 if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
1616
1617 CompactUnwindEncoding |= CU::UNWIND_MODE_BP_FRAME;
1618 CompactUnwindEncoding |= (StackAdjust & 0xFF) << 16;
1619 CompactUnwindEncoding |= RegEnc & CU::UNWIND_BP_FRAME_REGISTERS;
1620 } else {
1621 SubtractInstrIdx += InstrOffset;
1622 ++StackAdjust;
1623
1624 if ((StackSize & 0xFF) == StackSize) {
1625 // Frameless stack with a small stack size.
1626 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IMMD;
1627
1628 // Encode the stack size.
1629 CompactUnwindEncoding |= (StackSize & 0xFF) << 16;
1630 } else {
1631 if ((StackAdjust & 0x7) != StackAdjust)
1632 // The extra stack adjustments are too big for us to handle.
1633 return CU::UNWIND_MODE_DWARF;
1634
1635 // Frameless stack with an offset too large for us to encode compactly.
1636 CompactUnwindEncoding |= CU::UNWIND_MODE_STACK_IND;
1637
1638 // Encode the offset to the nnnnnn value in the 'subl $nnnnnn, ESP'
1639 // instruction.
1640 CompactUnwindEncoding |= (SubtractInstrIdx & 0xFF) << 16;
1641
1642 // Encode any extra stack adjustments (done via push instructions).
1643 CompactUnwindEncoding |= (StackAdjust & 0x7) << 13;
1644 }
1645
1646 // Encode the number of registers saved. (Reverse the list first.)
1647 std::reverse(&SavedRegs[0], &SavedRegs[SavedRegIdx]);
1648 CompactUnwindEncoding |= (SavedRegIdx & 0x7) << 10;
1649
1650 // Get the encoding of the saved registers when we don't have a frame
1651 // pointer.
1652 uint32_t RegEnc = encodeCompactUnwindRegistersWithoutFrame(SavedRegIdx);
1653 if (RegEnc == ~0U) return CU::UNWIND_MODE_DWARF;
1654
1655 // Encode the register encoding.
1656 CompactUnwindEncoding |=
1657 RegEnc & CU::UNWIND_FRAMELESS_STACK_REG_PERMUTATION;
1658 }
1659
1660 return CompactUnwindEncoding;
1661 }
1662};
1663
1664} // end anonymous namespace
1665
1667 const MCSubtargetInfo &STI,
1668 const MCRegisterInfo &MRI,
1669 const MCTargetOptions &Options) {
1670 const Triple &TheTriple = STI.getTargetTriple();
1671 if (TheTriple.isOSBinFormatMachO())
1672 return new DarwinX86AsmBackend(T, MRI, STI);
1673
1674 if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
1675 return new WindowsX86AsmBackend(T, false, STI);
1676
1677 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
1678
1679 if (TheTriple.isOSIAMCU())
1680 return new ELFX86_IAMCUAsmBackend(T, OSABI, STI);
1681
1682 return new ELFX86_32AsmBackend(T, OSABI, STI);
1683}
1684
1686 const MCSubtargetInfo &STI,
1687 const MCRegisterInfo &MRI,
1688 const MCTargetOptions &Options) {
1689 const Triple &TheTriple = STI.getTargetTriple();
1690 if (TheTriple.isOSBinFormatMachO())
1691 return new DarwinX86AsmBackend(T, MRI, STI);
1692
1693 if (TheTriple.isOSWindows() && TheTriple.isOSBinFormatCOFF())
1694 return new WindowsX86AsmBackend(T, true, STI);
1695
1696 if (TheTriple.isUEFI()) {
1697 assert(TheTriple.isOSBinFormatCOFF() &&
1698 "Only COFF format is supported in UEFI environment.");
1699 return new WindowsX86AsmBackend(T, true, STI);
1700 }
1701
1702 uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TheTriple.getOS());
1703
1704 if (TheTriple.isX32())
1705 return new ELFX86_X32AsmBackend(T, OSABI, STI);
1706 return new ELFX86_64AsmBackend(T, OSABI, STI);
1707}
1708
1709namespace {
1710class X86ELFStreamer : public MCELFStreamer {
1711public:
1712 X86ELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
1713 std::unique_ptr<MCObjectWriter> OW,
1714 std::unique_ptr<MCCodeEmitter> Emitter)
1715 : MCELFStreamer(Context, std::move(TAB), std::move(OW),
1716 std::move(Emitter)) {}
1717
1718 void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
1719};
1720} // end anonymous namespace
1721
1722void X86ELFStreamer::emitInstruction(const MCInst &Inst,
1723 const MCSubtargetInfo &STI) {
1724 X86_MC::emitInstruction(*this, Inst, STI);
1725}
1726
1728 std::unique_ptr<MCAsmBackend> &&MAB,
1729 std::unique_ptr<MCObjectWriter> &&MOW,
1730 std::unique_ptr<MCCodeEmitter> &&MCE) {
1731 return new X86ELFStreamer(Context, std::move(MAB), std::move(MOW),
1732 std::move(MCE));
1733}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:343
dxil DXContainer Global Emitter
IRTranslator LLVM IR MI
static LVOptions Options
Definition LVOptions.cpp:25
static unsigned getRelaxedOpcode(unsigned Opcode)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
#define T
PowerPC TLS Dynamic Call Fixup
if(PassOpts->AAPipeline)
SI Fold Operands
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.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
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...
Definition MCSection.h:539
void setSize(uint64_t Value)
Definition MCSection.h:559
const MCFragment * getLastFragment() const
Definition MCSection.h:567
void setLastFragment(const MCFragment *F)
Definition MCSection.h:568
Context object for machine code objects.
Definition MCContext.h:83
LLVM_ABI bool emitCompactUnwindNonCanonical() const
LLVM_ABI EmitDwarfUnwindType emitDwarfUnwindInfo() const
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
@ SymbolRef
References to labels and assigned expressions.
Definition MCExpr.h:43
ExprKind getKind() const
Definition MCExpr.h:85
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
Definition MCFixup.h:61
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Definition MCFixup.h:86
bool getAllowAutoPadding() const
Definition MCSection.h:209
void setAllowAutoPadding(bool V)
Definition MCSection.h:210
MCInst getInst() const
Definition MCSection.h:741
unsigned getOpcode() const
Definition MCSection.h:249
MCSection * getParent() const
Definition MCSection.h:181
LLVM_ABI void setVarFixups(ArrayRef< MCFixup > Fixups)
MCFragment * getNext() const
Definition MCSection.h:177
ArrayRef< MCOperand > getOperands() const
Definition MCSection.h:736
size_t getVarSize() const
Definition MCSection.h:224
LLVM_ABI void setVarContents(ArrayRef< char > Contents)
Definition MCSection.cpp:61
MutableArrayRef< char > getVarContents()
Definition MCSection.h:707
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
Definition MCSection.h:197
MutableArrayRef< MCFixup > getVarFixups()
Definition MCSection.h:727
void setInst(const MCInst &Inst)
Definition MCSection.h:750
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
unsigned getOpcode() const
Definition MCInst.h:202
void setOpcode(unsigned Op)
Definition MCInst.h:201
const MCOperand & getOperand(unsigned i) const
Definition MCInst.h:210
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.
Definition MCInstrInfo.h:27
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition MCInstrInfo.h:89
Streaming object file generation interface.
FT * newSpecialFragment(Args &&...args)
MCAssembler & getAssembler()
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
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.
Definition MCRegister.h:41
void ensureMinAlignment(Align MinAlignment)
Makes sure that Alignment is at least MinAlignment.
Definition MCSection.h:668
bool isText() const
Definition MCSection.h:651
Streaming machine code generation interface.
Definition MCStreamer.h:222
MCFragment * getCurrentFragment() const
Definition MCStreamer.h:449
SMLoc getStartTokLoc() const
Definition MCStreamer.h:314
size_t getCurFragSize() const
Definition MCStreamer.h:458
bool getAllowAutoPadding() const
Definition MCStreamer.h:341
MCSection * getCurrentSectionOnly() const
Definition MCStreamer.h:438
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
const Triple & getTargetTriple() const
iterator end() const
Definition ArrayRef.h:339
iterator begin() const
Definition ArrayRef.h:338
constexpr unsigned id() const
Definition Register.h:100
void push_back(const T &Elt)
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
bool isX86_64() const
Tests whether the target is x86 (64-bit).
Definition Triple.h:1203
bool isX32() const
Tests whether the target is X32.
Definition Triple.h:1229
bool isOSBinFormatMachO() const
Tests whether the environment is MachO.
Definition Triple.h:873
OSType getOS() const
Get the parsed operating system type of this triple.
Definition Triple.h:521
bool isOSBinFormatCOFF() const
Tests whether the OS uses the COFF binary format.
Definition Triple.h:867
bool isUEFI() const
Tests whether the OS is UEFI.
Definition Triple.h:772
bool isOSWindows() const
Tests whether the OS is Windows.
Definition Triple.h:775
bool isOSIAMCU() const
Definition Triple.h:754
bool isOSBinFormatELF() const
Tests whether the OS uses the ELF binary format.
Definition Triple.h:864
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition DenseSet.h:187
raw_ostream & write(unsigned char C)
Changed
#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.
@ EM_386
Definition ELF.h:141
@ EM_X86_64
Definition ELF.h:183
@ EM_IAMCU
Definition ELF.h:144
LLVM_ABI Expected< uint32_t > getCPUSubType(const Triple &T)
Definition MachO.cpp:107
LLVM_ABI Expected< uint32_t > getCPUType(const Triple &T)
Definition MachO.cpp:87
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.
@ AlignBranchIndirect
SecondMacroFusionInstKind
EncodingOfSegmentOverridePrefix getSegmentOverridePrefixForReg(MCRegister Reg)
Given a segment register, return the encoding of the segment override prefix for it.
FirstMacroFusionInstKind
unsigned getOpcodeForLongImmediateForm(unsigned Opcode)
bool isMacroFused(FirstMacroFusionInstKind FirstKind, SecondMacroFusionInstKind SecondKind)
@ reloc_riprel_4byte_movq_load_rex2
@ reloc_signed_4byte_relax
@ reloc_branch_4byte_pcrel
@ NumTargetFixupKinds
@ 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)
bool isRelocation(MCFixupKind FixupKind)
Definition MCFixup.h:130
NodeAddr< CodeNode * > Code
Definition RDFGraph.h:388
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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.
Op::Description Desc
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
uint16_t MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition MCFixup.h:22
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.
@ FirstTargetFixupKind
Definition MCFixup.h:44
@ FK_SecRel_2
A two-byte section relative fixup.
Definition MCFixup.h:40
@ FirstLiteralRelocationKind
Definition MCFixup.h:29
@ FK_Data_8
A eight-byte fixup.
Definition MCFixup.h:37
@ FK_Data_1
A one-byte fixup.
Definition MCFixup.h:34
@ FK_Data_4
A four-byte fixup.
Definition MCFixup.h:36
@ FK_SecRel_8
A eight-byte section relative fixup.
Definition MCFixup.h:42
@ FK_NONE
A no-op fixup.
Definition MCFixup.h:33
@ FK_SecRel_4
A four-byte section relative fixup.
Definition MCFixup.h:41
@ FK_SecRel_1
A one-byte section relative fixup.
Definition MCFixup.h:39
@ FK_Data_2
A two-byte fixup.
Definition MCFixup.h:35
void cantFail(Error Err, const char *Msg=nullptr)
Report a fatal error if Err is a failure value.
Definition Error.h:769
std::unique_ptr< MCObjectTargetWriter > createX86MachObjectWriter(bool Is64Bit, uint32_t CPUType, uint32_t CPUSubtype)
Construct an X86 Mach-O object writer.
@ Add
Sum of integers.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
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.
Definition STLExtras.h:1917
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
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.
Definition Alignment.h:100
endianness
Definition bit.h:71
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.
Definition BitVector.h:878
const MCSymbol * Personality
Definition MCDwarf.h:904
std::vector< MCCFIInstruction > Instructions
Definition MCDwarf.h:906