LLVM 24.0.0git
SystemZXPLINKAsmPrinter.cpp
Go to the documentation of this file.
1//===-- SystemZXPLINKAsmPrinter.cpp - SystemZ XPLINK asm printer ----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the SystemZXPLINKAsmPrinter class.
10//
11//===----------------------------------------------------------------------===//
12
17#include "SystemZInstrInfo.h"
18#include "SystemZMCInstLower.h"
20#include "SystemZSubtarget.h"
24#include "llvm/IR/Function.h"
25#include "llvm/IR/GlobalAlias.h"
27#include "llvm/IR/Module.h"
28#include "llvm/MC/MCExpr.h"
31#include "llvm/Support/Chrono.h"
34
35using namespace llvm;
36
40
42 SM.reset();
43
44 // In HLASM, the only way to represent aliases is to use the
45 // extra-label-at-definition strategy. This is similar to the AIX
46 // implementation with the additional caveat that all symbol attributes must
47 // be emitted before the label is emitted.
48 // Construct an aliasing list for each GlobalObject.
49 for (const auto &Alias : M.aliases()) {
50 const GlobalObject *Aliasee = Alias.getAliaseeObject();
51 if (!Aliasee)
52 OutContext.reportError(
53 {}, "Alias without a base object is not yet supported on z/OS.");
54
55 bool IsFunc = isa<Function>(Aliasee->stripPointerCasts());
56 if (IsFunc) {
57 if (Alias.hasWeakLinkage() || Alias.hasLinkOnceLinkage())
58 OutContext.reportError({},
59 "Weak alias/reference not supported on z/OS");
60
61 GOAliasMap[Aliasee].push_back(&Alias);
62 } else
63 OutContext.reportError({},
64 "Only aliases to functions is supported in GOFF.");
65 }
67}
68
69// The XPLINK ABI requires that a no-op encoding the call type is emitted after
70// each call to a subroutine. This information can be used by the called
71// function to determine its entry point, e.g. for generating a backtrace. The
72// call type is encoded as a register number in the bcr instruction. See
73// enumeration CallType for the possible values.
74void SystemZXPLINKAsmPrinter::emitCallInformation(CallType CT) {
76 MCInstBuilder(SystemZ::BCRAsm)
77 .addImm(0)
78 .addReg(SystemZMC::GR64Regs[static_cast<unsigned>(CT)]));
79}
80
82SystemZXPLINKAsmPrinter::AssociatedDataAreaTable::insert(const MCSymbol *Sym,
83 unsigned SlotKind) {
84 auto Key = std::make_pair(Sym, SlotKind);
85 auto It = Displacements.find(Key);
86
87 if (It != Displacements.end())
88 return (*It).second;
89
90 // Determine length of descriptor.
92 switch (SlotKind) {
94 Length = 2 * PointerSize;
95 break;
96 default:
98 break;
99 }
100
101 uint32_t Displacement = NextDisplacement;
102 Displacements[std::make_pair(Sym, SlotKind)] = NextDisplacement;
103 NextDisplacement += Length;
104
105 return Displacement;
106}
107
108uint32_t SystemZXPLINKAsmPrinter::AssociatedDataAreaTable::insert(
109 const MachineFunction &MF, const MachineOperand &MO) {
110 MCSymbol *Sym;
112 const GlobalValue *GV = MO.getGlobal();
113 Sym = MF.getTarget().getSymbol(GV);
114 assert(Sym && "No symbol");
115 } else if (MO.getType() == MachineOperand::MO_ExternalSymbol) {
116 const char *SymName = MO.getSymbolName();
117 Sym = MF.getContext().getOrCreateSymbol(SymName);
118 assert(Sym && "No symbol");
119 } else
120 llvm_unreachable("Unexpected operand type");
121
122 unsigned ADAslotType = MO.getTargetFlags();
123 return insert(Sym, ADAslotType);
124}
125
127 SystemZMCInstLower Lower(MF->getContext(), *this);
128 MCInst LoweredMI;
129
130 switch (MI->getOpcode()) {
131 case SystemZ::CallBRASL_XPLINK64:
133 .addReg(SystemZ::R7D)
134 .addExpr(Lower.getExpr(MI->getOperand(0),
136 emitCallInformation(CallType::BRASL7);
137 return;
138
139 case SystemZ::CallBASR_XPLINK64:
141 .addReg(SystemZ::R7D)
142 .addReg(MI->getOperand(0).getReg()));
143 emitCallInformation(CallType::BASR76);
144 return;
145
146 case SystemZ::Return_XPLINK:
147 LoweredMI =
148 MCInstBuilder(SystemZ::B).addReg(SystemZ::R7D).addImm(2).addReg(0);
149 break;
150
151 case SystemZ::CondReturn_XPLINK:
152 LoweredMI = MCInstBuilder(SystemZ::BC)
153 .addImm(MI->getOperand(0).getImm())
154 .addImm(MI->getOperand(1).getImm())
155 .addReg(SystemZ::R7D)
156 .addImm(2)
157 .addReg(0);
158 break;
159
160 case SystemZ::XPLINK_STACKRESTORE: {
161 if (!StackRestoreStub)
162 StackRestoreStub = OutContext.createTempSymbol("stackrestore");
164 .addReg(SystemZ::R3D)
166 StackRestoreStub, OutContext)));
169 MCInstBuilder(SystemZ::BASR).addReg(SystemZ::R3D).addReg(SystemZ::R3D));
170 emitCallInformation(CallType::BASR33);
171 return;
172 }
173
174 case SystemZ::CallBASR_STACKEXT:
176 .addReg(SystemZ::R3D)
177 .addReg(MI->getOperand(0).getReg()));
178 emitCallInformation(CallType::BASR33);
179 return;
180
181 case SystemZ::ADA_ENTRY_VALUE:
182 case SystemZ::ADA_ENTRY: {
183 const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
184 const SystemZInstrInfo *TII = Subtarget.getInstrInfo();
185 uint32_t Disp = ADATable.insert(*MF, MI->getOperand(1));
186 Register TargetReg = MI->getOperand(0).getReg();
187
188 Register ADAReg = MI->getOperand(2).getReg();
189 Disp += MI->getOperand(3).getImm();
190 bool LoadAddr = MI->getOpcode() == SystemZ::ADA_ENTRY;
191
192 unsigned Op0 = LoadAddr ? SystemZ::LA : SystemZ::LG;
193 unsigned Op = TII->getOpcodeForOffset(Op0, Disp);
194
195 Register IndexReg = 0;
196 if (!Op) {
197 if (TargetReg != ADAReg) {
198 IndexReg = TargetReg;
199 // Use TargetReg to store displacement.
202 MCInstBuilder(SystemZ::LLILF).addReg(TargetReg).addImm(Disp));
203 } else
205 .addReg(TargetReg)
206 .addReg(TargetReg)
207 .addImm(Disp));
208 Disp = 0;
209 Op = Op0;
210 }
213 MCInstBuilder(Op).addReg(TargetReg).addReg(ADAReg).addImm(Disp).addReg(
214 IndexReg));
215 return;
216 }
217
218 default:
220 return;
221 }
222 EmitToStreamer(*OutStreamer, LoweredMI);
223}
224
226 const Constant *List,
227 bool IsCtor) {
228 assert(TM.getTargetTriple().isOSBinFormatGOFF() && "Only GOFF supported");
229
230 SmallVector<Structor, 8> Structors;
231 preprocessXXStructorList(DL, List, Structors);
232 if (Structors.empty())
233 return;
234
235 const Align Align = llvm::Align(4);
237 static_cast<const TargetLoweringObjectFileGOFF &>(getObjFileLowering());
238 for (Structor &S : Structors) {
239 MCSectionGOFF *Section =
240 static_cast<MCSectionGOFF *>(Obj.getStaticXtorSection(S.Priority));
241 OutStreamer->switchSection(Section);
242 if (OutStreamer->getCurrentSection() != OutStreamer->getPreviousSection())
244
245 // The priority is provided as an input to getStaticXtorSection(), and is
246 // recalculated within that function as `Prio` going to going into the
247 // PR section.
248 // This priority retrieved via the `SortKey` below is the recalculated
249 // Priority.
250 uint32_t XtorPriority = Section->getPRAttributes().SortKey;
251
252 const GlobalValue *GV = dyn_cast<GlobalValue>(S.Func->stripPointerCasts());
253 assert(GV && "C++ xxtor pointer was not a GlobalValue!");
254 MCSymbolGOFF *Symbol = static_cast<MCSymbolGOFF *>(getSymbol(GV));
255
256 // @@SQINIT entry: { unsigned prio; void (*ctor)(); void (*dtor)(); }
257
258 unsigned PointerSizeInBytes = DL.getPointerSize();
259
260 auto &Ctx = OutStreamer->getContext();
261 const MCExpr *ADAFuncRefExpr;
262 unsigned SlotKind = SystemZII::MO_ADA_DIRECT_FUNC_DESC;
263
264 MCSectionGOFF *ADASection =
265 static_cast<MCSectionGOFF *>(Obj.getADASection());
266 assert(ADASection && "ADA section must exist for GOFF targets!");
267 const MCSymbol *ADASym = ADASection->getBeginSymbol();
268 assert(ADASym && "ADA symbol should already be set!");
269
270 ADAFuncRefExpr = MCBinaryExpr::createAdd(
273 MCConstantExpr::create(ADATable.insert(Symbol, SlotKind), Ctx), Ctx);
274
275 emitInt32(XtorPriority);
276 if (IsCtor) {
277 OutStreamer->emitValue(ADAFuncRefExpr, PointerSizeInBytes);
278 OutStreamer->emitIntValue(0, PointerSizeInBytes);
279 } else {
280 OutStreamer->emitIntValue(0, PointerSizeInBytes);
281 OutStreamer->emitValue(ADAFuncRefExpr, PointerSizeInBytes);
282 }
283 }
284}
285
287 // The stack restore stub follows the last function. It must be emitted
288 // before the debug information is finalized, which may end the code section
289 // (emitEndOfAsmFile is too late).
290 if (StackRestoreStub)
291 emitStackRestoreStub();
293}
294
296 auto *ZOS = getTargetStreamer();
297 emitADASection();
298 emitIDRLSection(M);
299 // On z/OS, we need to associate an external data reference with an ED
300 // symbol, for which we use the the ED of the ADA. We also need to mark the
301 // reference as being to data, otherwise we cannot bind with code generated
302 // by XL.
303 for (auto &GO : M.global_objects()) {
304 if (auto *GV = dyn_cast<GlobalVariable>(&GO)) {
305 if (!GV->hasInitializer()) {
306 MCSymbol *Sym = getSymbol(GV);
307 ZOS->emitADA(Sym, OutContext.getObjectFileInfo()->getADASection());
308 OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject);
309 }
310 }
311 }
312}
313
314// Emit CELQMAIN in RENT format (see z/OS Language Environment Vendor
315// Interfaces, "Program initialization and termination for AMODE 64
316// applications"):
317// +0 X'04000001'
318// +8 AD(main entry point)
319// +10 AD(CELQINPL)
320// +18 A(0) / Q(environment); emitted as 8 byte R-con to main, which the
321// binder resolves to the offset of the ADA of main (fits into 4 bytes)
322// followed by a reference to the bootstrap routine CELQBST. CELQSTRT only has
323// a weak reference to CELQBST, so without it autocall would not include it.
324void SystemZXPLINKAsmPrinter::emitCELQMAIN(const Function &MainFn) {
325 MCSymbol *MainSym = getSymbol(&MainFn);
326 auto ExternalOSSymbol = [&](StringRef Name, bool IsRenameable) {
328 OutStreamer->emitSymbolAttribute(Sym, MCSA_OSLinkage);
329 OutStreamer->emitSymbolAttribute(Sym, MCSA_Global);
330 getTargetStreamer()->emitRenameable(Sym, IsRenameable);
331 return Sym;
332 };
333 MCSymbol *CELQINPL = ExternalOSSymbol("CELQINPL", /*IsRenameable=*/false);
334 MCSymbol *CELQBST = ExternalOSSymbol("CELQBST", /*IsRenameable=*/true);
335
336 OutStreamer->pushSection();
337 OutStreamer->switchSection(getObjFileLowering().getTextSection());
338 OutStreamer->emitValueToAlignment(Align(8));
339 MCSymbol *CELQMAIN = OutContext.getOrCreateSymbol("CELQMAIN");
340 // Referenced by CELQSTRT, CELQINPL and CELQBST with OS linkage.
341 OutStreamer->emitSymbolAttribute(CELQMAIN, MCSA_OSLinkage);
342 OutStreamer->emitSymbolAttribute(CELQMAIN, MCSA_Global);
343 OutStreamer->emitSymbolAttribute(CELQMAIN, MCSA_Hidden);
344 OutStreamer->emitLabel(CELQMAIN);
345 OutStreamer->AddComment("CELQMAIN, RENT format");
346 OutStreamer->emitInt32(0x04000001);
347 OutStreamer->emitInt32(0);
348 OutStreamer->AddComment("Address of main");
349 OutStreamer->emitValue(MCSymbolRefExpr::create(MainSym, OutContext), 8);
350 OutStreamer->AddComment("Address of CELQINPL");
351 OutStreamer->emitValue(MCSymbolRefExpr::create(CELQINPL, OutContext), 8);
352 OutStreamer->AddComment("Q(environment) of main");
353 OutStreamer->emitValue(
356 8);
357 OutStreamer->AddComment("Reference to CELQBST");
358 OutStreamer->emitValue(MCSymbolRefExpr::create(CELQBST, OutContext), 8);
359 OutStreamer->popSection();
360}
361
362void SystemZXPLINKAsmPrinter::emitADASection() {
363 OutStreamer->pushSection();
364
365 const unsigned PointerSize = getDataLayout().getPointerSize();
366 OutStreamer->switchSection(getObjFileLowering().getADASection());
367
368 auto *ZOS = getTargetStreamer();
369 unsigned EmittedBytes = 0;
370 for (auto &Entry : ADATable.getTable()) {
371 const MCSymbol *Sym;
372 unsigned SlotKind;
373 std::tie(Sym, SlotKind) = Entry.first;
374 unsigned Offset = Entry.second;
375 assert(Offset == EmittedBytes && "Offset not as expected");
376 (void)EmittedBytes;
377#define EMIT_COMMENT(Str) \
378 OutStreamer->AddComment(Twine("Offset ") \
379 .concat(utostr(Offset)) \
380 .concat(" " Str " ") \
381 .concat(Sym->getName()));
382 switch (SlotKind) {
384 // Language Environment DLL logic requires function descriptors, for
385 // imported functions, that are placed in the ADA to be 8 byte aligned.
386 EMIT_COMMENT("function descriptor of");
387 OutStreamer->emitValue(
391 OutStreamer->emitValue(
395 EmittedBytes += PointerSize * 2;
396 break;
398 EMIT_COMMENT("pointer to data symbol");
399 OutStreamer->emitValue(
403 EmittedBytes += PointerSize;
404 break;
406 MCSymbol *Alias = OutContext.getOrCreateSymbol(
407 Twine(Sym->getName()).concat("@indirect"));
408 OutStreamer->emitSymbolAttribute(Alias, MCSA_IndirectSymbol);
409 OutStreamer->emitSymbolAttribute(Alias, MCSA_ELF_TypeFunction);
410 OutStreamer->emitSymbolAttribute(Alias, MCSA_Global);
411 OutStreamer->emitSymbolAttribute(Alias, MCSA_Extern);
412 MCSymbolGOFF *GOFFSym =
413 static_cast<llvm::MCSymbolGOFF *>(const_cast<llvm::MCSymbol *>(Sym));
414 // A weak reference (extern_weak) stays weak through the indirect
415 // symbol, otherwise the binder fails on the unresolved reference.
416 if (GOFFSym->isWeak())
417 OutStreamer->emitSymbolAttribute(Alias, MCSA_WeakReference);
418 ZOS->emitExternalName(Alias, GOFFSym->getExternalName());
419 EMIT_COMMENT("pointer to function descriptor");
420 OutStreamer->emitValue(
424 EmittedBytes += PointerSize;
425 break;
426 }
427 default:
428 llvm_unreachable("Unexpected slot kind");
429 }
430#undef EMIT_COMMENT
431 }
432 OutStreamer->popSection();
433}
434
435static std::string getProductID(Module &M) {
436 std::string ProductID;
437 if (auto *MD = M.getModuleFlag("zos_product_id"))
438 ProductID = cast<MDString>(MD)->getString().str();
439 if (ProductID.empty())
440 ProductID = "LLVM";
441 return ProductID;
442}
443
445 if (auto *VersionVal = mdconst::extract_or_null<ConstantInt>(
446 M.getModuleFlag("zos_product_major_version")))
447 return VersionVal->getZExtValue();
448 return LLVM_VERSION_MAJOR;
449}
450
452 if (auto *ReleaseVal = mdconst::extract_or_null<ConstantInt>(
453 M.getModuleFlag("zos_product_minor_version")))
454 return ReleaseVal->getZExtValue();
455 return LLVM_VERSION_MINOR;
456}
457
459 if (auto *PatchVal = mdconst::extract_or_null<ConstantInt>(
460 M.getModuleFlag("zos_product_patchlevel")))
461 return PatchVal->getZExtValue();
462 return LLVM_VERSION_PATCH;
463}
464
465static time_t getTranslationTime(Module &M) {
466 std::time_t Time = 0;
468 M.getModuleFlag("zos_translation_time"))) {
469 long SecondsSinceEpoch = Val->getSExtValue();
470 Time = static_cast<time_t>(SecondsSinceEpoch);
471 }
472 return Time;
473}
474
475void SystemZXPLINKAsmPrinter::emitIDRLSection(Module &M) {
476 OutStreamer->pushSection();
477 OutStreamer->switchSection(getObjFileLowering().getIDRLSection());
478 constexpr unsigned IDRLDataLength = 30;
479 std::time_t Time = getTranslationTime(M);
480
481 uint32_t ProductVersion = getProductVersion(M);
482 uint32_t ProductRelease = getProductRelease(M);
483
484 std::string ProductID = getProductID(M);
485
486 SmallString<IDRLDataLength + 1> TempStr;
487 raw_svector_ostream O(TempStr);
488 O << formatv("{0,-10}{1,0-2:d}{2,0-2:d}{3:%Y%m%d%H%M%S}{4,0-2}",
489 ProductID.substr(0, 10).c_str(), ProductVersion, ProductRelease,
490 llvm::sys::toUtcTime(Time), "0");
491 SmallString<IDRLDataLength> Data;
493
494 OutStreamer->emitInt8(0); // Reserved.
495 OutStreamer->emitInt8(3); // Format.
496 OutStreamer->emitInt16(IDRLDataLength); // Length.
497 OutStreamer->emitBytes(Data.str());
498 OutStreamer->popSection();
499}
500
502 // A stub (naked function) has no PPA1 and thus no end of function symbol.
503 if (MF->getFunction().hasFnAttribute(Attribute::Naked))
504 return;
505
506 // Emit symbol for the end of function if the z/OS target streamer
507 // is used. This is needed to calculate the size of the function.
508 auto *ZOS = getTargetStreamer();
509 OutStreamer->emitLabel(ZOS->DeferredPPA1.back().FnEnd);
510}
511
512// Determine the end of the prolog and the instructions which updates the stack
513// register, and attach symbols to those instructions.
515 MCSymbol *&EndOfPrologSym,
516 MCSymbol *&StackUpdateSym) {
517 EndOfPrologSym = nullptr;
518 StackUpdateSym = nullptr;
519
520 // Scan the basic block for the FENCE instruction which marks the end
521 // of the prologue. We know
522 // the prologue is spread at most across the first 3 basic blocks. Also record
523 // the first instruction updating the stack pointer.
526 MachineInstr *EndOfPrologMI = nullptr;
527 MachineInstr *StackUpdateMI = nullptr;
528 unsigned BBCount = 1;
529
530 for (auto &MBB : *MF) {
531 for (auto &I : MBB) {
532 if (I.getOpcode() == SystemZ::FENCE)
533 EndOfPrologMI = &I;
534 else if (!StackUpdateMI) {
535 unsigned Opcode = I.getOpcode();
536 // TODO: We can instead emit a pseudo instruction in
537 // SystemZFrameLowering to represent a stack adjustment instruction, and
538 // check for that here, instead of having to check for multiple
539 // instructions.
540 if ((Opcode == SystemZ::AGHI || Opcode == SystemZ::AGFI) &&
541 I.getOperand(0).getReg() == Regs.getStackPointerRegister())
542 StackUpdateMI = &I;
543 }
544 }
545
546 // Prologue can be a max of 3 BBs if we need to call stack extension code
547 if (EndOfPrologMI || BBCount == 3)
548 break;
549
550 ++BBCount;
551 }
552
553 // Leaf functions do not have a prologue.
554 if (EndOfPrologMI == nullptr)
555 return;
556
557#ifdef EXPENSIVE_CHECKS
558 // Check that the prolog length is valid.
559 auto *TII = STI.getInstrInfo();
560 size_t Size = 0;
561
562 for (auto &MBB : *MF) {
563 bool TerminateLoop = false;
564 for (auto &I : MBB) {
565 Size += TII->getInstSizeInBytes(I);
566 if (&I == EndOfPrologMI) {
567 TerminateLoop = true;
568 break;
569 }
570 }
571 if (TerminateLoop)
572 break;
573 }
574 if (Size > 128)
576 Twine(MF->getName()).concat(": Prolog exceeds 128 bytes"));
577#endif
578
579 // Attach a temporary symbol to mark the end of the prolog.
580 EndOfPrologSym = MF->getContext().createTempSymbol("end_of_prologue");
581 EndOfPrologMI->setPostInstrSymbol(*MF, EndOfPrologSym);
582
583 if (StackUpdateMI) {
584 StackUpdateSym = MF->getContext().createTempSymbol("stack_update");
585 StackUpdateMI->setPreInstrSymbol(*MF, StackUpdateSym);
586 }
587}
588
589void SystemZXPLINKAsmPrinter::calculatePPA1() {
590 auto *ZOS = getTargetStreamer();
591 assert(ZOS->PPA2Sym != nullptr && "PPA2 Symbol not defined");
592
593 SystemZTargetzOSStreamer::PPA1Info Info;
594
595 const TargetRegisterInfo *TRI = MF->getRegInfo().getTargetRegisterInfo();
596 const SystemZSubtarget &Subtarget = MF->getSubtarget<SystemZSubtarget>();
597
598 const SystemZMachineFunctionInfo *ZFI =
599 MF->getInfo<SystemZMachineFunctionInfo>();
600 const auto *ZFL = static_cast<const SystemZXPLINKFrameLowering *>(
602 const MachineFrameInfo &MFFrame = MF->getFrameInfo();
603
604 // Get saved GPR/FPR/VPR masks.
605 const std::vector<CalleeSavedInfo> &CSI = MFFrame.getCalleeSavedInfo();
606 uint16_t SavedGPRMask = 0;
607 uint16_t SavedFPRMask = 0;
608 uint8_t SavedVRMask = 0;
609 int64_t OffsetFPR = 0;
610 int64_t OffsetVR = 0;
611 const int64_t TopOfStack =
612 MFFrame.getOffsetAdjustment() + MFFrame.getStackSize();
613
614 // Loop over the spilled registers. The CalleeSavedInfo can't be used because
615 // it does not contain all spilled registers.
616 for (unsigned I = ZFI->getSpillGPRRegs().LowGPR,
617 E = ZFI->getSpillGPRRegs().HighGPR;
618 I && E && I <= E; ++I) {
619 unsigned V = TRI->getEncodingValue((Register)I);
620 assert(V < 16 && "GPR index out of range");
621 SavedGPRMask |= 1 << (15 - V);
622 }
623
624 for (auto &CS : CSI) {
625 unsigned Reg = CS.getReg();
626 unsigned I = TRI->getEncodingValue(Reg);
627
628 if (SystemZ::FP64BitRegClass.contains(Reg)) {
629 assert(I < 16 && "FPR index out of range");
630 SavedFPRMask |= 1 << (15 - I);
631 int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
632 if (Temp < OffsetFPR)
633 OffsetFPR = Temp;
634 } else if (SystemZ::VR128BitRegClass.contains(Reg)) {
635 assert(I >= 16 && I <= 23 && "VPR index out of range");
636 unsigned BitNum = I - 16;
637 SavedVRMask |= 1 << (7 - BitNum);
638 int64_t Temp = MFFrame.getObjectOffset(CS.getFrameIdx());
639 if (Temp < OffsetVR)
640 OffsetVR = Temp;
641 }
642 }
643
644 // Adjust the offset.
645 OffsetFPR += (OffsetFPR < 0) ? TopOfStack : 0;
646 OffsetVR += (OffsetVR < 0) ? TopOfStack : 0;
647
648 // Get alloca register.
649 uint8_t FrameReg = TRI->getEncodingValue(TRI->getFrameRegister(*MF));
650 uint8_t AllocaReg = ZFL->hasFP(*MF) ? FrameReg : 0;
651 assert(AllocaReg < 16 && "Can't have alloca register larger than 15");
652
653 MCSymbol *PersonalityRoutine = nullptr;
654 MCSymbol *GCCEH = nullptr;
655 uint64_t PersonalityADADisp = 0;
656 uint64_t GCCEHADADisp = 0;
657 if (!MF->getLandingPads().empty()) {
658 const Function *Per = dyn_cast<Function>(
659 MF->getFunction().getPersonalityFn()->stripPointerCasts());
660 PersonalityRoutine = Per ? MF->getTarget().getSymbol(Per) : nullptr;
661 if (PersonalityRoutine) {
662 GCCEH = MF->getContext().getOrCreateSymbol(
663 Twine("GCC_except_table") + Twine(MF->getFunctionNumber()));
664 PersonalityADADisp = ADATable.insert(
665 PersonalityRoutine, SystemZII::MO_ADA_INDIRECT_FUNC_DESC);
666 GCCEHADADisp = ADATable.insert(GCCEH, SystemZII::MO_ADA_DATA_SYMBOL_ADDR);
667 }
668 }
669
670 // Get the name of the function, with suffix _.
671 std::string N(MF->getFunction().hasName()
672 ? Twine(MF->getFunction().getName()).concat("_").str()
673 : "");
674
675 // Calculate the lables for the prolog size and the stack update symbol.
676 MCSymbol *EndOfPrologSym;
677 MCSymbol *StackUpdateSym;
678 determinePrologueStackUpdateSym(MF, EndOfPrologSym, StackUpdateSym);
679
680 // Save the calculated values.
681 if (MF->getFunction().hasFnAttribute("zos-ppa1-name"))
682 Info.Name =
683 MF->getFunction().getFnAttribute("zos-ppa1-name").getValueAsString();
684 else if (MF->getFunction().hasName())
685 Info.Name = MF->getFunction().getName();
686
687 Info.PPA1 = OutContext.createTempSymbol(Twine("PPA1_").concat(N), true);
688 Info.EPMarker = OutContext.createTempSymbol(Twine("EPM_").concat(N), true);
689 Info.FnEnd = OutContext.createTempSymbol(Twine(N).concat("end_"));
690 Info.Fn = CurrentFnSym;
691 Info.EndOfProlog = EndOfPrologSym;
692 Info.StackUpdate = StackUpdateSym;
693 Info.PersonalityADADisp = PersonalityADADisp;
694 Info.GCCEHADADisp = GCCEHADADisp;
695 Info.OffsetFPR = OffsetFPR;
696 Info.OffsetVR = OffsetVR;
697 Info.CallFrameSize = MFFrame.getMaxCallFrameSize();
698 Info.SizeOfFnParams = ZFI->getSizeOfFnParams();
699 Info.SavedGPRMask = SavedGPRMask;
700 Info.SavedFPRMask = SavedFPRMask;
701 Info.SavedVRMask = SavedVRMask;
702 Info.FrameReg = FrameReg;
703 Info.AllocaReg = AllocaReg;
704 Info.IsVarArg = MF->getFunction().isVarArg();
705 Info.HasStackProtector = MFFrame.hasStackProtectorIndex();
706
707 ZOS->DeferredPPA1.push_back(Info);
708}
709
711 emitPPA2(M);
712 // A main program needs CELQMAIN, through which the Language Environment
713 // startup (CELQSTRT) finds the main routine and its environment. It is
714 // emitted here and not at the end of the file, because the text section
715 // may already be closed then (e.g. after emitting the DWARF aranges).
716 if (const Function *MainFn = M.getFunction("main");
717 MainFn && !MainFn->isDeclaration())
718 emitCELQMAIN(*MainFn);
720}
721
722// Emit the stack restore stub. A stack restore must copy the frame header
723// (which @@ALCAXP moved down with the stack pointer) to the restored stack
724// pointer, and no signal may be delivered while the stack pointer is changed
725// and the header is copied. Language Environment delays signals while a stub
726// runs, so this is done in a stub routine: it has a stub entry marker
727// (preceded by 8 bytes of padding, so that the entry is 16 bytes after the
728// start, like for a normal routine), no PPA1 and no save area. Like the stack
729// extension routine, it is called with BASR 3,3 and returns with B 2(3). It
730// gets the new stack pointer in R1. The new stack pointer is never below the
731// current one, and both are multiples of 32 apart (0 if no storage was
732// allocated), so copying the header in blocks of 32 bytes from the highest
733// block down never overwrites a block that is still to be copied.
734void SystemZXPLINKAsmPrinter::emitStackRestoreStub() {
736 auto Emit = [&](const MCInst &Inst) {
737 OutStreamer->emitInstruction(Inst, STI);
738 };
739
740 OutStreamer->pushSection();
741 OutStreamer->switchSection(getObjFileLowering().getTextSection());
742 OutStreamer->emitValueToAlignment(Align(8));
743 OutStreamer->AddComment("XPLINK Stub Entry Padding");
744 OutStreamer->emitIntValue(0, 8);
745 OutStreamer->AddComment("XPLINK Stub Entry Marker");
746 OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
747 OutStreamer->emitIntValueInHex(0x00C300C500C500, 7);
748 OutStreamer->AddComment("Mark Type C'4'");
749 OutStreamer->emitInt8(0xF4);
750 OutStreamer->emitLabel(StackRestoreStub);
751
753 const int Bias = Regs.getStackPointerBias();
754 const int Block = 32;
755 for (int Off = Regs.getCallFrameSize() - Block; Off >= 0; Off -= Block)
756 Emit(MCInstBuilder(SystemZ::MVC)
757 .addReg(SystemZ::R1D)
758 .addImm(Bias + Off)
759 .addImm(Block)
760 .addReg(SystemZ::R4D)
761 .addImm(Bias + Off));
762 Emit(MCInstBuilder(SystemZ::LGR).addReg(SystemZ::R4D).addReg(SystemZ::R1D));
763 Emit(MCInstBuilder(SystemZ::B).addReg(SystemZ::R3D).addImm(2).addReg(0));
764 OutStreamer->popSection();
765}
766
767void SystemZXPLINKAsmPrinter::emitPPA2(Module &M) {
768 auto *ZOS = getTargetStreamer();
769 OutStreamer->pushSection();
770 OutStreamer->switchSection(getObjFileLowering().getTextSection());
771 MCContext &OutContext = OutStreamer->getContext();
772 // Make CELQSTRT symbol.
773 const char *StartSymbolName = "CELQSTRT";
774 MCSymbol *CELQSTRT = OutContext.getOrCreateSymbol(StartSymbolName);
775 OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_OSLinkage);
776 OutStreamer->emitSymbolAttribute(CELQSTRT, MCSA_Global);
777 ZOS->emitRenameable(CELQSTRT, /*IsRenamable=*/false);
778
779 // Create symbol and assign to streamer field for use in PPA1.
780 ZOS->PPA2Sym = OutContext.createTempSymbol("PPA2", false);
781 MCSymbol *PPA2Sym = ZOS->PPA2Sym;
782 MCSymbol *DateVersionSym = OutContext.createTempSymbol("DVS", false);
783
784 std::time_t Time = getTranslationTime(M);
785 SmallString<14> CompilationTimeEBCDIC, CompilationTime;
786 CompilationTime = formatv("{0:%Y%m%d%H%M%S}", llvm::sys::toUtcTime(Time));
787
788 uint32_t ProductVersion = getProductVersion(M),
789 ProductRelease = getProductRelease(M),
790 ProductPatch = getProductPatch(M);
791
792 SmallString<6> VersionEBCDIC, Version;
793 Version = formatv("{0,0+2:d}{1,0+2:d}{2,0+2:d}", ProductVersion,
794 ProductRelease, ProductPatch);
795
796 ConverterEBCDIC::convertToEBCDIC(CompilationTime, CompilationTimeEBCDIC);
798
799 enum class PPA2MemberId : uint8_t {
800 // See z/OS Language Environment Vendor Interfaces v2r5, p.23, for
801 // complete list. Only the C runtime is supported by this backend.
802 LE_C_Runtime = 3,
803 };
804 enum class PPA2MemberSubId : uint8_t {
805 // List of languages using the LE C runtime implementation.
806 C = 0x00,
807 CXX = 0x01,
808 Swift = 0x03,
809 Go = 0x60,
810 LLVMBasedLang = 0xe7,
811 };
812 // PPA2 Flags
813 enum class PPA2Flags : uint8_t {
814 CompileForBinaryFloatingPoint = 0x80,
815 CompiledWithXPLink = 0x01,
816 CompiledUnitASCII = 0x04,
817 HasServiceInfo = 0x20,
818 };
819
820 PPA2MemberSubId MemberSubId = PPA2MemberSubId::LLVMBasedLang;
821 if (auto *MD = M.getModuleFlag("zos_cu_language")) {
822 StringRef Language = cast<MDString>(MD)->getString();
823 MemberSubId = StringSwitch<PPA2MemberSubId>(Language)
824 .Case("C", PPA2MemberSubId::C)
825 .Case("C++", PPA2MemberSubId::CXX)
826 .Case("Swift", PPA2MemberSubId::Swift)
827 .Case("Go", PPA2MemberSubId::Go)
828 .Default(PPA2MemberSubId::LLVMBasedLang);
829 }
830
831 // Emit PPA2 section.
832 OutStreamer->emitLabel(PPA2Sym);
833 OutStreamer->emitInt8(static_cast<uint8_t>(PPA2MemberId::LE_C_Runtime));
834 OutStreamer->emitInt8(static_cast<uint8_t>(MemberSubId));
835 OutStreamer->emitInt8(0x22); // Member defined, c370_plist+c370_env
836 OutStreamer->emitInt8(0x04); // Control level 4 (XPLink)
837 OutStreamer->emitAbsoluteSymbolDiff(CELQSTRT, PPA2Sym, 4);
838 OutStreamer->emitInt32(0x00000000);
839 OutStreamer->emitAbsoluteSymbolDiff(DateVersionSym, PPA2Sym, 4);
840 OutStreamer->emitInt32(
841 0x00000000); // Offset to main entry point, always 0 (so says TR).
842 uint8_t Flgs = static_cast<uint8_t>(PPA2Flags::CompileForBinaryFloatingPoint);
843 Flgs |= static_cast<uint8_t>(PPA2Flags::CompiledWithXPLink);
844
845 bool IsASCII = true;
846 if (auto *MD = M.getModuleFlag("zos_le_char_mode")) {
847 const StringRef &CharMode = cast<MDString>(MD)->getString();
848 if (CharMode == "ebcdic")
849 IsASCII = false;
850 else if (CharMode != "ascii")
851 OutContext.reportError(
852 {}, "Only ascii or ebcdic are allowed for zos_le_char_mode");
853 }
854 if (IsASCII)
855 Flgs |= static_cast<uint8_t>(
856 PPA2Flags::CompiledUnitASCII); // Setting bit for ASCII char. mode.
857
858 OutStreamer->emitInt8(Flgs);
859 OutStreamer->emitInt8(0x00); // Reserved.
860 // No MD5 signature before timestamp.
861 // No FLOAT(AFP(VOLATILE)).
862 // Remaining 5 flag bits reserved.
863 OutStreamer->emitInt16(0x0000); // 16 Reserved flag bits.
864
865 // Emit date and version section.
866 OutStreamer->emitLabel(DateVersionSym);
867 OutStreamer->emitBytes(CompilationTimeEBCDIC.str());
868 OutStreamer->emitBytes(VersionEBCDIC.str());
869
870 OutStreamer->emitInt16(0x0000); // Service level string length.
871
872 // The binder requires that the offset to the PPA2 be emitted in a different,
873 // specially-named section.
874 OutStreamer->switchSection(getObjFileLowering().getPPA2ListSection());
875 // Emit 8 byte alignment.
876 // Emit pointer to PPA2 label.
877 OutStreamer->AddComment("A(PPA2-CELQSTRT)");
878 OutStreamer->emitAbsoluteSymbolDiff(PPA2Sym, CELQSTRT, 8);
879 OutStreamer->popSection();
880}
881
883 const GlobalAlias &GA) {
884 if (!M.getTargetTriple().isOSzOS())
885 return AsmPrinter::emitGlobalAlias(M, GA);
886
887 // Aliased function labels have already been emitted for z/OS
888}
889
891 const Constant *BaseCV,
892 uint64_t Offset) {
893 const GlobalAlias *GA = dyn_cast<GlobalAlias>(CV);
895 const Function *FV = dyn_cast<Function>(CV);
896
897 MCSymbol *Sym = nullptr;
898 if (GA)
899 Sym = getSymbol(GA);
900 else if (FV)
901 Sym = getSymbol(FV);
902 else if (GV)
903 Sym = getSymbol(GV);
904 else
905 return AsmPrinter::lowerConstant(CV);
906
907 // Functions and function aliases need special handling.
908 if (FV || (GA && isa<Function>(GA->getAliaseeObject()))) {
909 // A function pointer must point to a function descriptor (a V-con would
910 // yield the entry point instead), and it must compare equal to the address
911 // of the same function taken in code. For a function that is not internal,
912 // code loads the address of the descriptor from an ADA slot that refers to
913 // the indirect symbol; the binder resolves that reference to the function
914 // descriptor. Use the same reference here. The slot is shared with code
915 // taking the address and defines the indirect symbol.
916 const GlobalValue *FGV = GA ? static_cast<const GlobalValue *>(GA)
917 : static_cast<const GlobalValue *>(FV);
918 if (!FGV->hasLocalLinkage()) {
919 ADATable.insert(Sym, SystemZII::MO_ADA_INDIRECT_FUNC_DESC);
920 MCSymbol *Alias = OutContext.getOrCreateSymbol(
921 Twine(Sym->getName()).concat("@indirect"));
924 }
925 // Internal functions: function descriptor in the ADA.
926 unsigned Disp = ADATable.insert(Sym, SystemZII::MO_ADA_DIRECT_FUNC_DESC);
930 getObjFileLowering().getADASection()->getBeginSymbol(),
931 OutContext),
934 }
935 auto *ZOS = getTargetStreamer();
936 ZOS->emitADA(Sym, OutContext.getObjectFileInfo()->getADASection());
937 OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeObject);
939}
940
942 auto *ZOS = getTargetStreamer();
943
944 // A naked function is an XPLINK stub: it has a stub entry marker and no PPA1.
945 if (MF->getFunction().hasFnAttribute(Attribute::Naked)) {
946 // The entry marker of a normal function is 16 bytes. Pad the 8 byte stub
947 // marker, so that the entry point is at the same offset from the start of
948 // the function.
949 OutStreamer->AddComment("XPLINK Stub Entry Padding");
950 OutStreamer->emitZeros(8);
951 OutStreamer->AddComment("XPLINK Stub Entry Marker");
952 OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
953 OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
954 OutStreamer->AddComment("Mark Type C'4'");
955 OutStreamer->emitInt8(0xF4); // Mark Type.
956 } else {
957 calculatePPA1();
958
959 // EntryPoint Marker
960 const MachineFrameInfo &MFFrame = MF->getFrameInfo();
961 bool IsUsingAlloca = MFFrame.hasVarSizedObjects();
962 uint32_t DSASize = MFFrame.getStackSize();
963 bool IsLeaf = DSASize == 0 && MFFrame.getCalleeSavedInfo().empty();
964
965 // Set Flags.
966 uint8_t Flags = 0;
967 if (IsLeaf)
968 Flags |= 0x08;
969 if (IsUsingAlloca)
970 Flags |= 0x04;
971
972 // Combine into top 27 bits of DSASize and bottom 5 bits of Flags.
973 uint32_t DSAAndFlags = DSASize & 0xFFFFFFE0; // (x/32) << 5
974 DSAAndFlags |= Flags;
975
976 // Emit entry point marker section.
977 OutStreamer->AddComment("XPLINK Routine Layout Entry");
978 OutStreamer->emitLabel(ZOS->DeferredPPA1.back().EPMarker);
979 OutStreamer->AddComment("Eyecatcher 0x00C300C500C500");
980 OutStreamer->emitIntValueInHex(0x00C300C500C500, 7); // Eyecatcher.
981 OutStreamer->AddComment("Mark Type C'1'");
982 OutStreamer->emitInt8(0xF1); // Mark Type.
983 OutStreamer->AddComment("Offset to PPA1");
984 OutStreamer->emitAbsoluteSymbolDiff(ZOS->DeferredPPA1.back().PPA1,
985 ZOS->DeferredPPA1.back().EPMarker, 4);
986 if (OutStreamer->isVerboseAsm()) {
987 OutStreamer->AddComment("DSA Size 0x" + Twine::utohexstr(DSASize));
988 OutStreamer->AddComment("Entry Flags");
989 if (Flags & 0x08)
990 OutStreamer->AddComment(" Bit 1: 1 = Leaf function");
991 else
992 OutStreamer->AddComment(" Bit 1: 0 = Non-leaf function");
993 if (Flags & 0x04)
994 OutStreamer->AddComment(" Bit 2: 1 = Uses alloca");
995 else
996 OutStreamer->AddComment(" Bit 2: 0 = Does not use alloca");
997 }
998 OutStreamer->emitInt32(DSAAndFlags);
999 }
1000
1001 ZOS->emitADA(CurrentFnSym, getObjFileLowering().getADASection());
1002
1004
1005 const Function *F = &MF->getFunction();
1006 // Emit aliasing label for function entry point label.
1007 for (const GlobalAlias *Alias : GOAliasMap[F]) {
1008 MCSymbol *Sym = getSymbol(Alias);
1009 ZOS->emitADA(Sym, getObjFileLowering().getADASection());
1010 OutStreamer->emitSymbolAttribute(Sym, MCSA_ELF_TypeFunction);
1011 emitVisibility(Sym, Alias->getVisibility());
1012 emitLinkage(Alias, Sym);
1013 OutStreamer->emitLabel(Sym);
1014 }
1015}
const AArch64Subtarget & Subtarget
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides utility functions for converting between EBCDIC-1047 and UTF-8.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
This file contains the MCSymbolGOFF class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:479
This file contains some functions that are useful when dealing with strings.
std::unique_ptr< MCStreamer > && Streamer
#define EMIT_COMMENT(Str)
static void determinePrologueStackUpdateSym(MachineFunction *MF, MCSymbol *&EndOfPrologSym, MCSymbol *&StackUpdateSym)
static uint32_t getProductVersion(Module &M)
static std::string getProductID(Module &M)
static time_t getTranslationTime(Module &M)
static uint32_t getProductRelease(Module &M)
static uint32_t getProductPatch(Module &M)
const AArch64FrameLowering * getFrameLowering() const override
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
TargetMachine & TM
Target machine description.
Definition AsmPrinter.h:98
virtual void emitGlobalAlias(const Module &M, const GlobalAlias &GA)
Align emitAlignment(Align Alignment, const GlobalObject *GV=nullptr, unsigned MaxBytesToEmit=0) const
Emit an alignment directive to the specified power of two boundary.
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:113
virtual const MCExpr * lowerConstant(const Constant *CV, const Constant *BaseCV=nullptr, uint64_t Offset=0)
Lower the specified LLVM Constant to an MCExpr.
virtual void emitStartOfAsmFile(Module &)
This virtual method can be overridden by targets that want to emit something at the start of their fi...
Definition AsmPrinter.h:647
unsigned PointerSize
The pointer size in bytes for the default address space.
Definition AsmPrinter.h:119
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
virtual void emitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const
This emits linkage information about GVSym based on GV, if this is supported by the target.
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition AsmPrinter.h:135
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition AsmPrinter.h:105
bool doFinalization(Module &M) override
Shut down the asmprinter.
void emitVisibility(MCSymbol *Sym, unsigned Visibility, bool IsDefinition=true) const
This emits visibility information about symbol, if this is supported by the target.
void emitInt32(int Value) const
Emit a long directive and value.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:110
void preprocessXXStructorList(const DataLayout &DL, const Constant *List, SmallVector< Structor, 8 > &Structors)
This method gathers an array of Structors and then sorts them out by Priority.
const DataLayout & getDataLayout() const
Return information about data layout.
virtual void emitFunctionEntryLabel()
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
This is an important base class in LLVM.
Definition Constant.h:44
const Constant * stripPointerCasts() const
Definition Constant.h:243
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
LLVM_ABI unsigned getPointerSize(unsigned AS=0) const
The pointer representation size in bytes, rounded up to a whole number of bytes.
const Function & getFunction() const
Definition Function.h:167
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:730
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
bool hasLocalLinkage() const
LLVM_ABI const GlobalObject * getAliaseeObject() const
Definition Globals.cpp:521
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:342
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
LLVM_ABI MCSymbol * createTempSymbol()
Create a temporary symbol with a unique name.
LLVM_ABI MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
MCInstBuilder & addReg(MCRegister Reg)
Add a new register operand.
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
MCSymbol * getBeginSymbol()
Definition MCSection.h:653
static const MCSpecifierExpr * create(const MCExpr *Expr, Spec S, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.cpp:743
Generic base class for all target subtargets.
StringRef getExternalName() const
bool isWeak() const
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:213
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
bool hasStackProtectorIndex() const
int64_t getObjectOffset(int ObjectIdx) const
Return the assigned stack offset of the specified object from the incoming stack pointer.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MCContext & getContext() const
Representation of each machine instruction.
LLVM_ABI void setPreInstrSymbol(MachineFunction &MF, MCSymbol *Symbol)
Set a symbol that will be emitted just prior to the instruction itself.
const GlobalValue * getGlobal() const
unsigned getTargetFlags() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
@ MO_GlobalAddress
Address of a global value.
@ MO_ExternalSymbol
Name of external global symbol.
iterator find(const KeyT &Key)
Definition MapVector.h:157
iterator end()
Definition MapVector.h:70
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Wrapper class representing virtual and physical registers.
Definition Register.h:20
StringRef str() const
Explicit conversion to StringRef.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
SystemZAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
const SystemZInstrInfo * getInstrInfo() const override
SystemZCallingConventionRegisters * getSpecialRegisters() const
void emitRenameable(MCSymbol *Sym, bool IsRenamable)
XPLINK64 calling convention specific use registers Particular to z/OS when in 64 bit mode.
void emitGlobalAlias(const Module &M, const GlobalAlias &GA) override
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
SystemZXPLINKAsmPrinter(TargetMachine &TM, std::unique_ptr< MCStreamer > Streamer)
const MCExpr * lowerConstant(const Constant *CV, const Constant *BaseCV=nullptr, uint64_t Offset=0) override
Lower the specified LLVM Constant to an MCExpr.
bool doFinalization(Module &M) override
Shut down the asmprinter.
void emitFunctionBodyEnd() override
Targets can override this to emit stuff after the last basic block in the function.
void emitStartOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the start of their fi...
void emitFunctionEntryLabel() override
EmitFunctionEntryLabel - Emit the label that is the entrypoint for the function.
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
void emitEndOfAsmFile(Module &M) override
This virtual method can be overridden by targets that want to emit something at the end of their file...
void emitXXStructorList(const DataLayout &DL, const Constant *List, bool IsCtor) override
This method emits llvm.global_ctors or llvm.global_dtors list.
Primary interface to the complete machine description for the target machine.
const MCSubtargetInfo & getMCSubtargetInfo() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
Twine concat(const Twine &Suffix) const
Definition Twine.h:497
static Twine utohexstr(uint64_t Val)
Definition Twine.h:385
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Language[]
Key for Kernel::Metadata::mLanguage.
@ Entry
Definition COFF.h:862
@ Swift
Calling convention for Swift.
Definition CallingConv.h:69
LLVM_ABI std::error_code convertToEBCDIC(StringRef Source, SmallVectorImpl< char > &Result)
Converts UTF-8 text containing only code points in the range U+0000 to U+00FF to EBCDIC-1047.
const unsigned GR64Regs[16]
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:694
UtcTime< std::chrono::seconds > toUtcTime(std::time_t T)
Convert a std::time_t to a UtcTime.
Definition Chrono.h:44
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
@ Length
Definition DWP.cpp:577
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
Definition STLExtras.h:1167
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
@ ZOS
z/OS MVS Exception Handling.
Definition CodeGen.h:64
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
@ MCSA_OSLinkage
symbol uses OS linkage (GOFF)
@ MCSA_WeakReference
.weak_reference (MachO)
@ MCSA_IndirectSymbol
.indirect_symbol (MachO)
@ MCSA_Global
.type _foo, @gnu_unique_object
@ MCSA_Extern
.extern (XCOFF)
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:879
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
llvm.global_ctors and llvm.global_dtors are arrays of Structor structs.
Definition AsmPrinter.h:580