[ARM] Generate 8.1-m CSINC, CSNEG and CSINV instructions.
[llvm-core.git] / lib / MC / MCStreamer.cpp
blob38d4b177e282ce29e8fcc00d4718910a1ea0fd1f
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/MCRegister.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCSection.h"
27 #include "llvm/MC/MCSectionCOFF.h"
28 #include "llvm/MC/MCSymbol.h"
29 #include "llvm/MC/MCWin64EH.h"
30 #include "llvm/MC/MCWinEH.h"
31 #include "llvm/Support/Casting.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/LEB128.h"
34 #include "llvm/Support/MathExtras.h"
35 #include "llvm/Support/raw_ostream.h"
36 #include <cassert>
37 #include <cstdint>
38 #include <cstdlib>
39 #include <utility>
41 using namespace llvm;
43 MCTargetStreamer::MCTargetStreamer(MCStreamer &S) : Streamer(S) {
44 S.setTargetStreamer(this);
47 // Pin the vtables to this file.
48 MCTargetStreamer::~MCTargetStreamer() = default;
50 void MCTargetStreamer::emitLabel(MCSymbol *Symbol) {}
52 void MCTargetStreamer::finish() {}
54 void MCTargetStreamer::changeSection(const MCSection *CurSection,
55 MCSection *Section,
56 const MCExpr *Subsection,
57 raw_ostream &OS) {
58 Section->PrintSwitchToSection(
59 *Streamer.getContext().getAsmInfo(),
60 Streamer.getContext().getObjectFileInfo()->getTargetTriple(), OS,
61 Subsection);
64 void MCTargetStreamer::emitDwarfFileDirective(StringRef Directive) {
65 Streamer.EmitRawText(Directive);
68 void MCTargetStreamer::emitValue(const MCExpr *Value) {
69 SmallString<128> Str;
70 raw_svector_ostream OS(Str);
72 Value->print(OS, Streamer.getContext().getAsmInfo());
73 Streamer.EmitRawText(OS.str());
76 void MCTargetStreamer::emitRawBytes(StringRef Data) {
77 const MCAsmInfo *MAI = Streamer.getContext().getAsmInfo();
78 const char *Directive = MAI->getData8bitsDirective();
79 for (const unsigned char C : Data.bytes()) {
80 SmallString<128> Str;
81 raw_svector_ostream OS(Str);
83 OS << Directive << (unsigned)C;
84 Streamer.EmitRawText(OS.str());
88 void MCTargetStreamer::emitAssignment(MCSymbol *Symbol, const MCExpr *Value) {}
90 MCStreamer::MCStreamer(MCContext &Ctx)
91 : Context(Ctx), CurrentWinFrameInfo(nullptr),
92 UseAssemblerInfoForParsing(false) {
93 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
96 MCStreamer::~MCStreamer() {}
98 void MCStreamer::reset() {
99 DwarfFrameInfos.clear();
100 CurrentWinFrameInfo = nullptr;
101 WinFrameInfos.clear();
102 SymbolOrdering.clear();
103 SectionStack.clear();
104 SectionStack.push_back(std::pair<MCSectionSubPair, MCSectionSubPair>());
107 raw_ostream &MCStreamer::GetCommentOS() {
108 // By default, discard comments.
109 return nulls();
112 unsigned MCStreamer::getNumFrameInfos() { return DwarfFrameInfos.size(); }
113 ArrayRef<MCDwarfFrameInfo> MCStreamer::getDwarfFrameInfos() const {
114 return DwarfFrameInfos;
117 void MCStreamer::emitRawComment(const Twine &T, bool TabPrefix) {}
119 void MCStreamer::addExplicitComment(const Twine &T) {}
120 void MCStreamer::emitExplicitComments() {}
122 void MCStreamer::generateCompactUnwindEncodings(MCAsmBackend *MAB) {
123 for (auto &FI : DwarfFrameInfos)
124 FI.CompactUnwindEncoding =
125 (MAB ? MAB->generateCompactUnwindEncoding(FI.Instructions) : 0);
128 /// EmitIntValue - Special case of EmitValue that avoids the client having to
129 /// pass in a MCExpr for constant integers.
130 void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) {
131 assert(1 <= Size && Size <= 8 && "Invalid size");
132 assert((isUIntN(8 * Size, Value) || isIntN(8 * Size, Value)) &&
133 "Invalid size");
134 char buf[8];
135 const bool isLittleEndian = Context.getAsmInfo()->isLittleEndian();
136 for (unsigned i = 0; i != Size; ++i) {
137 unsigned index = isLittleEndian ? i : (Size - i - 1);
138 buf[i] = uint8_t(Value >> (index * 8));
140 EmitBytes(StringRef(buf, Size));
143 /// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the
144 /// client having to pass in a MCExpr for constant integers.
145 void MCStreamer::EmitULEB128IntValue(uint64_t Value, unsigned PadTo) {
146 SmallString<128> Tmp;
147 raw_svector_ostream OSE(Tmp);
148 encodeULEB128(Value, OSE, PadTo);
149 EmitBytes(OSE.str());
152 /// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the
153 /// client having to pass in a MCExpr for constant integers.
154 void MCStreamer::EmitSLEB128IntValue(int64_t Value) {
155 SmallString<128> Tmp;
156 raw_svector_ostream OSE(Tmp);
157 encodeSLEB128(Value, OSE);
158 EmitBytes(OSE.str());
161 void MCStreamer::EmitValue(const MCExpr *Value, unsigned Size, SMLoc Loc) {
162 EmitValueImpl(Value, Size, Loc);
165 void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size,
166 bool IsSectionRelative) {
167 assert((!IsSectionRelative || Size == 4) &&
168 "SectionRelative value requires 4-bytes");
170 if (!IsSectionRelative)
171 EmitValueImpl(MCSymbolRefExpr::create(Sym, getContext()), Size);
172 else
173 EmitCOFFSecRel32(Sym, /*Offset=*/0);
176 void MCStreamer::EmitDTPRel64Value(const MCExpr *Value) {
177 report_fatal_error("unsupported directive in streamer");
180 void MCStreamer::EmitDTPRel32Value(const MCExpr *Value) {
181 report_fatal_error("unsupported directive in streamer");
184 void MCStreamer::EmitTPRel64Value(const MCExpr *Value) {
185 report_fatal_error("unsupported directive in streamer");
188 void MCStreamer::EmitTPRel32Value(const MCExpr *Value) {
189 report_fatal_error("unsupported directive in streamer");
192 void MCStreamer::EmitGPRel64Value(const MCExpr *Value) {
193 report_fatal_error("unsupported directive in streamer");
196 void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
197 report_fatal_error("unsupported directive in streamer");
200 /// Emit NumBytes bytes worth of the value specified by FillValue.
201 /// This implements directives such as '.space'.
202 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
203 emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
206 /// The implementation in this class just redirects to emitFill.
207 void MCStreamer::EmitZeros(uint64_t NumBytes) {
208 emitFill(NumBytes, 0);
211 Expected<unsigned>
212 MCStreamer::tryEmitDwarfFileDirective(unsigned FileNo, StringRef Directory,
213 StringRef Filename,
214 Optional<MD5::MD5Result> Checksum,
215 Optional<StringRef> Source,
216 unsigned CUID) {
217 return getContext().getDwarfFile(Directory, Filename, FileNo, Checksum,
218 Source, CUID);
221 void MCStreamer::emitDwarfFile0Directive(StringRef Directory,
222 StringRef Filename,
223 Optional<MD5::MD5Result> Checksum,
224 Optional<StringRef> Source,
225 unsigned CUID) {
226 getContext().setMCLineTableRootFile(CUID, Directory, Filename, Checksum,
227 Source);
230 void MCStreamer::EmitCFIBKeyFrame() {
231 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
232 if (!CurFrame)
233 return;
234 CurFrame->IsBKeyFrame = true;
237 void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
238 unsigned Column, unsigned Flags,
239 unsigned Isa,
240 unsigned Discriminator,
241 StringRef FileName) {
242 getContext().setCurrentDwarfLoc(FileNo, Line, Column, Flags, Isa,
243 Discriminator);
246 MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
247 MCDwarfLineTable &Table = getContext().getMCDwarfLineTable(CUID);
248 if (!Table.getLabel()) {
249 StringRef Prefix = Context.getAsmInfo()->getPrivateGlobalPrefix();
250 Table.setLabel(
251 Context.getOrCreateSymbol(Prefix + "line_table_start" + Twine(CUID)));
253 return Table.getLabel();
256 bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
257 return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
260 MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
261 if (!hasUnfinishedDwarfFrameInfo()) {
262 getContext().reportError(SMLoc(), "this directive must appear between "
263 ".cfi_startproc and .cfi_endproc "
264 "directives");
265 return nullptr;
267 return &DwarfFrameInfos.back();
270 bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
271 ArrayRef<uint8_t> Checksum,
272 unsigned ChecksumKind) {
273 return getContext().getCVContext().addFile(*this, FileNo, Filename, Checksum,
274 ChecksumKind);
277 bool MCStreamer::EmitCVFuncIdDirective(unsigned FunctionId) {
278 return getContext().getCVContext().recordFunctionId(FunctionId);
281 bool MCStreamer::EmitCVInlineSiteIdDirective(unsigned FunctionId,
282 unsigned IAFunc, unsigned IAFile,
283 unsigned IALine, unsigned IACol,
284 SMLoc Loc) {
285 if (getContext().getCVContext().getCVFunctionInfo(IAFunc) == nullptr) {
286 getContext().reportError(Loc, "parent function id not introduced by "
287 ".cv_func_id or .cv_inline_site_id");
288 return true;
291 return getContext().getCVContext().recordInlinedCallSiteId(
292 FunctionId, IAFunc, IAFile, IALine, IACol);
295 void MCStreamer::EmitCVLocDirective(unsigned FunctionId, unsigned FileNo,
296 unsigned Line, unsigned Column,
297 bool PrologueEnd, bool IsStmt,
298 StringRef FileName, SMLoc Loc) {}
300 bool MCStreamer::checkCVLocSection(unsigned FuncId, unsigned FileNo,
301 SMLoc Loc) {
302 CodeViewContext &CVC = getContext().getCVContext();
303 MCCVFunctionInfo *FI = CVC.getCVFunctionInfo(FuncId);
304 if (!FI) {
305 getContext().reportError(
306 Loc, "function id not introduced by .cv_func_id or .cv_inline_site_id");
307 return false;
310 // Track the section
311 if (FI->Section == nullptr)
312 FI->Section = getCurrentSectionOnly();
313 else if (FI->Section != getCurrentSectionOnly()) {
314 getContext().reportError(
315 Loc,
316 "all .cv_loc directives for a function must be in the same section");
317 return false;
319 return true;
322 void MCStreamer::EmitCVLinetableDirective(unsigned FunctionId,
323 const MCSymbol *Begin,
324 const MCSymbol *End) {}
326 void MCStreamer::EmitCVInlineLinetableDirective(unsigned PrimaryFunctionId,
327 unsigned SourceFileId,
328 unsigned SourceLineNum,
329 const MCSymbol *FnStartSym,
330 const MCSymbol *FnEndSym) {}
332 /// Only call this on endian-specific types like ulittle16_t and little32_t, or
333 /// structs composed of them.
334 template <typename T>
335 static void copyBytesForDefRange(SmallString<20> &BytePrefix,
336 codeview::SymbolKind SymKind,
337 const T &DefRangeHeader) {
338 BytePrefix.resize(2 + sizeof(T));
339 codeview::ulittle16_t SymKindLE = codeview::ulittle16_t(SymKind);
340 memcpy(&BytePrefix[0], &SymKindLE, 2);
341 memcpy(&BytePrefix[2], &DefRangeHeader, sizeof(T));
344 void MCStreamer::EmitCVDefRangeDirective(
345 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
346 StringRef FixedSizePortion) {}
348 void MCStreamer::EmitCVDefRangeDirective(
349 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
350 codeview::DefRangeRegisterRelSym::Header DRHdr) {
351 SmallString<20> BytePrefix;
352 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER_REL, DRHdr);
353 EmitCVDefRangeDirective(Ranges, BytePrefix);
356 void MCStreamer::EmitCVDefRangeDirective(
357 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
358 codeview::DefRangeSubfieldRegisterSym::Header DRHdr) {
359 SmallString<20> BytePrefix;
360 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_SUBFIELD_REGISTER,
361 DRHdr);
362 EmitCVDefRangeDirective(Ranges, BytePrefix);
365 void MCStreamer::EmitCVDefRangeDirective(
366 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
367 codeview::DefRangeRegisterSym::Header DRHdr) {
368 SmallString<20> BytePrefix;
369 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_REGISTER, DRHdr);
370 EmitCVDefRangeDirective(Ranges, BytePrefix);
373 void MCStreamer::EmitCVDefRangeDirective(
374 ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
375 codeview::DefRangeFramePointerRelSym::Header DRHdr) {
376 SmallString<20> BytePrefix;
377 copyBytesForDefRange(BytePrefix, codeview::S_DEFRANGE_FRAMEPOINTER_REL,
378 DRHdr);
379 EmitCVDefRangeDirective(Ranges, BytePrefix);
382 void MCStreamer::EmitEHSymAttributes(const MCSymbol *Symbol,
383 MCSymbol *EHSymbol) {
386 void MCStreamer::InitSections(bool NoExecStack) {
387 SwitchSection(getContext().getObjectFileInfo()->getTextSection());
390 void MCStreamer::AssignFragment(MCSymbol *Symbol, MCFragment *Fragment) {
391 assert(Fragment);
392 Symbol->setFragment(Fragment);
394 // As we emit symbols into a section, track the order so that they can
395 // be sorted upon later. Zero is reserved to mean 'unemitted'.
396 SymbolOrdering[Symbol] = 1 + SymbolOrdering.size();
399 void MCStreamer::EmitLabel(MCSymbol *Symbol, SMLoc Loc) {
400 Symbol->redefineIfPossible();
402 if (!Symbol->isUndefined() || Symbol->isVariable())
403 return getContext().reportError(Loc, "invalid symbol redefinition");
405 assert(!Symbol->isVariable() && "Cannot emit a variable symbol!");
406 assert(getCurrentSectionOnly() && "Cannot emit before setting section!");
407 assert(!Symbol->getFragment() && "Unexpected fragment on symbol data!");
408 assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
410 Symbol->setFragment(&getCurrentSectionOnly()->getDummyFragment());
412 MCTargetStreamer *TS = getTargetStreamer();
413 if (TS)
414 TS->emitLabel(Symbol);
417 void MCStreamer::EmitCFISections(bool EH, bool Debug) {
418 assert(EH || Debug);
421 void MCStreamer::EmitCFIStartProc(bool IsSimple, SMLoc Loc) {
422 if (hasUnfinishedDwarfFrameInfo())
423 return getContext().reportError(
424 Loc, "starting new .cfi frame before finishing the previous one");
426 MCDwarfFrameInfo Frame;
427 Frame.IsSimple = IsSimple;
428 EmitCFIStartProcImpl(Frame);
430 const MCAsmInfo* MAI = Context.getAsmInfo();
431 if (MAI) {
432 for (const MCCFIInstruction& Inst : MAI->getInitialFrameState()) {
433 if (Inst.getOperation() == MCCFIInstruction::OpDefCfa ||
434 Inst.getOperation() == MCCFIInstruction::OpDefCfaRegister) {
435 Frame.CurrentCfaRegister = Inst.getRegister();
440 DwarfFrameInfos.push_back(Frame);
443 void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
446 void MCStreamer::EmitCFIEndProc() {
447 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
448 if (!CurFrame)
449 return;
450 EmitCFIEndProcImpl(*CurFrame);
453 void MCStreamer::EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
454 // Put a dummy non-null value in Frame.End to mark that this frame has been
455 // closed.
456 Frame.End = (MCSymbol *)1;
459 MCSymbol *MCStreamer::EmitCFILabel() {
460 // Return a dummy non-null value so that label fields appear filled in when
461 // generating textual assembly.
462 return (MCSymbol *)1;
465 void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
466 MCSymbol *Label = EmitCFILabel();
467 MCCFIInstruction Instruction =
468 MCCFIInstruction::createDefCfa(Label, Register, Offset);
469 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
470 if (!CurFrame)
471 return;
472 CurFrame->Instructions.push_back(Instruction);
473 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
476 void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
477 MCSymbol *Label = EmitCFILabel();
478 MCCFIInstruction Instruction =
479 MCCFIInstruction::createDefCfaOffset(Label, Offset);
480 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
481 if (!CurFrame)
482 return;
483 CurFrame->Instructions.push_back(Instruction);
486 void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
487 MCSymbol *Label = EmitCFILabel();
488 MCCFIInstruction Instruction =
489 MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
490 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
491 if (!CurFrame)
492 return;
493 CurFrame->Instructions.push_back(Instruction);
496 void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
497 MCSymbol *Label = EmitCFILabel();
498 MCCFIInstruction Instruction =
499 MCCFIInstruction::createDefCfaRegister(Label, Register);
500 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
501 if (!CurFrame)
502 return;
503 CurFrame->Instructions.push_back(Instruction);
504 CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
507 void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
508 MCSymbol *Label = EmitCFILabel();
509 MCCFIInstruction Instruction =
510 MCCFIInstruction::createOffset(Label, Register, Offset);
511 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
512 if (!CurFrame)
513 return;
514 CurFrame->Instructions.push_back(Instruction);
517 void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
518 MCSymbol *Label = EmitCFILabel();
519 MCCFIInstruction Instruction =
520 MCCFIInstruction::createRelOffset(Label, Register, Offset);
521 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
522 if (!CurFrame)
523 return;
524 CurFrame->Instructions.push_back(Instruction);
527 void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
528 unsigned Encoding) {
529 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
530 if (!CurFrame)
531 return;
532 CurFrame->Personality = Sym;
533 CurFrame->PersonalityEncoding = Encoding;
536 void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
537 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
538 if (!CurFrame)
539 return;
540 CurFrame->Lsda = Sym;
541 CurFrame->LsdaEncoding = Encoding;
544 void MCStreamer::EmitCFIRememberState() {
545 MCSymbol *Label = EmitCFILabel();
546 MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
547 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
548 if (!CurFrame)
549 return;
550 CurFrame->Instructions.push_back(Instruction);
553 void MCStreamer::EmitCFIRestoreState() {
554 // FIXME: Error if there is no matching cfi_remember_state.
555 MCSymbol *Label = EmitCFILabel();
556 MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
557 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
558 if (!CurFrame)
559 return;
560 CurFrame->Instructions.push_back(Instruction);
563 void MCStreamer::EmitCFISameValue(int64_t Register) {
564 MCSymbol *Label = EmitCFILabel();
565 MCCFIInstruction Instruction =
566 MCCFIInstruction::createSameValue(Label, Register);
567 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
568 if (!CurFrame)
569 return;
570 CurFrame->Instructions.push_back(Instruction);
573 void MCStreamer::EmitCFIRestore(int64_t Register) {
574 MCSymbol *Label = EmitCFILabel();
575 MCCFIInstruction Instruction =
576 MCCFIInstruction::createRestore(Label, Register);
577 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
578 if (!CurFrame)
579 return;
580 CurFrame->Instructions.push_back(Instruction);
583 void MCStreamer::EmitCFIEscape(StringRef Values) {
584 MCSymbol *Label = EmitCFILabel();
585 MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
586 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
587 if (!CurFrame)
588 return;
589 CurFrame->Instructions.push_back(Instruction);
592 void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
593 MCSymbol *Label = EmitCFILabel();
594 MCCFIInstruction Instruction =
595 MCCFIInstruction::createGnuArgsSize(Label, Size);
596 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
597 if (!CurFrame)
598 return;
599 CurFrame->Instructions.push_back(Instruction);
602 void MCStreamer::EmitCFISignalFrame() {
603 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
604 if (!CurFrame)
605 return;
606 CurFrame->IsSignalFrame = true;
609 void MCStreamer::EmitCFIUndefined(int64_t Register) {
610 MCSymbol *Label = EmitCFILabel();
611 MCCFIInstruction Instruction =
612 MCCFIInstruction::createUndefined(Label, Register);
613 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
614 if (!CurFrame)
615 return;
616 CurFrame->Instructions.push_back(Instruction);
619 void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
620 MCSymbol *Label = EmitCFILabel();
621 MCCFIInstruction Instruction =
622 MCCFIInstruction::createRegister(Label, Register1, Register2);
623 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
624 if (!CurFrame)
625 return;
626 CurFrame->Instructions.push_back(Instruction);
629 void MCStreamer::EmitCFIWindowSave() {
630 MCSymbol *Label = EmitCFILabel();
631 MCCFIInstruction Instruction =
632 MCCFIInstruction::createWindowSave(Label);
633 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
634 if (!CurFrame)
635 return;
636 CurFrame->Instructions.push_back(Instruction);
639 void MCStreamer::EmitCFINegateRAState() {
640 MCSymbol *Label = EmitCFILabel();
641 MCCFIInstruction Instruction = MCCFIInstruction::createNegateRAState(Label);
642 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
643 if (!CurFrame)
644 return;
645 CurFrame->Instructions.push_back(Instruction);
648 void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
649 MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
650 if (!CurFrame)
651 return;
652 CurFrame->RAReg = Register;
655 WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
656 const MCAsmInfo *MAI = Context.getAsmInfo();
657 if (!MAI->usesWindowsCFI()) {
658 getContext().reportError(
659 Loc, ".seh_* directives are not supported on this target");
660 return nullptr;
662 if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
663 getContext().reportError(
664 Loc, ".seh_ directive must appear within an active frame");
665 return nullptr;
667 return CurrentWinFrameInfo;
670 void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
671 const MCAsmInfo *MAI = Context.getAsmInfo();
672 if (!MAI->usesWindowsCFI())
673 return getContext().reportError(
674 Loc, ".seh_* directives are not supported on this target");
675 if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
676 getContext().reportError(
677 Loc, "Starting a function before ending the previous one!");
679 MCSymbol *StartProc = EmitCFILabel();
681 WinFrameInfos.emplace_back(
682 std::make_unique<WinEH::FrameInfo>(Symbol, StartProc));
683 CurrentWinFrameInfo = WinFrameInfos.back().get();
684 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
687 void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
688 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
689 if (!CurFrame)
690 return;
691 if (CurFrame->ChainedParent)
692 getContext().reportError(Loc, "Not all chained regions terminated!");
694 MCSymbol *Label = EmitCFILabel();
695 CurFrame->End = Label;
698 void MCStreamer::EmitWinCFIFuncletOrFuncEnd(SMLoc Loc) {
699 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
700 if (!CurFrame)
701 return;
702 if (CurFrame->ChainedParent)
703 getContext().reportError(Loc, "Not all chained regions terminated!");
705 MCSymbol *Label = EmitCFILabel();
706 CurFrame->FuncletOrFuncEnd = Label;
709 void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
710 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
711 if (!CurFrame)
712 return;
714 MCSymbol *StartProc = EmitCFILabel();
716 WinFrameInfos.emplace_back(std::make_unique<WinEH::FrameInfo>(
717 CurFrame->Function, StartProc, CurFrame));
718 CurrentWinFrameInfo = WinFrameInfos.back().get();
719 CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
722 void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
723 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
724 if (!CurFrame)
725 return;
726 if (!CurFrame->ChainedParent)
727 return getContext().reportError(
728 Loc, "End of a chained region outside a chained region!");
730 MCSymbol *Label = EmitCFILabel();
732 CurFrame->End = Label;
733 CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
736 void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
737 SMLoc Loc) {
738 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
739 if (!CurFrame)
740 return;
741 if (CurFrame->ChainedParent)
742 return getContext().reportError(
743 Loc, "Chained unwind areas can't have handlers!");
744 CurFrame->ExceptionHandler = Sym;
745 if (!Except && !Unwind)
746 getContext().reportError(Loc, "Don't know what kind of handler this is!");
747 if (Unwind)
748 CurFrame->HandlesUnwind = true;
749 if (Except)
750 CurFrame->HandlesExceptions = true;
753 void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
754 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
755 if (!CurFrame)
756 return;
757 if (CurFrame->ChainedParent)
758 getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
761 void MCStreamer::emitCGProfileEntry(const MCSymbolRefExpr *From,
762 const MCSymbolRefExpr *To, uint64_t Count) {
765 static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
766 MCSection *MainCFISec,
767 const MCSection *TextSec) {
768 // If this is the main .text section, use the main unwind info section.
769 if (TextSec == Context.getObjectFileInfo()->getTextSection())
770 return MainCFISec;
772 const auto *TextSecCOFF = cast<MCSectionCOFF>(TextSec);
773 auto *MainCFISecCOFF = cast<MCSectionCOFF>(MainCFISec);
774 unsigned UniqueID = TextSecCOFF->getOrAssignWinCFISectionID(NextWinCFIID);
776 // If this section is COMDAT, this unwind section should be COMDAT associative
777 // with its group.
778 const MCSymbol *KeySym = nullptr;
779 if (TextSecCOFF->getCharacteristics() & COFF::IMAGE_SCN_LNK_COMDAT) {
780 KeySym = TextSecCOFF->getCOMDATSymbol();
782 // In a GNU environment, we can't use associative comdats. Instead, do what
783 // GCC does, which is to make plain comdat selectany section named like
784 // ".[px]data$_Z3foov".
785 if (!Context.getAsmInfo()->hasCOFFAssociativeComdats()) {
786 std::string SectionName =
787 (MainCFISecCOFF->getSectionName() + "$" +
788 TextSecCOFF->getSectionName().split('$').second)
789 .str();
790 return Context.getCOFFSection(
791 SectionName,
792 MainCFISecCOFF->getCharacteristics() | COFF::IMAGE_SCN_LNK_COMDAT,
793 MainCFISecCOFF->getKind(), "", COFF::IMAGE_COMDAT_SELECT_ANY);
797 return Context.getAssociativeCOFFSection(MainCFISecCOFF, KeySym, UniqueID);
800 MCSection *MCStreamer::getAssociatedPDataSection(const MCSection *TextSec) {
801 return getWinCFISection(getContext(), &NextWinCFIID,
802 getContext().getObjectFileInfo()->getPDataSection(),
803 TextSec);
806 MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
807 return getWinCFISection(getContext(), &NextWinCFIID,
808 getContext().getObjectFileInfo()->getXDataSection(),
809 TextSec);
812 void MCStreamer::EmitSyntaxDirective() {}
814 static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
815 return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
818 void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
819 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
820 if (!CurFrame)
821 return;
823 MCSymbol *Label = EmitCFILabel();
825 WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
826 Label, encodeSEHRegNum(Context, Register));
827 CurFrame->Instructions.push_back(Inst);
830 void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
831 SMLoc Loc) {
832 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
833 if (!CurFrame)
834 return;
835 if (CurFrame->LastFrameInst >= 0)
836 return getContext().reportError(
837 Loc, "frame register and offset can be set at most once");
838 if (Offset & 0x0F)
839 return getContext().reportError(Loc, "offset is not a multiple of 16");
840 if (Offset > 240)
841 return getContext().reportError(
842 Loc, "frame offset must be less than or equal to 240");
844 MCSymbol *Label = EmitCFILabel();
846 WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
847 Label, encodeSEHRegNum(getContext(), Register), Offset);
848 CurFrame->LastFrameInst = CurFrame->Instructions.size();
849 CurFrame->Instructions.push_back(Inst);
852 void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
853 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
854 if (!CurFrame)
855 return;
856 if (Size == 0)
857 return getContext().reportError(Loc,
858 "stack allocation size must be non-zero");
859 if (Size & 7)
860 return getContext().reportError(
861 Loc, "stack allocation size is not a multiple of 8");
863 MCSymbol *Label = EmitCFILabel();
865 WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
866 CurFrame->Instructions.push_back(Inst);
869 void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
870 SMLoc Loc) {
871 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
872 if (!CurFrame)
873 return;
875 if (Offset & 7)
876 return getContext().reportError(
877 Loc, "register save offset is not 8 byte aligned");
879 MCSymbol *Label = EmitCFILabel();
881 WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
882 Label, encodeSEHRegNum(Context, Register), Offset);
883 CurFrame->Instructions.push_back(Inst);
886 void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
887 SMLoc Loc) {
888 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
889 if (!CurFrame)
890 return;
891 if (Offset & 0x0F)
892 return getContext().reportError(Loc, "offset is not a multiple of 16");
894 MCSymbol *Label = EmitCFILabel();
896 WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
897 Label, encodeSEHRegNum(Context, Register), Offset);
898 CurFrame->Instructions.push_back(Inst);
901 void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
902 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
903 if (!CurFrame)
904 return;
905 if (!CurFrame->Instructions.empty())
906 return getContext().reportError(
907 Loc, "If present, PushMachFrame must be the first UOP");
909 MCSymbol *Label = EmitCFILabel();
911 WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
912 CurFrame->Instructions.push_back(Inst);
915 void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
916 WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
917 if (!CurFrame)
918 return;
920 MCSymbol *Label = EmitCFILabel();
922 CurFrame->PrologEnd = Label;
925 void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {}
927 void MCStreamer::EmitCOFFSymbolIndex(MCSymbol const *Symbol) {}
929 void MCStreamer::EmitCOFFSectionIndex(MCSymbol const *Symbol) {}
931 void MCStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol, uint64_t Offset) {}
933 void MCStreamer::EmitCOFFImgRel32(MCSymbol const *Symbol, int64_t Offset) {}
935 /// EmitRawText - If this file is backed by an assembly streamer, this dumps
936 /// the specified string in the output .s file. This capability is
937 /// indicated by the hasRawTextSupport() predicate.
938 void MCStreamer::EmitRawTextImpl(StringRef String) {
939 // This is not llvm_unreachable for the sake of out of tree backend
940 // developers who may not have assembly streamers and should serve as a
941 // reminder to not accidentally call EmitRawText in the absence of such.
942 report_fatal_error("EmitRawText called on an MCStreamer that doesn't support "
943 "it (target backend is likely missing an AsmStreamer "
944 "implementation)");
947 void MCStreamer::EmitRawText(const Twine &T) {
948 SmallString<128> Str;
949 EmitRawTextImpl(T.toStringRef(Str));
952 void MCStreamer::EmitWindowsUnwindTables() {
955 void MCStreamer::Finish() {
956 if ((!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End) ||
957 (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)) {
958 getContext().reportError(SMLoc(), "Unfinished frame!");
959 return;
962 MCTargetStreamer *TS = getTargetStreamer();
963 if (TS)
964 TS->finish();
966 FinishImpl();
969 void MCStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) {
970 visitUsedExpr(*Value);
971 Symbol->setVariableValue(Value);
973 MCTargetStreamer *TS = getTargetStreamer();
974 if (TS)
975 TS->emitAssignment(Symbol, Value);
978 void MCTargetStreamer::prettyPrintAsm(MCInstPrinter &InstPrinter,
979 raw_ostream &OS, const MCInst &Inst,
980 const MCSubtargetInfo &STI) {
981 InstPrinter.printInst(&Inst, OS, "", STI);
984 void MCStreamer::visitUsedSymbol(const MCSymbol &Sym) {
987 void MCStreamer::visitUsedExpr(const MCExpr &Expr) {
988 switch (Expr.getKind()) {
989 case MCExpr::Target:
990 cast<MCTargetExpr>(Expr).visitUsedExpr(*this);
991 break;
993 case MCExpr::Constant:
994 break;
996 case MCExpr::Binary: {
997 const MCBinaryExpr &BE = cast<MCBinaryExpr>(Expr);
998 visitUsedExpr(*BE.getLHS());
999 visitUsedExpr(*BE.getRHS());
1000 break;
1003 case MCExpr::SymbolRef:
1004 visitUsedSymbol(cast<MCSymbolRefExpr>(Expr).getSymbol());
1005 break;
1007 case MCExpr::Unary:
1008 visitUsedExpr(*cast<MCUnaryExpr>(Expr).getSubExpr());
1009 break;
1013 void MCStreamer::EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &) {
1014 // Scan for values.
1015 for (unsigned i = Inst.getNumOperands(); i--;)
1016 if (Inst.getOperand(i).isExpr())
1017 visitUsedExpr(*Inst.getOperand(i).getExpr());
1020 void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
1021 unsigned Size) {
1022 // Get the Hi-Lo expression.
1023 const MCExpr *Diff =
1024 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1025 MCSymbolRefExpr::create(Lo, Context), Context);
1027 const MCAsmInfo *MAI = Context.getAsmInfo();
1028 if (!MAI->doesSetDirectiveSuppressReloc()) {
1029 EmitValue(Diff, Size);
1030 return;
1033 // Otherwise, emit with .set (aka assignment).
1034 MCSymbol *SetLabel = Context.createTempSymbol("set", true);
1035 EmitAssignment(SetLabel, Diff);
1036 EmitSymbolValue(SetLabel, Size);
1039 void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi,
1040 const MCSymbol *Lo) {
1041 // Get the Hi-Lo expression.
1042 const MCExpr *Diff =
1043 MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
1044 MCSymbolRefExpr::create(Lo, Context), Context);
1046 EmitULEB128Value(Diff);
1049 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
1050 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
1051 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}
1052 void MCStreamer::BeginCOFFSymbolDef(const MCSymbol *Symbol) {
1053 llvm_unreachable("this directive only supported on COFF targets");
1055 void MCStreamer::EndCOFFSymbolDef() {
1056 llvm_unreachable("this directive only supported on COFF targets");
1058 void MCStreamer::EmitFileDirective(StringRef Filename) {}
1059 void MCStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
1060 llvm_unreachable("this directive only supported on COFF targets");
1062 void MCStreamer::EmitCOFFSymbolType(int Type) {
1063 llvm_unreachable("this directive only supported on COFF targets");
1065 void MCStreamer::EmitXCOFFLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1066 unsigned ByteAlign) {
1067 llvm_unreachable("this directive only supported on XCOFF targets");
1069 void MCStreamer::emitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
1070 void MCStreamer::emitELFSymverDirective(StringRef AliasName,
1071 const MCSymbol *Aliasee) {}
1072 void MCStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
1073 unsigned ByteAlignment) {}
1074 void MCStreamer::EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol,
1075 uint64_t Size, unsigned ByteAlignment) {}
1076 void MCStreamer::ChangeSection(MCSection *, const MCExpr *) {}
1077 void MCStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {}
1078 void MCStreamer::EmitBytes(StringRef Data) {}
1079 void MCStreamer::EmitBinaryData(StringRef Data) { EmitBytes(Data); }
1080 void MCStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, SMLoc Loc) {
1081 visitUsedExpr(*Value);
1083 void MCStreamer::EmitULEB128Value(const MCExpr *Value) {}
1084 void MCStreamer::EmitSLEB128Value(const MCExpr *Value) {}
1085 void MCStreamer::emitFill(const MCExpr &NumBytes, uint64_t Value, SMLoc Loc) {}
1086 void MCStreamer::emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
1087 SMLoc Loc) {}
1088 void MCStreamer::EmitValueToAlignment(unsigned ByteAlignment, int64_t Value,
1089 unsigned ValueSize,
1090 unsigned MaxBytesToEmit) {}
1091 void MCStreamer::EmitCodeAlignment(unsigned ByteAlignment,
1092 unsigned MaxBytesToEmit) {}
1093 void MCStreamer::emitValueToOffset(const MCExpr *Offset, unsigned char Value,
1094 SMLoc Loc) {}
1095 void MCStreamer::EmitBundleAlignMode(unsigned AlignPow2) {}
1096 void MCStreamer::EmitBundleLock(bool AlignToEnd) {}
1097 void MCStreamer::FinishImpl() {}
1098 void MCStreamer::EmitBundleUnlock() {}
1100 void MCStreamer::SwitchSection(MCSection *Section, const MCExpr *Subsection) {
1101 assert(Section && "Cannot switch to a null section!");
1102 MCSectionSubPair curSection = SectionStack.back().first;
1103 SectionStack.back().second = curSection;
1104 if (MCSectionSubPair(Section, Subsection) != curSection) {
1105 ChangeSection(Section, Subsection);
1106 SectionStack.back().first = MCSectionSubPair(Section, Subsection);
1107 assert(!Section->hasEnded() && "Section already ended");
1108 MCSymbol *Sym = Section->getBeginSymbol();
1109 if (Sym && !Sym->isInSection())
1110 EmitLabel(Sym);
1114 MCSymbol *MCStreamer::endSection(MCSection *Section) {
1115 // TODO: keep track of the last subsection so that this symbol appears in the
1116 // correct place.
1117 MCSymbol *Sym = Section->getEndSymbol(Context);
1118 if (Sym->isInSection())
1119 return Sym;
1121 SwitchSection(Section);
1122 EmitLabel(Sym);
1123 return Sym;
1126 void MCStreamer::EmitVersionForTarget(const Triple &Target,
1127 const VersionTuple &SDKVersion) {
1128 if (!Target.isOSBinFormatMachO() || !Target.isOSDarwin())
1129 return;
1130 // Do we even know the version?
1131 if (Target.getOSMajorVersion() == 0)
1132 return;
1134 unsigned Major;
1135 unsigned Minor;
1136 unsigned Update;
1137 if (Target.isMacCatalystEnvironment()) {
1138 // Mac Catalyst always uses the build version load command.
1139 Target.getiOSVersion(Major, Minor, Update);
1140 assert(Major && "A non-zero major version is expected");
1141 EmitBuildVersion(MachO::PLATFORM_MACCATALYST, Major, Minor, Update,
1142 SDKVersion);
1143 return;
1146 MCVersionMinType VersionType;
1147 if (Target.isWatchOS()) {
1148 VersionType = MCVM_WatchOSVersionMin;
1149 Target.getWatchOSVersion(Major, Minor, Update);
1150 } else if (Target.isTvOS()) {
1151 VersionType = MCVM_TvOSVersionMin;
1152 Target.getiOSVersion(Major, Minor, Update);
1153 } else if (Target.isMacOSX()) {
1154 VersionType = MCVM_OSXVersionMin;
1155 if (!Target.getMacOSXVersion(Major, Minor, Update))
1156 Major = 0;
1157 } else {
1158 VersionType = MCVM_IOSVersionMin;
1159 Target.getiOSVersion(Major, Minor, Update);
1161 if (Major != 0)
1162 EmitVersionMin(VersionType, Major, Minor, Update, SDKVersion);