[ARM] MVE integer min and max
[llvm-complete.git] / lib / MC / MCStreamer.cpp
blobdecbb96817e3ac96b0f2e5ca0e3911181033da0b
1 //===- lib/MC/MCStreamer.cpp - Streaming Machine Code Output --------------===//
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 //===----------------------------------------------------------------------===//
9 #include "llvm/MC/MCStreamer.h"
10 #include "llvm/ADT/Optional.h"
11 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/ADT/Twine.h"
14 #include "llvm/BinaryFormat/COFF.h"
15 #include "llvm/MC/MCAsmBackend.h"
16 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCCodeView.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCDwarf.h"
20 #include "llvm/MC/MCExpr.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstPrinter.h"
23 #include "llvm/MC/MCObjectFileInfo.h"
24 #include "llvm/MC/MCSection.h"
25 #include "llvm/MC/MCSectionCOFF.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCWin64EH.h"
28 #include "llvm/MC/MCWinEH.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/ErrorHandling.h"
31 #include "llvm/Support/LEB128.h"
32 #include "llvm/Support/MathExtras.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include <cassert>
35 #include <cstdint>
36 #include <cstdlib>
37 #include <utility>
39 using namespace llvm;
41 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
42 S.setTargetStreamer(this);
45 // Pin the vtables to this file.
46 MCTargetStreamer::~MCTargetStreamer() = default;
48 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
50 void MCTargetStreamer::finish() {}
52 void MCTargetStreamer::changeSection(const MCSection *CurSection,
53 MCSection *Section,
54 const MCExpr *Subsection,
55 raw_ostream &OS) {
56 Section->PrintSwitchToSection(
57 *Streamer.getContext().getAsmInfo(),
58 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
59 Subsection);
62 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
63 Streamer.EmitRawText(Directive);
66 void MCTargetStreamer::emitValue(const MCExpr *Value) {
67 SmallString<128> Str;
68 raw_svector_ostream OS(Str);
70 Value->print(OS, Streamer.getContext().getAsmInfo());
71 Streamer.EmitRawText(OS.str());
74 void MCTargetStreamer::emitRawBytes(StringRef Data) {
75 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
76 const char *Directive = MAI->getData8bitsDirective();
77 for (const unsigned char C : Data.bytes()) {
78 SmallString<128> Str;
79 raw_svector_ostream OS(Str);
81 OS << Directive << (unsigned)C;
82 Streamer.EmitRawText(OS.str());
86 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
88 MCStreamer::MCStreamer(MCContext &Ctx)
89 : Context(Ctx), CurrentWinFrameInfo(nullptr),
90 UseAssemblerInfoForParsing(false) {
91 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
94 MCStreamer::~MCStreamer() {}
96 void MCStreamer::reset() {
97 DwarfFrameInfos.clear();
98 CurrentWinFrameInfo = nullptr;
99 WinFrameInfos.clear();
100 SymbolOrdering.clear();
101 SectionStack.clear();
102 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
105 raw_ostream &MCStreamer::GetCommentOS() {
106 // By default, discard comments.
107 return nulls();
110 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
111 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
112 return DwarfFrameInfos;
115 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
117 void MCStreamer::addExplicitComment(const Twine &T) {}
118 void MCStreamer::emitExplicitComments() {}
120 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
121 for (auto &FI : DwarfFrameInfos)
122 FI.CompactUnwindEncoding =
123 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
126 /// EmitIntValue - Special case of EmitValue that avoids the client having to
127 /// pass in a MCExpr for constant integers.
128 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
129 assert(1 <= Size && Size <= 8 && "Invalid size");
130 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
131 "Invalid size");
132 char buf[8];
133 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
134 for (unsigned i = 0; i != Size; ++i) {
135 unsigned index = isLittleEndian ? i : (Size - i - 1);
136 buf[i] = uint8_t(Value >> (index * 8));
138 EmitBytes(StringRef(buf, Size));
141 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
142 /// client having to pass in a MCExpr for constant integers.
143 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned PadTo) {
144 SmallString<128> Tmp;
145 raw_svector_ostream OSE(Tmp);
146 encodeULEB128(Value, OSE, PadTo);
147 EmitBytes(OSE.str());
150 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
151 /// client having to pass in a MCExpr for constant integers.
152 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
153 SmallString<128> Tmp;
154 raw_svector_ostream OSE(Tmp);
155 encodeSLEB128(Value, OSE);
156 EmitBytes(OSE.str());
159 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
160 EmitValueImpl(Value, Size, Loc);
163 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
164 bool IsSectionRelative) {
165 assert((!IsSectionRelative || Size == 4) &&
166 "SectionRelative value requires 4-bytes");
168 if (!IsSectionRelative)
169 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
170 else
171 EmitCOFFSecRel32(Sym, /*Offset=*/0);
174 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
175 report_fatal_error("unsupported directive in streamer");
178 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
179 report_fatal_error("unsupported directive in streamer");
182 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
183 report_fatal_error("unsupported directive in streamer");
186 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
187 report_fatal_error("unsupported directive in streamer");
190 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
191 report_fatal_error("unsupported directive in streamer");
194 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
195 report_fatal_error("unsupported directive in streamer");
198 /// Emit NumBytes bytes worth of the value specified by FillValue.
199 /// This implements directives such as '.space'.
200 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
201 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
204 /// The implementation in this class just redirects to emitFill.
205 void MCStreamer::EmitZeros(uint64_t NumBytes) {
206 emitFill(NumBytes, 0);
209 Expected<unsigned>
210 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
211 StringRef Filename,
212 Optional<MD5::MD5Result> Checksum,
213 Optional<StringRef> Source,
214 unsigned CUID) {
215 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
216 Source, CUID);
219 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
220 StringRef Filename,
221 Optional<MD5::MD5Result> Checksum,
222 Optional<StringRef> Source,
223 unsigned CUID) {
224 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
225 Source);
228 void MCStreamer::EmitCFIBKeyFrame() {
229 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
230 if (!CurFrame)
231 return;
232 CurFrame->IsBKeyFrame = true;
235 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
236 unsigned Column, unsigned Flags,
237 unsigned Isa,
238 unsigned Discriminator,
239 StringRef FileName) {
240 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
241 Discriminator);
244 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
245 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
246 if (!Table.getLabel()) {
247 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
248 Table.setLabel(
249 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
251 return Table.getLabel();
254 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
255 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
258 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
259 if (!hasUnfinishedDwarfFrameInfo()) {
260 getContext().reportError(SMLoc(), "this directive must appear between "
261 ".cfi_startproc and .cfi_endproc "
262 "directives");
263 return nullptr;
265 return &DwarfFrameInfos.back();
268 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
269 ArrayRef<uint8_t> Checksum,
270 unsigned ChecksumKind) {
271 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
272 ChecksumKind);
275 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
276 return getContext().getCVContext().recordFunctionId(FunctionId);
279 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
280 unsigned IAFunc, unsigned IAFile,
281 unsigned IALine, unsigned IACol,
282 SMLoc Loc) {
283 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
284 getContext().reportError(Loc, "parent function id not introduced by "
285 ".cv_func_id or .cv_inline_site_id");
286 return true;
289 return getContext().getCVContext().recordInlinedCallSiteId(
290 FunctionId, IAFunc, IAFile, IALine, IACol);
293 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
294 unsigned Line, unsigned Column,
295 bool PrologueEnd, bool IsStmt,
296 StringRef FileName, SMLoc Loc) {}
298 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
299 SMLoc Loc) {
300 CodeViewContext &CVC = getContext().getCVContext();
301 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
302 if (!FI) {
303 getContext().reportError(
304 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
305 return false;
308 // Track the section
309 if (FI->Section == nullptr)
310 FI->Section = getCurrentSectionOnly();
311 else if (FI->Section != getCurrentSectionOnly()) {
312 getContext().reportError(
313 Loc,
314 "all .cv_loc directives for a function must be in the same section");
315 return false;
317 return true;
320 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
321 const MCSymbol *Begin,
322 const MCSymbol *End) {}
324 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
325 unsigned SourceFileId,
326 unsigned SourceLineNum,
327 const MCSymbol *FnStartSym,
328 const MCSymbol *FnEndSym) {}
330 void MCStreamer::EmitCVDefRangeDirective(
331 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
332 StringRef FixedSizePortion) {}
334 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
335 MCSymbol *EHSymbol) {
338 void MCStreamer::InitSections(bool NoExecStack) {
339 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
342 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
343 assert(Fragment);
344 Symbol->setFragment(Fragment);
346 // As we emit symbols into a section, track the order so that they can
347 // be sorted upon later. Zero is reserved to mean 'unemitted'.
348 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
351 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
352 Symbol->redefineIfPossible();
354 if (!Symbol->isUndefined() || Symbol->isVariable())
355 return getContext().reportError(Loc, "invalid symbol redefinition");
357 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
358 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
359 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
360 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
362 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
364 MCTargetStreamer *TS = getTargetStreamer();
365 if (TS)
366 TS->emitLabel(Symbol);
369 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
370 assert(EH || Debug);
373 void MCStreamer::EmitCFIStartProc(bool IsSimple, SMLoc Loc) {
374 if (hasUnfinishedDwarfFrameInfo())
375 return getContext().reportError(
376 Loc, "starting new .cfi frame before finishing the previous one");
378 MCDwarfFrameInfo Frame;
379 Frame.IsSimple = IsSimple;
380 EmitCFIStartProcImpl(Frame);
382 const MCAsmInfo* MAI = Context.getAsmInfo();
383 if (MAI) {
384 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
385 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
386 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
387 Frame.CurrentCfaRegister = Inst.getRegister();
392 DwarfFrameInfos.push_back(Frame);
395 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
398 void MCStreamer::EmitCFIEndProc() {
399 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
400 if (!CurFrame)
401 return;
402 EmitCFIEndProcImpl(*CurFrame);
405 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
406 // Put a dummy non-null value in Frame.End to mark that this frame has been
407 // closed.
408 Frame.End = (MCSymbol *)1;
411 MCSymbol *MCStreamer::EmitCFILabel() {
412 // Return a dummy non-null value so that label fields appear filled in when
413 // generating textual assembly.
414 return (MCSymbol *)1;
417 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
418 MCSymbol *Label = EmitCFILabel();
419 MCCFIInstruction Instruction =
420 MCCFIInstruction::createDefCfa(Label, Register, Offset);
421 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
422 if (!CurFrame)
423 return;
424 CurFrame->Instructions.push_back(Instruction);
425 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
428 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
429 MCSymbol *Label = EmitCFILabel();
430 MCCFIInstruction Instruction =
431 MCCFIInstruction::createDefCfaOffset(Label, Offset);
432 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
433 if (!CurFrame)
434 return;
435 CurFrame->Instructions.push_back(Instruction);
438 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
439 MCSymbol *Label = EmitCFILabel();
440 MCCFIInstruction Instruction =
441 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
442 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
443 if (!CurFrame)
444 return;
445 CurFrame->Instructions.push_back(Instruction);
448 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
449 MCSymbol *Label = EmitCFILabel();
450 MCCFIInstruction Instruction =
451 MCCFIInstruction::createDefCfaRegister(Label, Register);
452 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
453 if (!CurFrame)
454 return;
455 CurFrame->Instructions.push_back(Instruction);
456 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
459 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
460 MCSymbol *Label = EmitCFILabel();
461 MCCFIInstruction Instruction =
462 MCCFIInstruction::createOffset(Label, Register, Offset);
463 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
464 if (!CurFrame)
465 return;
466 CurFrame->Instructions.push_back(Instruction);
469 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
470 MCSymbol *Label = EmitCFILabel();
471 MCCFIInstruction Instruction =
472 MCCFIInstruction::createRelOffset(Label, Register, Offset);
473 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
474 if (!CurFrame)
475 return;
476 CurFrame->Instructions.push_back(Instruction);
479 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
480 unsigned Encoding) {
481 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
482 if (!CurFrame)
483 return;
484 CurFrame->Personality = Sym;
485 CurFrame->PersonalityEncoding = Encoding;
488 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
489 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
490 if (!CurFrame)
491 return;
492 CurFrame->Lsda = Sym;
493 CurFrame->LsdaEncoding = Encoding;
496 void MCStreamer::EmitCFIRememberState() {
497 MCSymbol *Label = EmitCFILabel();
498 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
499 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
500 if (!CurFrame)
501 return;
502 CurFrame->Instructions.push_back(Instruction);
505 void MCStreamer::EmitCFIRestoreState() {
506 // FIXME: Error if there is no matching cfi_remember_state.
507 MCSymbol *Label = EmitCFILabel();
508 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
509 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
510 if (!CurFrame)
511 return;
512 CurFrame->Instructions.push_back(Instruction);
515 void MCStreamer::EmitCFISameValue(int64_t Register) {
516 MCSymbol *Label = EmitCFILabel();
517 MCCFIInstruction Instruction =
518 MCCFIInstruction::createSameValue(Label, Register);
519 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
520 if (!CurFrame)
521 return;
522 CurFrame->Instructions.push_back(Instruction);
525 void MCStreamer::EmitCFIRestore(int64_t Register) {
526 MCSymbol *Label = EmitCFILabel();
527 MCCFIInstruction Instruction =
528 MCCFIInstruction::createRestore(Label, Register);
529 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
530 if (!CurFrame)
531 return;
532 CurFrame->Instructions.push_back(Instruction);
535 void MCStreamer::EmitCFIEscape(StringRef Values) {
536 MCSymbol *Label = EmitCFILabel();
537 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
538 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
539 if (!CurFrame)
540 return;
541 CurFrame->Instructions.push_back(Instruction);
544 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
545 MCSymbol *Label = EmitCFILabel();
546 MCCFIInstruction Instruction =
547 MCCFIInstruction::createGnuArgsSize(Label, Size);
548 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
549 if (!CurFrame)
550 return;
551 CurFrame->Instructions.push_back(Instruction);
554 void MCStreamer::EmitCFISignalFrame() {
555 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
556 if (!CurFrame)
557 return;
558 CurFrame->IsSignalFrame = true;
561 void MCStreamer::EmitCFIUndefined(int64_t Register) {
562 MCSymbol *Label = EmitCFILabel();
563 MCCFIInstruction Instruction =
564 MCCFIInstruction::createUndefined(Label, Register);
565 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
566 if (!CurFrame)
567 return;
568 CurFrame->Instructions.push_back(Instruction);
571 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
572 MCSymbol *Label = EmitCFILabel();
573 MCCFIInstruction Instruction =
574 MCCFIInstruction::createRegister(Label, Register1, Register2);
575 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
576 if (!CurFrame)
577 return;
578 CurFrame->Instructions.push_back(Instruction);
581 void MCStreamer::EmitCFIWindowSave() {
582 MCSymbol *Label = EmitCFILabel();
583 MCCFIInstruction Instruction =
584 MCCFIInstruction::createWindowSave(Label);
585 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
586 if (!CurFrame)
587 return;
588 CurFrame->Instructions.push_back(Instruction);
591 void MCStreamer::EmitCFINegateRAState() {
592 MCSymbol *Label = EmitCFILabel();
593 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
594 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
595 if (!CurFrame)
596 return;
597 CurFrame->Instructions.push_back(Instruction);
600 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
601 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
602 if (!CurFrame)
603 return;
604 CurFrame->RAReg = Register;
607 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
608 const MCAsmInfo *MAI = Context.getAsmInfo();
609 if (!MAI->usesWindowsCFI()) {
610 getContext().reportError(
611 Loc, ".seh_* directives are not supported on this target");
612 return nullptr;
614 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
615 getContext().reportError(
616 Loc, ".seh_ directive must appear within an active frame");
617 return nullptr;
619 return CurrentWinFrameInfo;
622 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
623 const MCAsmInfo *MAI = Context.getAsmInfo();
624 if (!MAI->usesWindowsCFI())
625 return getContext().reportError(
626 Loc, ".seh_* directives are not supported on this target");
627 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
628 getContext().reportError(
629 Loc, "Starting a function before ending the previous one!");
631 MCSymbol *StartProc = EmitCFILabel();
633 WinFrameInfos.emplace_back(
634 llvm::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
635 CurrentWinFrameInfo = WinFrameInfos.back().get();
636 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
639 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
640 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
641 if (!CurFrame)
642 return;
643 if (CurFrame->ChainedParent)
644 getContext().reportError(Loc, "Not all chained regions terminated!");
646 MCSymbol *Label = EmitCFILabel();
647 CurFrame->End = Label;
650 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
651 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
652 if (!CurFrame)
653 return;
654 if (CurFrame->ChainedParent)
655 getContext().reportError(Loc, "Not all chained regions terminated!");
657 MCSymbol *Label = EmitCFILabel();
658 CurFrame->FuncletOrFuncEnd = Label;
661 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
662 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
663 if (!CurFrame)
664 return;
666 MCSymbol *StartProc = EmitCFILabel();
668 WinFrameInfos.emplace_back(llvm::make_unique<WinEH::FrameInfo>(
669 CurFrame->Function, StartProc, CurFrame));
670 CurrentWinFrameInfo = WinFrameInfos.back().get();
671 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
674 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
675 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
676 if (!CurFrame)
677 return;
678 if (!CurFrame->ChainedParent)
679 return getContext().reportError(
680 Loc, "End of a chained region outside a chained region!");
682 MCSymbol *Label = EmitCFILabel();
684 CurFrame->End = Label;
685 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
688 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
689 SMLoc Loc) {
690 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
691 if (!CurFrame)
692 return;
693 if (CurFrame->ChainedParent)
694 return getContext().reportError(
695 Loc, "Chained unwind areas can't have handlers!");
696 CurFrame->ExceptionHandler = Sym;
697 if (!Except && !Unwind)
698 getContext().reportError(Loc, "Don't know what kind of handler this is!");
699 if (Unwind)
700 CurFrame->HandlesUnwind = true;
701 if (Except)
702 CurFrame->HandlesExceptions = true;
705 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
706 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
707 if (!CurFrame)
708 return;
709 if (CurFrame->ChainedParent)
710 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
713 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
714 const MCSymbolRefExpr *To, uint64_t Count) {
717 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
718 MCSection *MainCFISec,
719 const MCSection *TextSec) {
720 // If this is the main .text section, use the main unwind info section.
721 if (TextSec == Context.getObjectFileInfo()->getTextSection())
722 return MainCFISec;
724 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
725 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
726 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
728 // If this section is COMDAT, this unwind section should be COMDAT associative
729 // with its group.
730 const MCSymbol *KeySym = nullptr;
731 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
732 KeySym = TextSecCOFF->getCOMDATSymbol();
734 // In a GNU environment, we can't use associative comdats. Instead, do what
735 // GCC does, which is to make plain comdat selectany section named like
736 // ".[px]data$_Z3foov".
737 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
738 std::string SectionName =
739 (MainCFISecCOFF->getSectionName() + "$" +
740 TextSecCOFF->getSectionName().split('$').second)
741 .str();
742 return Context.getCOFFSection(
743 SectionName,
744 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
745 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
749 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
752 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
753 return getWinCFISection(getContext(), &NextWinCFIID,
754 getContext().getObjectFileInfo()->getPDataSection(),
755 TextSec);
758 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
759 return getWinCFISection(getContext(), &NextWinCFIID,
760 getContext().getObjectFileInfo()->getXDataSection(),
761 TextSec);
764 void MCStreamer::EmitSyntaxDirective() {}
766 void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
767 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
768 if (!CurFrame)
769 return;
771 MCSymbol *Label = EmitCFILabel();
773 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
774 CurFrame->Instructions.push_back(Inst);
777 void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
778 SMLoc Loc) {
779 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
780 if (!CurFrame)
781 return;
782 if (CurFrame->LastFrameInst >= 0)
783 return getContext().reportError(
784 Loc, "frame register and offset can be set at most once");
785 if (Offset & 0x0F)
786 return getContext().reportError(Loc, "offset is not a multiple of 16");
787 if (Offset > 240)
788 return getContext().reportError(
789 Loc, "frame offset must be less than or equal to 240");
791 MCSymbol *Label = EmitCFILabel();
793 WinEH::Instruction Inst =
794 Win64EH::Instruction::SetFPReg(Label, Register, Offset);
795 CurFrame->LastFrameInst = CurFrame->Instructions.size();
796 CurFrame->Instructions.push_back(Inst);
799 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
800 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
801 if (!CurFrame)
802 return;
803 if (Size == 0)
804 return getContext().reportError(Loc,
805 "stack allocation size must be non-zero");
806 if (Size & 7)
807 return getContext().reportError(
808 Loc, "stack allocation size is not a multiple of 8");
810 MCSymbol *Label = EmitCFILabel();
812 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
813 CurFrame->Instructions.push_back(Inst);
816 void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
817 SMLoc Loc) {
818 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
819 if (!CurFrame)
820 return;
822 if (Offset & 7)
823 return getContext().reportError(
824 Loc, "register save offset is not 8 byte aligned");
826 MCSymbol *Label = EmitCFILabel();
828 WinEH::Instruction Inst =
829 Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
830 CurFrame->Instructions.push_back(Inst);
833 void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
834 SMLoc Loc) {
835 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
836 if (!CurFrame)
837 return;
838 if (Offset & 0x0F)
839 return getContext().reportError(Loc, "offset is not a multiple of 16");
841 MCSymbol *Label = EmitCFILabel();
843 WinEH::Instruction Inst =
844 Win64EH::Instruction::SaveXMM(Label, Register, Offset);
845 CurFrame->Instructions.push_back(Inst);
848 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
849 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
850 if (!CurFrame)
851 return;
852 if (!CurFrame->Instructions.empty())
853 return getContext().reportError(
854 Loc, "If present, PushMachFrame must be the first UOP");
856 MCSymbol *Label = EmitCFILabel();
858 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
859 CurFrame->Instructions.push_back(Inst);
862 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
863 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
864 if (!CurFrame)
865 return;
867 MCSymbol *Label = EmitCFILabel();
869 CurFrame->PrologEnd = Label;
872 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
874 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
876 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
878 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
880 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
882 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
883 /// the specified string in the output .s file. This capability is
884 /// indicated by the hasRawTextSupport() predicate.
885 void MCStreamer::EmitRawTextImpl(StringRef String) {
886 // This is not llvm_unreachable for the sake of out of tree backend
887 // developers who may not have assembly streamers and should serve as a
888 // reminder to not accidentally call EmitRawText in the absence of such.
889 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
890 "it (target backend is likely missing an AsmStreamer "
891 "implementation)");
894 void MCStreamer::EmitRawText(const Twine &T) {
895 SmallString<128> Str;
896 EmitRawTextImpl(T.toStringRef(Str));
899 void MCStreamer::EmitWindowsUnwindTables() {
902 void MCStreamer::Finish() {
903 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
904 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
905 getContext().reportError(SMLoc(), "Unfinished frame!");
906 return;
909 MCTargetStreamer *TS = getTargetStreamer();
910 if (TS)
911 TS->finish();
913 FinishImpl();
916 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
917 visitUsedExpr(*Value);
918 Symbol->setVariableValue(Value);
920 MCTargetStreamer *TS = getTargetStreamer();
921 if (TS)
922 TS->emitAssignment(Symbol, Value);
925 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
926 raw_ostream &OS, const MCInst &Inst,
927 const MCSubtargetInfo &STI) {
928 InstPrinter.printInst(&Inst, OS, "", STI);
931 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
934 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
935 switch (Expr.getKind()) {
936 case MCExpr::Target:
937 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
938 break;
940 case MCExpr::Constant:
941 break;
943 case MCExpr::Binary: {
944 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
945 visitUsedExpr(*BE.getLHS());
946 visitUsedExpr(*BE.getRHS());
947 break;
950 case MCExpr::SymbolRef:
951 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
952 break;
954 case MCExpr::Unary:
955 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
956 break;
960 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
961 // Scan for values.
962 for (unsigned i = Inst.getNumOperands(); i--;)
963 if (Inst.getOperand(i).isExpr())
964 visitUsedExpr(*Inst.getOperand(i).getExpr());
967 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
968 unsigned Size) {
969 // Get the Hi-Lo expression.
970 const MCExpr *Diff =
971 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
972 MCSymbolRefExpr::create(Lo, Context), Context);
974 const MCAsmInfo *MAI = Context.getAsmInfo();
975 if (!MAI->doesSetDirectiveSuppressReloc()) {
976 EmitValue(Diff, Size);
977 return;
980 // Otherwise, emit with .set (aka assignment).
981 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
982 EmitAssignment(SetLabel, Diff);
983 EmitSymbolValue(SetLabel, Size);
986 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
987 const MCSymbol *Lo) {
988 // Get the Hi-Lo expression.
989 const MCExpr *Diff =
990 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
991 MCSymbolRefExpr::create(Lo, Context), Context);
993 EmitULEB128Value(Diff);
996 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
997 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
998 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
999 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1000 llvm_unreachable("this directive only supported on COFF targets");
1002 void MCStreamer::EndCOFFSymbolDef() {
1003 llvm_unreachable("this directive only supported on COFF targets");
1005 void MCStreamer::EmitFileDirective(StringRef Filename) {}
1006 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1007 llvm_unreachable("this directive only supported on COFF targets");
1009 void MCStreamer::EmitCOFFSymbolType(int Type) {
1010 llvm_unreachable("this directive only supported on COFF targets");
1012 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
1013 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1014 const MCSymbol *Aliasee) {}
1015 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1016 unsigned ByteAlignment) {}
1017 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1018 uint64_t Size, unsigned ByteAlignment) {}
1019 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
1020 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
1021 void MCStreamer::EmitBytes(StringRef Data) {}
1022 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
1023 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1024 visitUsedExpr(*Value);
1026 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
1027 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
1028 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
1029 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1030 SMLoc Loc) {}
1031 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1032 unsigned ValueSize,
1033 unsigned MaxBytesToEmit) {}
1034 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
1035 unsigned MaxBytesToEmit) {}
1036 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1037 SMLoc Loc) {}
1038 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
1039 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
1040 void MCStreamer::FinishImpl() {}
1041 void MCStreamer::EmitBundleUnlock() {}
1043 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1044 assert(Section && "Cannot switch to a null section!");
1045 MCSectionSubPair curSection = SectionStack.back().first;
1046 SectionStack.back().second = curSection;
1047 if (MCSectionSubPair(Section, Subsection) != curSection) {
1048 ChangeSection(Section, Subsection);
1049 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1050 assert(!Section->hasEnded() && "Section already ended");
1051 MCSymbol *Sym = Section->getBeginSymbol();
1052 if (Sym && !Sym->isInSection())
1053 EmitLabel(Sym);
1057 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1058 // TODO: keep track of the last subsection so that this symbol appears in the
1059 // correct place.
1060 MCSymbol *Sym = Section->getEndSymbol(Context);
1061 if (Sym->isInSection())
1062 return Sym;
1064 SwitchSection(Section);
1065 EmitLabel(Sym);
1066 return Sym;
1069 void MCStreamer::EmitVersionForTarget(const Triple &Target,
1070 const VersionTuple &SDKVersion) {
1071 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1072 return;
1073 // Do we even know the version?
1074 if (Target.getOSMajorVersion() == 0)
1075 return;
1077 unsigned Major;
1078 unsigned Minor;
1079 unsigned Update;
1080 if (Target.isMacCatalystEnvironment()) {
1081 // Mac Catalyst always uses the build version load command.
1082 Target.getiOSVersion(Major, Minor, Update);
1083 assert(Major && "A non-zero major version is expected");
1084 EmitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update,
1085 SDKVersion);
1086 return;
1089 MCVersionMinType VersionType;
1090 if (Target.isWatchOS()) {
1091 VersionType = MCVM_WatchOSVersionMin;
1092 Target.getWatchOSVersion(Major, Minor, Update);
1093 } else if (Target.isTvOS()) {
1094 VersionType = MCVM_TvOSVersionMin;
1095 Target.getiOSVersion(Major, Minor, Update);
1096 } else if (Target.isMacOSX()) {
1097 VersionType = MCVM_OSXVersionMin;
1098 if (!Target.getMacOSXVersion(Major, Minor, Update))
1099 Major = 0;
1100 } else {
1101 VersionType = MCVM_IOSVersionMin;
1102 Target.getiOSVersion(Major, Minor, Update);
1104 if (Major != 0)
1105 EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion);