LLVM: lib/MC/MCAssembler.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
36#include
37#include
38#include
39#include
40
41using namespace llvm;
42
43namespace llvm {
45}
46
47#define DEBUG_TYPE "assembler"
48
49namespace {
51
52STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total");
53STATISTIC(EmittedRelaxableFragments,
54 "Number of emitted assembler fragments - relaxable");
56 "Number of emitted assembler fragments - data");
58 "Number of emitted assembler fragments - align");
60 "Number of emitted assembler fragments - fill");
61STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops");
62STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org");
63STATISTIC(Fixups, "Number of fixups");
64STATISTIC(FixupEvalForRelax, "Number of fixup evaluations for relaxation");
65STATISTIC(ObjectBytes, "Number of emitted object file bytes");
66STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");
67STATISTIC(RelaxedInstructions, "Number of relaxed instructions");
68
69}
70}
71
72
73
74
75
76
77
78
80 std::unique_ptr Backend,
81 std::unique_ptr Emitter,
82 std::unique_ptr Writer)
83 : Context(Context), Backend(std::move(Backend)),
84 Emitter(std::move(Emitter)), Writer(std::move(Writer)) {
85 if (this->Backend)
86 this->Backend->setAssembler(this);
87 if (this->Writer)
88 this->Writer->setAssembler(this);
89}
90
92 HasLayout = false;
93 HasFinalLayout = false;
94 RelaxAll = false;
95 Sections.clear();
96 Symbols.clear();
97 ThumbFuncs.clear();
98
99
104 if (Writer)
105 Writer->reset();
106}
107
109 if (Section.isRegistered())
110 return false;
111 Sections.push_back(&Section);
112 Section.setIsRegistered(true);
113 return true;
114}
115
117 if (ThumbFuncs.count(Symbol))
118 return true;
119
120 if (!Symbol->isVariable())
121 return false;
122
123 const MCExpr *Expr = Symbol->getVariableValue();
124
127 return false;
128
129 if (V.getSubSym() || V.getSpecifier())
130 return false;
131
133 if (!Sym || V.getSpecifier())
134 return false;
135
137 return false;
138
139 ThumbFuncs.insert(Symbol);
140 return true;
141}
142
146 if (RecordReloc)
147 ++stats::Fixups;
148
149
150
151
152
153
154
158 reportError(Fixup.getLoc(), "expected relocatable expression");
159 return true;
160 }
161
162 bool IsResolved = false;
164 IsResolved = *State;
165 } else {
169 if (Add && Add->isDefined())
171 if (Sub && Sub->isDefined())
173
174 if (Fixup.isPCRel()) {
176 if (Add && &&
->isUndefined() &&
->isAbsolute()) {
179 }
180 } else {
181 IsResolved = Target.isAbsolute();
182 }
183 }
184
185 if (!RecordReloc)
186 return IsResolved;
187
189 IsResolved = false;
191 return true;
192}
193
196 switch (F.getKind()) {
206 return F.getSize();
209 int64_t NumValues = 0;
210 if (!FF.getNumValues().evaluateKnownAbsolute(NumValues, *this)) {
211 recordError(FF.getLoc(), "expected assembly-time absolute expression");
212 return 0;
213 }
214 int64_t Size = NumValues * FF.getValueSize();
215 if (Size < 0) {
216 recordError(FF.getLoc(), "invalid number of bytes");
217 return 0;
218 }
220 }
221
224
227
229 return 4;
230
234 if (!OF.getOffset().evaluateAsValue(Value, *this)) {
235 recordError(OF.getLoc(), "expected assembly-time absolute expression");
236 return 0;
237 }
238
240 int64_t TargetLocation = Value.getConstant();
241 if (const auto *SA = Value.getAddSym()) {
244 recordError(OF.getLoc(), "expected absolute expression");
245 return 0;
246 }
247 TargetLocation += Val;
248 }
249 int64_t Size = TargetLocation - FragmentOffset;
251 recordError(OF.getLoc(), "invalid .org offset '" + Twine(TargetLocation) +
252 "' (at offset '" + Twine(FragmentOffset) +
253 "')");
254 return 0;
255 }
257 }
258 }
259
261}
262
263
265 bool ReportError, uint64_t &Val) {
267 if (ReportError)
269 "'");
270 return false;
271 }
273 return true;
274}
275
277 bool ReportError, uint64_t &Val) {
280
281
285 "'");
286
288
290 if (A) {
292
293
294
295
297 return false;
299 }
300
302 if (B) {
305 return false;
307 }
308
310 return true;
311}
312
316
322
325 if (!Symbol.isVariable())
326 return &Symbol;
327
328 const MCExpr *Expr = Symbol.getVariableValue();
331 reportError(Expr->getLoc(), "expression could not be evaluated");
332 return nullptr;
333 }
334
336 if (SymB) {
339 "' could not be evaluated in a subtraction expression");
340 return nullptr;
341 }
342
344 if ()
345 return nullptr;
346
350 "' cannot be used in assignment expr");
351 return nullptr;
352 }
353
354 return &ASym;
355}
356
362
369
371 bool Changed = !Symbol.isRegistered();
373 Symbol.setIsRegistered(true);
374 Symbols.push_back(&Symbol);
375 }
377}
378
380 relocDirectives.push_back(RD);
381}
382
383
386
387 uint64_t FragmentSize = Asm.computeFragmentSize(F);
388
390
391
392
394 (void) Start;
395
396 ++stats::EmittedFragments;
397
398 switch (F.getKind()) {
408 ++stats::EmittedDataFragments;
410 ++stats::EmittedRelaxableFragments;
412 OS << StringRef(EF.getContents().data(), EF.getContents().size());
413 OS << StringRef(EF.getVarContents().data(), EF.getVarContents().size());
414 } break;
415
417 ++stats::EmittedAlignFragments;
418 OS << StringRef(F.getContents().data(), F.getContents().size());
419 assert(F.getAlignFillLen() &&
420 "Invalid virtual align in concrete fragment!");
421
422 uint64_t Count = (FragmentSize - F.getFixedSize()) / F.getAlignFillLen();
423 assert((FragmentSize - F.getFixedSize()) % F.getAlignFillLen() == 0 &&
424 "computeFragmentSize computed size is incorrect");
425
426
427 if (F.hasAlignEmitNops()) {
428 if (!Asm.getBackend().writeNopData(OS, Count, F.getSubtargetInfo()))
431 } else {
432
434 switch (F.getAlignFillLen()) {
435 default:
437 case 1:
438 OS << char(F.getAlignFill());
439 break;
440 case 2:
442 break;
443 case 4:
445 break;
446 case 8:
448 break;
449 }
450 }
451 }
452 } break;
453
455 ++stats::EmittedFillFragments;
459 const unsigned MaxChunkSize = 16;
460 char Data[MaxChunkSize];
461 assert(0 < VSize && VSize <= MaxChunkSize && "Illegal fragment fill size");
462
463
464 for (unsigned I = 0; I != VSize; ++I) {
467 }
468 for (unsigned I = VSize; I < MaxChunkSize; ++I)
470
471
472 const unsigned NumPerChunk = MaxChunkSize / VSize;
473
474 const unsigned ChunkSize = VSize * NumPerChunk;
475
476
478 for (uint64_t I = 0, E = FragmentSize / ChunkSize; I != E; ++I)
479 OS << Ref;
480
481
482 unsigned TrailingCount = FragmentSize % ChunkSize;
483 if (TrailingCount)
485 break;
486 }
487
489 ++stats::EmittedNopsFragments;
491
494 int64_t MaximumNopLength =
496
497 assert(NumBytes > 0 && "Expected positive NOPs fragment size");
498 assert(ControlledNopLength >= 0 && "Expected non-negative NOP size");
499
500 if (ControlledNopLength > MaximumNopLength) {
501 Asm.reportError(NF.getLoc(), "illegal NOP size " +
502 std::to_string(ControlledNopLength) +
503 ". (expected within [0, " +
504 std::to_string(MaximumNopLength) + "])");
505
506
507 ControlledNopLength = MaximumNopLength;
508 }
509
510
511 if (!ControlledNopLength)
512 ControlledNopLength = MaximumNopLength;
513
514 while (NumBytes) {
516 (uint64_t)std::min(NumBytes, ControlledNopLength);
517 assert(NumBytesToEmit && "try to emit empty NOP instruction");
518 if (!Asm.getBackend().writeNopData(OS, NumBytesToEmit,
520 report_fatal_error("unable to write nop sequence of the remaining " +
521 Twine(NumBytesToEmit) + " bytes");
522 break;
523 }
524 NumBytes -= NumBytesToEmit;
525 }
526 break;
527 }
528
531 if (!Asm.getBackend().writeNopData(OS, FragmentSize, BF.getSubtargetInfo()))
533 Twine(FragmentSize) + " bytes");
534 break;
535 }
536
540 break;
541 }
542
544 ++stats::EmittedOrgFragments;
546
547 for (uint64_t i = 0, e = FragmentSize; i != e; ++i)
548 OS << char(OF.getValue());
549
550 break;
551 }
552
553 }
554
555 assert(OS.tell() - Start == FragmentSize &&
556 "The stream should advance by fragment size");
557}
558
562
565
566
567
568
569 auto Fn = [](char c) { return c != 0; };
571 bool HasNonZero = false;
572 switch (F.getKind()) {
573 default:
575 "' contains invalid fragment");
576 break;
579 HasNonZero =
580 any_of(F.getContents(), Fn) || any_of(F.getVarContents(), Fn);
581 break;
583
584
585 assert(F.getAlignFill() == 0 && "Invalid align in virtual section!");
586 break;
589 break;
592 break;
593 }
594 if (HasNonZero) {
596 "' cannot have non-zero bytes");
597 break;
598 }
599 if (F.getFixups().size() || F.getVarFixups().size()) {
601 "BSS section '" + Sec->getName() + "' cannot have fixups");
602 break;
603 }
604 }
605
606 return;
607 }
608
610 (void)Start;
611
614
618}
619
623 errs() << "assembler backend - pre-layout\n--\n";
625 });
626
627
628 unsigned SectionIndex = 0;
631
632
633 if (Sec.Subsections.size() > 1) {
636 for (auto &[_, List] : Sec.Subsections) {
640 }
641 Sec.Subsections.clear();
642 Sec.Subsections.push_back({0u, {Dummy.getNext(), Tail}});
643 Sec.CurFragList = &Sec.Subsections[0].second;
644
645 unsigned FragmentIndex = 0;
647 Frag.setLayoutOrder(FragmentIndex++);
648 }
649 }
650
651
652 this->HasLayout = true;
654 layoutSection(Sec);
655 unsigned FirstStable = Sections.size();
656 while ((FirstStable = relaxOnce(FirstStable)) > 0)
658 return;
659
660
661
664 layoutSection(Sec);
665
667
669 errs() << "assembler backend - final-layout\n--\n";
671
672
673
675
676
677
678 this->HasFinalLayout = true;
679
680
681 for (auto &PF : relocDirectives) {
683 auto &O = PF.Offset;
684 if (!O.evaluateAsValue(Res, *this)) {
686 continue;
687 }
689 auto *F = Sym ? Sym->getFragment() : nullptr;
690 auto *Sec = F ? F->getParent() : nullptr;
693 ".reloc offset is not relative to a section");
694 continue;
695 }
696
699 }
700
701
704
705 auto Contents = F.getContents();
710 Fixup.getOffset() <= F.getFixedSize());
712 reinterpret_cast<uint8_t *>(Contents.data() + Fixup.getOffset());
714 true, Data);
715 }
716
717
722 (Fixup.getOffset() >= F.getFixedSize() &&
723 Fixup.getOffset() <= F.getSize()));
724 auto *Data = reinterpret_cast<uint8_t *>(
725 F.getVarContents().data() + (Fixup.getOffset() - F.getFixedSize()));
727 true, Data);
728 }
729 }
730 }
731}
732
735
736
738
739 HasLayout = false;
740 assert(PendingErrors.empty());
741}
742
743bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F,
745 ++stats::FixupEvalForRelax;
749 false, {});
751 Resolved);
752}
753
754void MCAssembler::relaxInstruction(MCFragment &F) {
756 "Expected CodeEmitter defined for relaxInstruction");
757
758
759
760 if (().mayNeedRelaxation(F.getOpcode(), F.getOperands(),
761 *F.getSubtargetInfo()))
762 return;
763
764 bool DoRelax = false;
765 for (const MCFixup &Fixup : F.getVarFixups())
766 if ((DoRelax = fixupNeedsRelaxation(F, Fixup)))
767 break;
768 if (!DoRelax)
769 return;
770
771 ++stats::RelaxedInstructions;
772
773
774
775 MCInst Relaxed = F.getInst();
777
778
779 F.setInst(Relaxed);
784 F.setVarFixups(Fixups);
785}
786
787void MCAssembler::relaxLEB(MCFragment &F) {
788 unsigned PadTo = F.getVarSize();
790 F.clearVarFixups();
791
792
793
795 ? F.getLEBValue().evaluateKnownAbsolute(Value, *this)
796 : F.getLEBValue().evaluateAsAbsolute(Value, *this);
797 if (!Abs) {
798 bool Relaxed, UseZeroPad;
800 if (!Relaxed) {
802 Twine(F.isLEBSigned() ? ".s" : ".u") +
803 "leb128 expression is not absolute");
805 }
806 uint8_t Tmp[10];
808 if (UseZeroPad)
810 }
811 uint8_t Data[16];
812 size_t Size = 0;
813
814
815
816
817 if (F.isLEBSigned())
819 else
821 F.setVarContents({reinterpret_cast<char *>(Data), Size});
822}
823
824
825
826
827
828
829
831 Align BoundaryAlignment) {
833 return (StartAddr >> Log2(BoundaryAlignment)) !=
834 ((EndAddr - 1) >> Log2(BoundaryAlignment));
835}
836
837
838
839
840
841
842
844 Align BoundaryAlignment) {
846 return (EndAddr & (BoundaryAlignment.value() - 1)) == 0;
847}
848
849
850
851
852
853
854
856 Align BoundaryAlignment) {
859}
860
862
863
865 return;
866
868 uint64_t AlignedSize = 0;
872 break;
873 }
874
876 uint64_t NewSize = needPadding(AlignedOffset, AlignedSize, BoundaryAlignment)
878 : 0U;
879 if (NewSize == BF.getSize())
880 return;
882}
883
884void MCAssembler::relaxDwarfLineAddr(MCFragment &F) {
886 return;
887
889 int64_t AddrDelta;
890 bool Abs = F.getDwarfAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);
891 assert(Abs && "We created a line delta with an invalid expression");
892 (void)Abs;
893 SmallVector<char, 8> Data;
895 F.getDwarfLineDelta(), AddrDelta, Data);
897 F.clearVarFixups();
898}
899
900void MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) {
902 return;
903
906 bool Abs = F.getDwarfAddrDelta().evaluateAsAbsolute(Value, *this);
907 if (!Abs) {
909 "invalid CFI advance_loc expression");
911 return;
912 }
913
914 SmallVector<char, 8> Data;
917 F.clearVarFixups();
918}
919
920void MCAssembler::relaxSFrameFragment(MCFragment &F) {
924 bool Abs = F.getSFrameAddrDelta().evaluateAsAbsolute(Value, *this);
925 if (!Abs) {
926 C.reportError(F.getSFrameAddrDelta().getLoc(),
927 "invalid CFI advance_loc expression in sframe");
929 return;
930 }
931
935 F.clearVarFixups();
936}
937
938bool MCAssembler::relaxFragment(MCFragment &F) {
940 switch (F.getKind()) {
941 default:
942 return false;
944 assert(() && "Did not expect a FT_Relaxable in RelaxAll mode");
945 relaxInstruction(F);
946 break;
948 relaxLEB(F);
949 break;
951 relaxDwarfLineAddr(F);
952 break;
954 relaxDwarfCallFrameFragment(F);
955 break;
957 relaxSFrameFragment(F);
958 break;
960 relaxBoundaryAlign(static_cast<MCBoundaryAlignFragment &>(F));
961 break;
964 *this, static_cast<MCCVInlineLineTableFragment &>(F));
965 break;
968 *this, static_cast<MCCVDefRangeFragment &>(F));
969 break;
972 return F.getNext()->Offset - F.Offset != Size;
973 }
975}
976
977void MCAssembler::layoutSection(MCSection &Sec) {
979 for (MCFragment &F : Sec) {
982 Offset += F.getFixedSize();
984
985
986 bool AlignFixup = false;
987 if (F.hasAlignEmitNops()) {
989
990
991 if (!AlignFixup)
993 Size += F.getAlignment().value();
994 }
995 if (!AlignFixup && Size > F.getAlignMaxBytesToEmit())
997
998
999 F.VarContentStart = F.getFixedSize();
1000 F.VarContentEnd = F.VarContentStart + Size;
1001 if (F.VarContentEnd > F.getParent()->ContentStorage.size())
1002 F.getParent()->ContentStorage.resize(F.VarContentEnd);
1004 } else {
1006 }
1007 }
1008}
1009
1010unsigned MCAssembler::relaxOnce(unsigned FirstStable) {
1011 ++stats::RelaxationSteps;
1012 PendingErrors.clear();
1013
1014 unsigned Res = 0;
1015 for (unsigned I = 0; I != FirstStable; ++I) {
1016
1017
1018 auto &Sec = *Sections[I];
1019 auto MaxIter = Sec.curFragList()->Tail->getLayoutOrder() + 1;
1020 for (;;) {
1022 for (MCFragment &F : Sec)
1025
1027 break;
1028
1029
1030 FirstStable = Sections.size();
1031 Res = I;
1032 if (--MaxIter == 0)
1033 break;
1034 layoutSection(Sec);
1035 }
1036 }
1037
1038
1039 return Res;
1040}
1041
1045
1047 PendingErrors.emplace_back(Loc, Msg.str());
1048}
1049
1051 for (auto &Err : PendingErrors)
1053 PendingErrors.clear();
1054}
1055
1056#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1060
1061
1062
1064 if (!Sym.isVariable())
1065 if (auto *F = Sym.getFragment())
1066 FragToSyms.try_emplace(F).first->second.push_back(&Sym);
1067
1068 OS << "Sections:[";
1069 for (const MCSection &Sec : *this) {
1070 OS << '\n';
1071 Sec.dump(&FragToSyms);
1072 }
1073 OS << "\n]\n";
1074}
1075#endif
1076
1079 return E->getLoc();
1080 return {};
1081}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static bool getSymbolOffsetImpl(const MCAssembler &Asm, const MCSymbol &S, bool ReportError, uint64_t &Val)
Definition MCAssembler.cpp:276
static bool needPadding(uint64_t StartAddr, uint64_t Size, Align BoundaryAlignment)
Check if the branch needs padding.
Definition MCAssembler.cpp:855
static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, const MCFragment &F)
Write the fragment F to the output file.
Definition MCAssembler.cpp:384
static bool mayCrossBoundary(uint64_t StartAddr, uint64_t Size, Align BoundaryAlignment)
Check if the branch crosses the boundary.
Definition MCAssembler.cpp:830
static bool isAgainstBoundary(uint64_t StartAddr, uint64_t Size, Align BoundaryAlignment)
Check if the branch is against the boundary.
Definition MCAssembler.cpp:843
static bool getLabelOffset(const MCAssembler &Asm, const MCSymbol &S, bool ReportError, uint64_t &Val)
Definition MCAssembler.cpp:264
PowerPC TLS Dynamic Call Fixup
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
#define DEBUG_WITH_TYPE(TYPE,...)
DEBUG_WITH_TYPE macro - This macro should be used by passes to emit debug information.
void encodeInlineLineTable(const MCAssembler &Asm, MCCVInlineLineTableFragment &F)
Encodes the binary annotations once we have a layout.
void encodeDefRange(const MCAssembler &Asm, MCCVDefRangeFragment &F)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
virtual void relaxInstruction(MCInst &Inst, const MCSubtargetInfo &STI) const
Relax the instruction in the given fragment to the next wider instruction.
virtual bool relaxAlign(MCFragment &F, unsigned &Size)
virtual std::pair< bool, bool > relaxLEB128(MCFragment &, int64_t &Value) const
virtual bool fixupNeedsRelaxationAdvanced(const MCFragment &, const MCFixup &, const MCValue &, uint64_t, bool Resolved) const
Target specific predicate for whether a given fixup requires the associated instruction to be relaxed...
virtual void reset()
lifetime management
virtual void applyFixup(const MCFragment &, const MCFixup &, const MCValue &Target, uint8_t *Data, uint64_t Value, bool IsResolved)=0
MCContext & getContext() const
LLVM_ABI bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const
Definition MCAssembler.cpp:313
LLVM_ABI uint64_t getSectionAddressSize(const MCSection &Sec) const
Definition MCAssembler.cpp:357
LLVM_ABI void Finish()
Finish - Do final processing and write the object to the output stream.
Definition MCAssembler.cpp:733
LLVM_ABI void reportError(SMLoc L, const Twine &Msg) const
Definition MCAssembler.cpp:1042
LLVM_ABI void writeSectionData(raw_ostream &OS, const MCSection *Section) const
Emit the section contents to OS.
Definition MCAssembler.cpp:559
iterator_range< pointee_iterator< SmallVector< const MCSymbol *, 0 >::const_iterator > > symbols() const
LLVM_ABI void dump() const
Definition MCAssembler.cpp:1057
LLVM_ABI void layout()
Definition MCAssembler.cpp:620
MCObjectWriter & getWriter() const
MCCodeEmitter * getEmitterPtr() const
LLVM_ABI void addRelocDirective(RelocDirective RD)
Definition MCAssembler.cpp:379
MCCodeEmitter & getEmitter() const
LLVM_ABI void recordError(SMLoc L, const Twine &Msg) const
Definition MCAssembler.cpp:1046
LLVM_ABI MCAssembler(MCContext &Context, std::unique_ptr< MCAsmBackend > Backend, std::unique_ptr< MCCodeEmitter > Emitter, std::unique_ptr< MCObjectWriter > Writer)
Construct a new assembler instance.
Definition MCAssembler.cpp:79
LLVM_ABI bool isThumbFunc(const MCSymbol *Func) const
Check whether a given symbol has been flagged with .thumb_func.
Definition MCAssembler.cpp:116
MCAsmBackend & getBackend() const
LLVM_ABI bool registerSection(MCSection &Section)
Definition MCAssembler.cpp:108
LLVM_ABI void flushPendingErrors() const
Definition MCAssembler.cpp:1050
LLVM_ABI uint64_t computeFragmentSize(const MCFragment &F) const
Compute the effective fragment size.
Definition MCAssembler.cpp:194
LLVM_ABI const MCSymbol * getBaseSymbol(const MCSymbol &Symbol) const
Definition MCAssembler.cpp:323
MCAsmBackend * getBackendPtr() const
LLVM_ABI uint64_t getSectionFileSize(const MCSection &Sec) const
Definition MCAssembler.cpp:363
LLVM_ABI void reset()
Reuse an assembler instance.
Definition MCAssembler.cpp:91
LLVM_ABI bool registerSymbol(const MCSymbol &Symbol)
Definition MCAssembler.cpp:370
uint64_t getFragmentOffset(const MCFragment &F) const
MCDwarfLineTableParams getDWARFLinetableParams() const
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
Align getAlignment() const
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
virtual void reset()
Lifetime management.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Context object for machine code objects.
LLVM_ABI CodeViewContext & getCVContext()
LLVM_ABI void reportError(SMLoc L, const Twine &Msg)
static LLVM_ABI void encodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
static LLVM_ABI void encode(MCContext &Context, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ABI bool evaluateAsValue(MCValue &Res, const MCAssembler &Asm) const
Try to evaluate the expression to the form (a - b + constant) where neither a nor b are variables.
LLVM_ABI bool evaluateAsRelocatable(MCValue &Res, const MCAssembler *Asm) const
Try to evaluate the expression to a relocatable value, i.e.
uint8_t getValueSize() const
uint64_t getValue() const
Encode information on a single operation to perform on a byte sequence (e.g., an encoded instruction)...
const MCExpr * getValue() const
LLVM_ABI SMLoc getLoc() const
Definition MCAssembler.cpp:1077
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
MCFragment * getNext() const
const MCSubtargetInfo * getSubtargetInfo() const
Retrieve the MCSubTargetInfo in effect when the instruction was encoded.
int64_t getControlledNopLength() const
int64_t getNumBytes() const
virtual bool isSymbolRefDifferenceFullyResolvedImpl(const MCSymbol &SymA, const MCFragment &FB, bool InSet, bool IsPCRel) const
bool getSubsectionsViaSymbols() const
virtual void executePostLayoutBinding()
Perform any late binding of symbols (for example, to assign symbol indices for use when generating re...
virtual uint64_t writeObject()=0
Write the object file and returns the number of bytes written.
static void encodeFuncOffset(MCContext &C, uint64_t Offset, SmallVectorImpl< char > &Out, MCFragment *FDEFrag)
Instances of this class represent a uniqued identifier for a section in the current translation unit.
bool isBssSection() const
Check whether this section is "virtual", that is has no actual object file contents.
void dump(DenseMap< const MCFragment *, SmallVector< const MCSymbol *, 0 > > *FragToSyms=nullptr) const
void setOrdinal(unsigned Value)
FragList * curFragList() const
Generic base class for all target subtargets.
Represents a symbol table index fragment.
const MCSymbol * getSymbol()
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
bool isCommon() const
Is this a 'common' symbol.
StringRef getName() const
getName - Get the symbol name.
bool isVariable() const
isVariable - Check if this is a variable symbol.
uint32_t getIndex() const
Get the (implementation defined) index.
const MCExpr * getVariableValue() const
Get the expression of the variable symbol.
MCFragment * getFragment() const
uint64_t getOffset() const
const MCSymbol * getAddSym() const
int64_t getConstant() const
const MCSymbol * getSubSym() const
Represents a location in source code.
StringRef - Represent a constant reference to a string, i.e.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
LLVM Value Representation.
This class implements an extremely fast bulk output stream that can only output to a stream.
uint64_t tell() const
tell - Return the current offset with the file.
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.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ C
The default llvm calling convention, compatible with C.
bool isRelocRelocation(MCFixupKind FixupKind)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
uint64_t offsetToAlignment(uint64_t Value, Align Alignment)
Returns the offset to the next integer (mod 2**64) that is greater than or equal to Value and is a mu...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
@ Sub
Subtraction of integers.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
unsigned Log2(Align A)
Returns the log2 of the alignment.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.