1 //===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains a printer that converts from our internal representation
10 // of machine-dependent LLVM code to PowerPC assembly language. This printer is
11 // the output mechanism used by `llc'.
13 // Documentation at http://developer.apple.com/documentation/DeveloperTools/
14 // Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
16 //===----------------------------------------------------------------------===//
18 #include "MCTargetDesc/PPCInstPrinter.h"
19 #include "MCTargetDesc/PPCMCExpr.h"
20 #include "MCTargetDesc/PPCMCTargetDesc.h"
21 #include "MCTargetDesc/PPCPredicates.h"
23 #include "PPCInstrInfo.h"
24 #include "PPCMachineFunctionInfo.h"
25 #include "PPCSubtarget.h"
26 #include "PPCTargetMachine.h"
27 #include "PPCTargetStreamer.h"
28 #include "TargetInfo/PowerPCTargetInfo.h"
29 #include "llvm/ADT/MapVector.h"
30 #include "llvm/ADT/SetVector.h"
31 #include "llvm/ADT/Statistic.h"
32 #include "llvm/ADT/StringExtras.h"
33 #include "llvm/ADT/StringRef.h"
34 #include "llvm/ADT/Twine.h"
35 #include "llvm/BinaryFormat/ELF.h"
36 #include "llvm/CodeGen/AsmPrinter.h"
37 #include "llvm/CodeGen/MachineBasicBlock.h"
38 #include "llvm/CodeGen/MachineFrameInfo.h"
39 #include "llvm/CodeGen/MachineFunction.h"
40 #include "llvm/CodeGen/MachineInstr.h"
41 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
42 #include "llvm/CodeGen/MachineOperand.h"
43 #include "llvm/CodeGen/MachineRegisterInfo.h"
44 #include "llvm/CodeGen/StackMaps.h"
45 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
46 #include "llvm/IR/DataLayout.h"
47 #include "llvm/IR/GlobalValue.h"
48 #include "llvm/IR/GlobalVariable.h"
49 #include "llvm/IR/Module.h"
50 #include "llvm/MC/MCAsmInfo.h"
51 #include "llvm/MC/MCContext.h"
52 #include "llvm/MC/MCDirectives.h"
53 #include "llvm/MC/MCExpr.h"
54 #include "llvm/MC/MCInst.h"
55 #include "llvm/MC/MCInstBuilder.h"
56 #include "llvm/MC/MCSectionELF.h"
57 #include "llvm/MC/MCSectionXCOFF.h"
58 #include "llvm/MC/MCStreamer.h"
59 #include "llvm/MC/MCSymbol.h"
60 #include "llvm/MC/MCSymbolELF.h"
61 #include "llvm/MC/MCSymbolXCOFF.h"
62 #include "llvm/MC/SectionKind.h"
63 #include "llvm/MC/TargetRegistry.h"
64 #include "llvm/Support/Casting.h"
65 #include "llvm/Support/CodeGen.h"
66 #include "llvm/Support/Debug.h"
67 #include "llvm/Support/Error.h"
68 #include "llvm/Support/ErrorHandling.h"
69 #include "llvm/Support/MathExtras.h"
70 #include "llvm/Support/Process.h"
71 #include "llvm/Support/Threading.h"
72 #include "llvm/Support/raw_ostream.h"
73 #include "llvm/Target/TargetMachine.h"
74 #include "llvm/TargetParser/PPCTargetParser.h"
75 #include "llvm/TargetParser/Triple.h"
76 #include "llvm/Transforms/Utils/ModuleUtils.h"
83 using namespace llvm::XCOFF
;
85 #define DEBUG_TYPE "asmprinter"
87 STATISTIC(NumTOCEntries
, "Number of Total TOC Entries Emitted.");
88 STATISTIC(NumTOCConstPool
, "Number of Constant Pool TOC Entries.");
89 STATISTIC(NumTOCGlobalInternal
,
90 "Number of Internal Linkage Global TOC Entries.");
91 STATISTIC(NumTOCGlobalExternal
,
92 "Number of External Linkage Global TOC Entries.");
93 STATISTIC(NumTOCJumpTable
, "Number of Jump Table TOC Entries.");
94 STATISTIC(NumTOCThreadLocal
, "Number of Thread Local TOC Entries.");
95 STATISTIC(NumTOCBlockAddress
, "Number of Block Address TOC Entries.");
96 STATISTIC(NumTOCEHBlock
, "Number of EH Block TOC Entries.");
98 static cl::opt
<bool> EnableSSPCanaryBitInTB(
99 "aix-ssp-tb-bit", cl::init(false),
100 cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden
);
102 // Specialize DenseMapInfo to allow
103 // std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind> in DenseMap.
104 // This specialization is needed here because that type is used as keys in the
105 // map representing TOC entries.
108 struct DenseMapInfo
<std::pair
<const MCSymbol
*, MCSymbolRefExpr::VariantKind
>> {
109 using TOCKey
= std::pair
<const MCSymbol
*, MCSymbolRefExpr::VariantKind
>;
111 static inline TOCKey
getEmptyKey() {
112 return {nullptr, MCSymbolRefExpr::VariantKind::VK_None
};
114 static inline TOCKey
getTombstoneKey() {
115 return {nullptr, MCSymbolRefExpr::VariantKind::VK_Invalid
};
117 static unsigned getHashValue(const TOCKey
&PairVal
) {
118 return detail::combineHashValue(
119 DenseMapInfo
<const MCSymbol
*>::getHashValue(PairVal
.first
),
120 DenseMapInfo
<int>::getHashValue(PairVal
.second
));
122 static bool isEqual(const TOCKey
&A
, const TOCKey
&B
) { return A
== B
; }
124 } // end namespace llvm
129 // GNU attribute tags for PowerPC ABI
130 Tag_GNU_Power_ABI_FP
= 4,
131 Tag_GNU_Power_ABI_Vector
= 8,
132 Tag_GNU_Power_ABI_Struct_Return
= 12,
134 // GNU attribute values for PowerPC float ABI, as combination of two parts
135 Val_GNU_Power_ABI_NoFloat
= 0b00,
136 Val_GNU_Power_ABI_HardFloat_DP
= 0b01,
137 Val_GNU_Power_ABI_SoftFloat_DP
= 0b10,
138 Val_GNU_Power_ABI_HardFloat_SP
= 0b11,
140 Val_GNU_Power_ABI_LDBL_IBM128
= 0b0100,
141 Val_GNU_Power_ABI_LDBL_64
= 0b1000,
142 Val_GNU_Power_ABI_LDBL_IEEE128
= 0b1100,
145 class PPCAsmPrinter
: public AsmPrinter
{
147 // For TLS on AIX, we need to be able to identify TOC entries of specific
148 // VariantKind so we can add the right relocations when we generate the
149 // entries. So each entry is represented by a pair of MCSymbol and
150 // VariantKind. For example, we need to be able to identify the following
151 // entry as a TLSGD entry so we can add the @m relocation:
152 // .tc .i[TC],i[TL]@m
153 // By default, VK_None is used for the VariantKind.
154 MapVector
<std::pair
<const MCSymbol
*, MCSymbolRefExpr::VariantKind
>,
157 const PPCSubtarget
*Subtarget
= nullptr;
159 // Keep track of the number of TLS variables and their corresponding
160 // addresses, which is then used for the assembly printing of
161 // non-TOC-based local-exec variables.
162 MapVector
<const GlobalValue
*, uint64_t> TLSVarsToAddressMapping
;
165 explicit PPCAsmPrinter(TargetMachine
&TM
,
166 std::unique_ptr
<MCStreamer
> Streamer
)
167 : AsmPrinter(TM
, std::move(Streamer
)) {}
169 StringRef
getPassName() const override
{ return "PowerPC Assembly Printer"; }
172 TOCType_ConstantPool
,
173 TOCType_GlobalExternal
,
174 TOCType_GlobalInternal
,
177 TOCType_BlockAddress
,
181 MCSymbol
*lookUpOrCreateTOCEntry(const MCSymbol
*Sym
, TOCEntryType Type
,
182 MCSymbolRefExpr::VariantKind Kind
=
183 MCSymbolRefExpr::VariantKind::VK_None
);
185 bool doInitialization(Module
&M
) override
{
188 return AsmPrinter::doInitialization(M
);
191 void emitInstruction(const MachineInstr
*MI
) override
;
193 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
194 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
195 /// The \p MI would be INLINEASM ONLY.
196 void printOperand(const MachineInstr
*MI
, unsigned OpNo
, raw_ostream
&O
);
198 void PrintSymbolOperand(const MachineOperand
&MO
, raw_ostream
&O
) override
;
199 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
200 const char *ExtraCode
, raw_ostream
&O
) override
;
201 bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
202 const char *ExtraCode
, raw_ostream
&O
) override
;
204 void LowerSTACKMAP(StackMaps
&SM
, const MachineInstr
&MI
);
205 void LowerPATCHPOINT(StackMaps
&SM
, const MachineInstr
&MI
);
206 void EmitTlsCall(const MachineInstr
*MI
, MCSymbolRefExpr::VariantKind VK
);
207 void EmitAIXTlsCallHelper(const MachineInstr
*MI
);
208 const MCExpr
*getAdjustedFasterLocalExpr(const MachineOperand
&MO
,
210 bool runOnMachineFunction(MachineFunction
&MF
) override
{
211 Subtarget
= &MF
.getSubtarget
<PPCSubtarget
>();
212 bool Changed
= AsmPrinter::runOnMachineFunction(MF
);
218 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
219 class PPCLinuxAsmPrinter
: public PPCAsmPrinter
{
221 explicit PPCLinuxAsmPrinter(TargetMachine
&TM
,
222 std::unique_ptr
<MCStreamer
> Streamer
)
223 : PPCAsmPrinter(TM
, std::move(Streamer
)) {}
225 StringRef
getPassName() const override
{
226 return "Linux PPC Assembly Printer";
229 void emitGNUAttributes(Module
&M
);
231 void emitStartOfAsmFile(Module
&M
) override
;
232 void emitEndOfAsmFile(Module
&) override
;
234 void emitFunctionEntryLabel() override
;
236 void emitFunctionBodyStart() override
;
237 void emitFunctionBodyEnd() override
;
238 void emitInstruction(const MachineInstr
*MI
) override
;
241 class PPCAIXAsmPrinter
: public PPCAsmPrinter
{
243 /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern
244 /// linkage for them in AIX.
245 SmallSetVector
<MCSymbol
*, 8> ExtSymSDNodeSymbols
;
247 /// A format indicator and unique trailing identifier to form part of the
248 /// sinit/sterm function names.
249 std::string FormatIndicatorAndUniqueModId
;
251 // Record a list of GlobalAlias associated with a GlobalObject.
252 // This is used for AIX's extra-label-at-definition aliasing strategy.
253 DenseMap
<const GlobalObject
*, SmallVector
<const GlobalAlias
*, 1>>
256 uint16_t getNumberOfVRSaved();
257 void emitTracebackTable();
259 SmallVector
<const GlobalVariable
*, 8> TOCDataGlobalVars
;
261 void emitGlobalVariableHelper(const GlobalVariable
*);
263 // Get the offset of an alias based on its AliaseeObject.
264 uint64_t getAliasOffset(const Constant
*C
);
267 PPCAIXAsmPrinter(TargetMachine
&TM
, std::unique_ptr
<MCStreamer
> Streamer
)
268 : PPCAsmPrinter(TM
, std::move(Streamer
)) {
269 if (MAI
->isLittleEndian())
271 "cannot create AIX PPC Assembly Printer for a little-endian target");
274 StringRef
getPassName() const override
{ return "AIX PPC Assembly Printer"; }
276 bool doInitialization(Module
&M
) override
;
278 void emitXXStructorList(const DataLayout
&DL
, const Constant
*List
,
279 bool IsCtor
) override
;
281 void SetupMachineFunction(MachineFunction
&MF
) override
;
283 void emitGlobalVariable(const GlobalVariable
*GV
) override
;
285 void emitFunctionDescriptor() override
;
287 void emitFunctionEntryLabel() override
;
289 void emitFunctionBodyEnd() override
;
291 void emitPGORefs(Module
&M
);
295 void emitEndOfAsmFile(Module
&) override
;
297 void emitLinkage(const GlobalValue
*GV
, MCSymbol
*GVSym
) const override
;
299 void emitInstruction(const MachineInstr
*MI
) override
;
301 bool doFinalization(Module
&M
) override
;
303 void emitTTypeReference(const GlobalValue
*GV
, unsigned Encoding
) override
;
305 void emitModuleCommandLines(Module
&M
) override
;
308 } // end anonymous namespace
310 void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand
&MO
,
312 // Computing the address of a global symbol, not calling it.
313 const GlobalValue
*GV
= MO
.getGlobal();
314 getSymbol(GV
)->print(O
, MAI
);
315 printOffset(MO
.getOffset(), O
);
318 void PPCAsmPrinter::printOperand(const MachineInstr
*MI
, unsigned OpNo
,
320 const DataLayout
&DL
= getDataLayout();
321 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
323 switch (MO
.getType()) {
324 case MachineOperand::MO_Register
: {
325 // The MI is INLINEASM ONLY and UseVSXReg is always false.
326 const char *RegName
= PPCInstPrinter::getRegisterName(MO
.getReg());
328 // Linux assembler (Others?) does not take register mnemonics.
329 // FIXME - What about special registers used in mfspr/mtspr?
330 O
<< PPC::stripRegisterPrefix(RegName
);
333 case MachineOperand::MO_Immediate
:
337 case MachineOperand::MO_MachineBasicBlock
:
338 MO
.getMBB()->getSymbol()->print(O
, MAI
);
340 case MachineOperand::MO_ConstantPoolIndex
:
341 O
<< DL
.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
344 case MachineOperand::MO_BlockAddress
:
345 GetBlockAddressSymbol(MO
.getBlockAddress())->print(O
, MAI
);
347 case MachineOperand::MO_GlobalAddress
: {
348 PrintSymbolOperand(MO
, O
);
353 O
<< "<unknown operand type: " << (unsigned)MO
.getType() << ">";
358 /// PrintAsmOperand - Print out an operand for an inline asm expression.
360 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
361 const char *ExtraCode
, raw_ostream
&O
) {
362 // Does this asm operand have a single letter operand modifier?
363 if (ExtraCode
&& ExtraCode
[0]) {
364 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
366 switch (ExtraCode
[0]) {
368 // See if this is a generic print operand
369 return AsmPrinter::PrintAsmOperand(MI
, OpNo
, ExtraCode
, O
);
370 case 'L': // Write second word of DImode reference.
371 // Verify that this operand has two consecutive registers.
372 if (!MI
->getOperand(OpNo
).isReg() ||
373 OpNo
+1 == MI
->getNumOperands() ||
374 !MI
->getOperand(OpNo
+1).isReg())
376 ++OpNo
; // Return the high-part.
379 // Write 'i' if an integer constant, otherwise nothing. Used to print
381 if (MI
->getOperand(OpNo
).isImm())
385 if(!MI
->getOperand(OpNo
).isReg())
387 // This operand uses VSX numbering.
388 // If the operand is a VMX register, convert it to a VSX register.
389 Register Reg
= MI
->getOperand(OpNo
).getReg();
390 if (PPC::isVRRegister(Reg
))
391 Reg
= PPC::VSX32
+ (Reg
- PPC::V0
);
392 else if (PPC::isVFRegister(Reg
))
393 Reg
= PPC::VSX32
+ (Reg
- PPC::VF0
);
395 RegName
= PPCInstPrinter::getRegisterName(Reg
);
396 RegName
= PPC::stripRegisterPrefix(RegName
);
402 printOperand(MI
, OpNo
, O
);
406 // At the moment, all inline asm memory operands are a single register.
407 // In any case, the output of this routine should always be just one
408 // assembler operand.
409 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
410 const char *ExtraCode
,
412 if (ExtraCode
&& ExtraCode
[0]) {
413 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
415 switch (ExtraCode
[0]) {
416 default: return true; // Unknown modifier.
417 case 'L': // A memory reference to the upper word of a double word op.
418 O
<< getDataLayout().getPointerSize() << "(";
419 printOperand(MI
, OpNo
, O
);
422 case 'y': // A memory reference for an X-form instruction
424 printOperand(MI
, OpNo
, O
);
427 // Write 'i' if an integer constant, otherwise nothing. Used to print
429 if (MI
->getOperand(OpNo
).isImm())
432 case 'U': // Print 'u' for update form.
433 case 'X': // Print 'x' for indexed form.
434 // FIXME: Currently for PowerPC memory operands are always loaded
435 // into a register, so we never get an update or indexed form.
436 // This is bad even for offset forms, since even if we know we
437 // have a value in -16(r1), we will generate a load into r<n>
438 // and then load from 0(r<n>). Until that issue is fixed,
439 // tolerate 'U' and 'X' but don't output anything.
440 assert(MI
->getOperand(OpNo
).isReg());
445 assert(MI
->getOperand(OpNo
).isReg());
447 printOperand(MI
, OpNo
, O
);
452 static void collectTOCStats(PPCAsmPrinter::TOCEntryType Type
) {
455 case PPCAsmPrinter::TOCType_ConstantPool
:
458 case PPCAsmPrinter::TOCType_GlobalInternal
:
459 ++NumTOCGlobalInternal
;
461 case PPCAsmPrinter::TOCType_GlobalExternal
:
462 ++NumTOCGlobalExternal
;
464 case PPCAsmPrinter::TOCType_JumpTable
:
467 case PPCAsmPrinter::TOCType_ThreadLocal
:
470 case PPCAsmPrinter::TOCType_BlockAddress
:
471 ++NumTOCBlockAddress
;
473 case PPCAsmPrinter::TOCType_EHBlock
:
479 static CodeModel::Model
getCodeModel(const PPCSubtarget
&S
,
480 const TargetMachine
&TM
,
481 const MachineOperand
&MO
) {
482 CodeModel::Model ModuleModel
= TM
.getCodeModel();
484 // If the operand is not a global address then there is no
485 // global variable to carry an attribute.
486 if (!(MO
.getType() == MachineOperand::MO_GlobalAddress
))
489 const GlobalValue
*GV
= MO
.getGlobal();
490 assert(GV
&& "expected global for MO_GlobalAddress");
492 return S
.getCodeModel(TM
, GV
);
495 static void setOptionalCodeModel(MCSymbolXCOFF
*XSym
, CodeModel::Model CM
) {
497 case CodeModel::Large
:
498 XSym
->setPerSymbolCodeModel(MCSymbolXCOFF::CM_Large
);
500 case CodeModel::Small
:
501 XSym
->setPerSymbolCodeModel(MCSymbolXCOFF::CM_Small
);
504 report_fatal_error("Invalid code model for AIX");
508 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
509 /// exists for it. If not, create one. Then return a symbol that references
512 PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol
*Sym
, TOCEntryType Type
,
513 MCSymbolRefExpr::VariantKind Kind
) {
514 // If this is a new TOC entry add statistics about it.
515 if (!TOC
.contains({Sym
, Kind
}))
516 collectTOCStats(Type
);
518 MCSymbol
*&TOCEntry
= TOC
[{Sym
, Kind
}];
520 TOCEntry
= createTempSymbol("C");
524 void PPCAsmPrinter::LowerSTACKMAP(StackMaps
&SM
, const MachineInstr
&MI
) {
525 unsigned NumNOPBytes
= MI
.getOperand(1).getImm();
527 auto &Ctx
= OutStreamer
->getContext();
528 MCSymbol
*MILabel
= Ctx
.createTempSymbol();
529 OutStreamer
->emitLabel(MILabel
);
531 SM
.recordStackMap(*MILabel
, MI
);
532 assert(NumNOPBytes
% 4 == 0 && "Invalid number of NOP bytes requested!");
534 // Scan ahead to trim the shadow.
535 const MachineBasicBlock
&MBB
= *MI
.getParent();
536 MachineBasicBlock::const_iterator
MII(MI
);
538 while (NumNOPBytes
> 0) {
539 if (MII
== MBB
.end() || MII
->isCall() ||
540 MII
->getOpcode() == PPC::DBG_VALUE
||
541 MII
->getOpcode() == TargetOpcode::PATCHPOINT
||
542 MII
->getOpcode() == TargetOpcode::STACKMAP
)
549 for (unsigned i
= 0; i
< NumNOPBytes
; i
+= 4)
550 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
553 // Lower a patchpoint of the form:
554 // [<def>], <id>, <numBytes>, <target>, <numArgs>
555 void PPCAsmPrinter::LowerPATCHPOINT(StackMaps
&SM
, const MachineInstr
&MI
) {
556 auto &Ctx
= OutStreamer
->getContext();
557 MCSymbol
*MILabel
= Ctx
.createTempSymbol();
558 OutStreamer
->emitLabel(MILabel
);
560 SM
.recordPatchPoint(*MILabel
, MI
);
561 PatchPointOpers
Opers(&MI
);
563 unsigned EncodedBytes
= 0;
564 const MachineOperand
&CalleeMO
= Opers
.getCallTarget();
566 if (CalleeMO
.isImm()) {
567 int64_t CallTarget
= CalleeMO
.getImm();
569 assert((CallTarget
& 0xFFFFFFFFFFFF) == CallTarget
&&
570 "High 16 bits of call target should be zero.");
571 Register ScratchReg
= MI
.getOperand(Opers
.getNextScratchIdx()).getReg();
573 // Materialize the jump address:
574 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LI8
)
576 .addImm((CallTarget
>> 32) & 0xFFFF));
578 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::RLDIC
)
581 .addImm(32).addImm(16));
583 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ORIS8
)
586 .addImm((CallTarget
>> 16) & 0xFFFF));
588 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ORI8
)
591 .addImm(CallTarget
& 0xFFFF));
593 // Save the current TOC pointer before the remote call.
594 int TOCSaveOffset
= Subtarget
->getFrameLowering()->getTOCSaveOffset();
595 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::STD
)
597 .addImm(TOCSaveOffset
)
601 // If we're on ELFv1, then we need to load the actual function pointer
602 // from the function descriptor.
603 if (!Subtarget
->isELFv2ABI()) {
604 // Load the new TOC pointer and the function address, but not r11
605 // (needing this is rare, and loading it here would prevent passing it
606 // via a 'nest' parameter.
607 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
610 .addReg(ScratchReg
));
612 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
615 .addReg(ScratchReg
));
619 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MTCTR8
)
620 .addReg(ScratchReg
));
622 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BCTRL8
));
625 // Restore the TOC pointer after the call.
626 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
628 .addImm(TOCSaveOffset
)
632 } else if (CalleeMO
.isGlobal()) {
633 const GlobalValue
*GValue
= CalleeMO
.getGlobal();
634 MCSymbol
*MOSymbol
= getSymbol(GValue
);
635 const MCExpr
*SymVar
= MCSymbolRefExpr::create(MOSymbol
, OutContext
);
637 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BL8_NOP
)
642 // Each instruction is 4 bytes.
646 unsigned NumBytes
= Opers
.getNumPatchBytes();
647 assert(NumBytes
>= EncodedBytes
&&
648 "Patchpoint can't request size less than the length of a call.");
649 assert((NumBytes
- EncodedBytes
) % 4 == 0 &&
650 "Invalid number of NOP bytes requested!");
651 for (unsigned i
= EncodedBytes
; i
< NumBytes
; i
+= 4)
652 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
655 /// This helper function creates the TlsGetAddr/TlsGetMod MCSymbol for AIX. We
656 /// will create the csect and use the qual-name symbol instead of creating just
657 /// the external symbol.
658 static MCSymbol
*createMCSymbolForTlsGetAddr(MCContext
&Ctx
, unsigned MIOpc
) {
662 SymName
= ".__tls_get_addr";
664 case PPC::GETtlsTpointer32AIX
:
665 SymName
= ".__get_tpointer";
667 case PPC::GETtlsMOD32AIX
:
668 case PPC::GETtlsMOD64AIX
:
669 SymName
= ".__tls_get_mod";
673 .getXCOFFSection(SymName
, SectionKind::getText(),
674 XCOFF::CsectProperties(XCOFF::XMC_PR
, XCOFF::XTY_ER
))
675 ->getQualNameSymbol();
678 void PPCAsmPrinter::EmitAIXTlsCallHelper(const MachineInstr
*MI
) {
679 assert(Subtarget
->isAIXABI() &&
680 "Only expecting to emit calls to get the thread pointer on AIX!");
682 MCSymbol
*TlsCall
= createMCSymbolForTlsGetAddr(OutContext
, MI
->getOpcode());
683 const MCExpr
*TlsRef
=
684 MCSymbolRefExpr::create(TlsCall
, MCSymbolRefExpr::VK_None
, OutContext
);
685 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BLA
).addExpr(TlsRef
));
688 /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
689 /// call to __tls_get_addr to the current output stream.
690 void PPCAsmPrinter::EmitTlsCall(const MachineInstr
*MI
,
691 MCSymbolRefExpr::VariantKind VK
) {
692 MCSymbolRefExpr::VariantKind Kind
= MCSymbolRefExpr::VK_None
;
693 unsigned Opcode
= PPC::BL8_NOP_TLS
;
695 assert(MI
->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");
696 if (MI
->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG
||
697 MI
->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG
) {
698 Kind
= MCSymbolRefExpr::VK_PPC_NOTOC
;
699 Opcode
= PPC::BL8_NOTOC_TLS
;
701 const Module
*M
= MF
->getFunction().getParent();
703 assert(MI
->getOperand(0).isReg() &&
704 ((Subtarget
->isPPC64() && MI
->getOperand(0).getReg() == PPC::X3
) ||
705 (!Subtarget
->isPPC64() && MI
->getOperand(0).getReg() == PPC::R3
)) &&
706 "GETtls[ld]ADDR[32] must define GPR3");
707 assert(MI
->getOperand(1).isReg() &&
708 ((Subtarget
->isPPC64() && MI
->getOperand(1).getReg() == PPC::X3
) ||
709 (!Subtarget
->isPPC64() && MI
->getOperand(1).getReg() == PPC::R3
)) &&
710 "GETtls[ld]ADDR[32] must read GPR3");
712 if (Subtarget
->isAIXABI()) {
713 // For TLSGD, the variable offset should already be in R4 and the region
714 // handle should already be in R3. We generate an absolute branch to
715 // .__tls_get_addr. For TLSLD, the module handle should already be in R3.
716 // We generate an absolute branch to .__tls_get_mod.
717 Register VarOffsetReg
= Subtarget
->isPPC64() ? PPC::X4
: PPC::R4
;
719 assert((MI
->getOpcode() == PPC::GETtlsMOD32AIX
||
720 MI
->getOpcode() == PPC::GETtlsMOD64AIX
||
721 (MI
->getOperand(2).isReg() &&
722 MI
->getOperand(2).getReg() == VarOffsetReg
)) &&
723 "GETtls[ld]ADDR[32] must read GPR4");
724 EmitAIXTlsCallHelper(MI
);
728 MCSymbol
*TlsGetAddr
= OutContext
.getOrCreateSymbol("__tls_get_addr");
730 if (Subtarget
->is32BitELFABI() && isPositionIndependent())
731 Kind
= MCSymbolRefExpr::VK_PLT
;
733 const MCExpr
*TlsRef
=
734 MCSymbolRefExpr::create(TlsGetAddr
, Kind
, OutContext
);
736 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
737 if (Kind
== MCSymbolRefExpr::VK_PLT
&& Subtarget
->isSecurePlt() &&
738 M
->getPICLevel() == PICLevel::BigPIC
)
739 TlsRef
= MCBinaryExpr::createAdd(
740 TlsRef
, MCConstantExpr::create(32768, OutContext
), OutContext
);
741 const MachineOperand
&MO
= MI
->getOperand(2);
742 const GlobalValue
*GValue
= MO
.getGlobal();
743 MCSymbol
*MOSymbol
= getSymbol(GValue
);
744 const MCExpr
*SymVar
= MCSymbolRefExpr::create(MOSymbol
, VK
, OutContext
);
745 EmitToStreamer(*OutStreamer
,
746 MCInstBuilder(Subtarget
->isPPC64() ? Opcode
747 : (unsigned)PPC::BL_TLS
)
752 /// Map a machine operand for a TOC pseudo-machine instruction to its
753 /// corresponding MCSymbol.
754 static MCSymbol
*getMCSymbolForTOCPseudoMO(const MachineOperand
&MO
,
756 switch (MO
.getType()) {
757 case MachineOperand::MO_GlobalAddress
:
758 return AP
.getSymbol(MO
.getGlobal());
759 case MachineOperand::MO_ConstantPoolIndex
:
760 return AP
.GetCPISymbol(MO
.getIndex());
761 case MachineOperand::MO_JumpTableIndex
:
762 return AP
.GetJTISymbol(MO
.getIndex());
763 case MachineOperand::MO_BlockAddress
:
764 return AP
.GetBlockAddressSymbol(MO
.getBlockAddress());
766 llvm_unreachable("Unexpected operand type to get symbol.");
770 static PPCAsmPrinter::TOCEntryType
771 getTOCEntryTypeForMO(const MachineOperand
&MO
) {
772 // Use the target flags to determine if this MO is Thread Local.
773 // If we don't do this it comes out as Global.
774 if (PPCInstrInfo::hasTLSFlag(MO
.getTargetFlags()))
775 return PPCAsmPrinter::TOCType_ThreadLocal
;
777 switch (MO
.getType()) {
778 case MachineOperand::MO_GlobalAddress
: {
779 const GlobalValue
*GlobalV
= MO
.getGlobal();
780 GlobalValue::LinkageTypes Linkage
= GlobalV
->getLinkage();
781 if (Linkage
== GlobalValue::ExternalLinkage
||
782 Linkage
== GlobalValue::AvailableExternallyLinkage
||
783 Linkage
== GlobalValue::ExternalWeakLinkage
)
784 return PPCAsmPrinter::TOCType_GlobalExternal
;
786 return PPCAsmPrinter::TOCType_GlobalInternal
;
788 case MachineOperand::MO_ConstantPoolIndex
:
789 return PPCAsmPrinter::TOCType_ConstantPool
;
790 case MachineOperand::MO_JumpTableIndex
:
791 return PPCAsmPrinter::TOCType_JumpTable
;
792 case MachineOperand::MO_BlockAddress
:
793 return PPCAsmPrinter::TOCType_BlockAddress
;
795 llvm_unreachable("Unexpected operand type to get TOC type.");
798 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
799 /// the current output stream.
801 void PPCAsmPrinter::emitInstruction(const MachineInstr
*MI
) {
802 PPC_MC::verifyInstructionPredicates(MI
->getOpcode(),
803 getSubtargetInfo().getFeatureBits());
806 const bool IsPPC64
= Subtarget
->isPPC64();
807 const bool IsAIX
= Subtarget
->isAIXABI();
808 const bool HasAIXSmallLocalTLS
= Subtarget
->hasAIXSmallLocalExecTLS() ||
809 Subtarget
->hasAIXSmallLocalDynamicTLS();
810 const Module
*M
= MF
->getFunction().getParent();
811 PICLevel::Level PL
= M
->getPICLevel();
814 // Validate that SPE and FPU are mutually exclusive in codegen
815 if (!MI
->isInlineAsm()) {
816 for (const MachineOperand
&MO
: MI
->operands()) {
818 Register Reg
= MO
.getReg();
819 if (Subtarget
->hasSPE()) {
820 if (PPC::F4RCRegClass
.contains(Reg
) ||
821 PPC::F8RCRegClass
.contains(Reg
) ||
822 PPC::VFRCRegClass
.contains(Reg
) ||
823 PPC::VRRCRegClass
.contains(Reg
) ||
824 PPC::VSFRCRegClass
.contains(Reg
) ||
825 PPC::VSSRCRegClass
.contains(Reg
)
827 llvm_unreachable("SPE targets cannot have FPRegs!");
829 if (PPC::SPERCRegClass
.contains(Reg
))
830 llvm_unreachable("SPE register found in FPU-targeted code!");
837 auto getTOCRelocAdjustedExprForXCOFF
= [this](const MCExpr
*Expr
,
838 ptrdiff_t OriginalOffset
) {
839 // Apply an offset to the TOC-based expression such that the adjusted
840 // notional offset from the TOC base (to be encoded into the instruction's D
841 // or DS field) is the signed 16-bit truncation of the original notional
842 // offset from the TOC base.
843 // This is consistent with the treatment used both by XL C/C++ and
845 ptrdiff_t Adjustment
=
846 OriginalOffset
- llvm::SignExtend32
<16>(OriginalOffset
);
847 return MCBinaryExpr::createAdd(
848 Expr
, MCConstantExpr::create(-Adjustment
, OutContext
), OutContext
);
851 auto getTOCEntryLoadingExprForXCOFF
=
852 [IsPPC64
, getTOCRelocAdjustedExprForXCOFF
,
853 this](const MCSymbol
*MOSymbol
, const MCExpr
*Expr
,
854 MCSymbolRefExpr::VariantKind VK
=
855 MCSymbolRefExpr::VariantKind::VK_None
) -> const MCExpr
* {
856 const unsigned EntryByteSize
= IsPPC64
? 8 : 4;
857 const auto TOCEntryIter
= TOC
.find({MOSymbol
, VK
});
858 assert(TOCEntryIter
!= TOC
.end() &&
859 "Could not find the TOC entry for this symbol.");
860 const ptrdiff_t EntryDistanceFromTOCBase
=
861 (TOCEntryIter
- TOC
.begin()) * EntryByteSize
;
862 constexpr int16_t PositiveTOCRange
= INT16_MAX
;
864 if (EntryDistanceFromTOCBase
> PositiveTOCRange
)
865 return getTOCRelocAdjustedExprForXCOFF(Expr
, EntryDistanceFromTOCBase
);
869 auto GetVKForMO
= [&](const MachineOperand
&MO
) {
870 // For TLS initial-exec and local-exec accesses on AIX, we have one TOC
871 // entry for the symbol (with the variable offset), which is differentiated
873 unsigned Flag
= MO
.getTargetFlags();
874 if (Flag
== PPCII::MO_TPREL_FLAG
||
875 Flag
== PPCII::MO_GOT_TPREL_PCREL_FLAG
||
876 Flag
== PPCII::MO_TPREL_PCREL_FLAG
) {
877 assert(MO
.isGlobal() && "Only expecting a global MachineOperand here!\n");
878 TLSModel::Model Model
= TM
.getTLSModel(MO
.getGlobal());
879 if (Model
== TLSModel::LocalExec
)
880 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLE
;
881 if (Model
== TLSModel::InitialExec
)
882 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE
;
883 // On AIX, TLS model opt may have turned local-dynamic accesses into
884 // initial-exec accesses.
885 PPCFunctionInfo
*FuncInfo
= MF
->getInfo
<PPCFunctionInfo
>();
886 if (Model
== TLSModel::LocalDynamic
&&
887 FuncInfo
->isAIXFuncUseTLSIEForLD()) {
889 dbgs() << "Current function uses IE access for default LD vars.\n");
890 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSIE
;
892 llvm_unreachable("Only expecting local-exec or initial-exec accesses!");
894 // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
895 // the variable offset and the other for the region handle). They are
896 // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG.
897 if (Flag
== PPCII::MO_TLSGDM_FLAG
)
898 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM
;
899 if (Flag
== PPCII::MO_TLSGD_FLAG
|| Flag
== PPCII::MO_GOT_TLSGD_PCREL_FLAG
)
900 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD
;
901 // For local-dynamic TLS access on AIX, we have one TOC entry for the symbol
902 // (the variable offset) and one shared TOC entry for the module handle.
903 // They are differentiated by MO_TLSLD_FLAG and MO_TLSLDM_FLAG.
904 if (Flag
== PPCII::MO_TLSLD_FLAG
&& IsAIX
)
905 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD
;
906 if (Flag
== PPCII::MO_TLSLDM_FLAG
&& IsAIX
)
907 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSML
;
908 return MCSymbolRefExpr::VariantKind::VK_None
;
911 // Lower multi-instruction pseudo operations.
912 switch (MI
->getOpcode()) {
914 case TargetOpcode::PATCHABLE_FUNCTION_ENTER
: {
915 assert(!Subtarget
->isAIXABI() &&
916 "AIX does not support patchable function entry!");
917 // PATCHABLE_FUNCTION_ENTER on little endian is for XRAY support which is
918 // handled in PPCLinuxAsmPrinter.
919 if (MAI
->isLittleEndian())
921 const Function
&F
= MF
->getFunction();
923 (void)F
.getFnAttribute("patchable-function-entry")
925 .getAsInteger(10, Num
);
931 case TargetOpcode::DBG_VALUE
:
932 llvm_unreachable("Should be handled target independently");
933 case TargetOpcode::STACKMAP
:
934 return LowerSTACKMAP(SM
, *MI
);
935 case TargetOpcode::PATCHPOINT
:
936 return LowerPATCHPOINT(SM
, *MI
);
938 case PPC::MoveGOTtoLR
: {
939 // Transform %lr = MoveGOTtoLR
940 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
941 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
942 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
944 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
945 MCSymbol
*GOTSymbol
=
946 OutContext
.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
947 const MCExpr
*OffsExpr
=
948 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol
,
949 MCSymbolRefExpr::VK_PPC_LOCAL
,
951 MCConstantExpr::create(4, OutContext
),
955 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BL
).addExpr(OffsExpr
));
958 case PPC::MovePCtoLR
:
959 case PPC::MovePCtoLR8
: {
960 // Transform %lr = MovePCtoLR
961 // Into this, where the label is the PIC base:
964 MCSymbol
*PICBase
= MF
->getPICBaseSymbol();
967 EmitToStreamer(*OutStreamer
,
968 MCInstBuilder(PPC::BL
)
969 // FIXME: We would like an efficient form for this, so we
970 // don't have to do a lot of extra uniquing.
971 .addExpr(MCSymbolRefExpr::create(PICBase
, OutContext
)));
974 OutStreamer
->emitLabel(PICBase
);
977 case PPC::UpdateGBR
: {
978 // Transform %rd = UpdateGBR(%rt, %ri)
979 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
981 // or into (if secure plt mode is on):
982 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
983 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
984 // Get the offset from the GOT Base Register to the GOT
985 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
986 if (Subtarget
->isSecurePlt() && isPositionIndependent() ) {
987 unsigned PICR
= TmpInst
.getOperand(0).getReg();
988 MCSymbol
*BaseSymbol
= OutContext
.getOrCreateSymbol(
989 M
->getPICLevel() == PICLevel::SmallPIC
? "_GLOBAL_OFFSET_TABLE_"
992 MCSymbolRefExpr::create(MF
->getPICBaseSymbol(), OutContext
);
994 const MCExpr
*DeltaExpr
= MCBinaryExpr::createSub(
995 MCSymbolRefExpr::create(BaseSymbol
, OutContext
), PB
, OutContext
);
997 const MCExpr
*DeltaHi
= PPCMCExpr::createHa(DeltaExpr
, OutContext
);
1000 MCInstBuilder(PPC::ADDIS
).addReg(PICR
).addReg(PICR
).addExpr(DeltaHi
));
1002 const MCExpr
*DeltaLo
= PPCMCExpr::createLo(DeltaExpr
, OutContext
);
1005 MCInstBuilder(PPC::ADDI
).addReg(PICR
).addReg(PICR
).addExpr(DeltaLo
));
1008 MCSymbol
*PICOffset
=
1009 MF
->getInfo
<PPCFunctionInfo
>()->getPICOffsetSymbol(*MF
);
1010 TmpInst
.setOpcode(PPC::LWZ
);
1012 MCSymbolRefExpr::create(PICOffset
, MCSymbolRefExpr::VK_None
, OutContext
);
1014 MCSymbolRefExpr::create(MF
->getPICBaseSymbol(),
1015 MCSymbolRefExpr::VK_None
,
1017 const MCOperand TR
= TmpInst
.getOperand(1);
1018 const MCOperand PICR
= TmpInst
.getOperand(0);
1020 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
1021 TmpInst
.getOperand(1) =
1022 MCOperand::createExpr(MCBinaryExpr::createSub(Exp
, PB
, OutContext
));
1023 TmpInst
.getOperand(0) = TR
;
1024 TmpInst
.getOperand(2) = PICR
;
1025 EmitToStreamer(*OutStreamer
, TmpInst
);
1027 TmpInst
.setOpcode(PPC::ADD4
);
1028 TmpInst
.getOperand(0) = PICR
;
1029 TmpInst
.getOperand(1) = TR
;
1030 TmpInst
.getOperand(2) = PICR
;
1031 EmitToStreamer(*OutStreamer
, TmpInst
);
1036 // Transform %rN = LWZtoc @op1, %r2
1037 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1039 // Change the opcode to LWZ.
1040 TmpInst
.setOpcode(PPC::LWZ
);
1042 const MachineOperand
&MO
= MI
->getOperand(1);
1043 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
1044 "Invalid operand for LWZtoc.");
1046 // Map the operand to its corresponding MCSymbol.
1047 const MCSymbol
*const MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1049 // Create a reference to the GOT entry for the symbol. The GOT entry will be
1050 // synthesized later.
1051 if (PL
== PICLevel::SmallPIC
&& !IsAIX
) {
1053 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_GOT
,
1055 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1056 EmitToStreamer(*OutStreamer
, TmpInst
);
1060 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1062 // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the
1063 // storage allocated in the TOC which contains the address of
1064 // 'MOSymbol'. Said TOC entry will be synthesized later.
1065 MCSymbol
*TOCEntry
=
1066 lookUpOrCreateTOCEntry(MOSymbol
, getTOCEntryTypeForMO(MO
), VK
);
1068 MCSymbolRefExpr::create(TOCEntry
, MCSymbolRefExpr::VK_None
, OutContext
);
1070 // AIX uses the label directly as the lwz displacement operand for
1071 // references into the toc section. The displacement value will be generated
1072 // relative to the toc-base.
1075 getCodeModel(*Subtarget
, TM
, MO
) == CodeModel::Small
&&
1076 "This pseudo should only be selected for 32-bit small code model.");
1077 Exp
= getTOCEntryLoadingExprForXCOFF(MOSymbol
, Exp
, VK
);
1078 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1080 // Print MO for better readability
1082 OutStreamer
->getCommentOS() << MO
<< '\n';
1083 EmitToStreamer(*OutStreamer
, TmpInst
);
1087 // Create an explicit subtract expression between the local symbol and
1088 // '.LTOC' to manifest the toc-relative offset.
1089 const MCExpr
*PB
= MCSymbolRefExpr::create(
1090 OutContext
.getOrCreateSymbol(Twine(".LTOC")), OutContext
);
1091 Exp
= MCBinaryExpr::createSub(Exp
, PB
, OutContext
);
1092 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1093 EmitToStreamer(*OutStreamer
, TmpInst
);
1097 case PPC::ADDItoc8
: {
1098 assert(IsAIX
&& TM
.getCodeModel() == CodeModel::Small
&&
1099 "PseudoOp only valid for small code model AIX");
1101 // Transform %rN = ADDItoc/8 %r2, @op1.
1102 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1104 // Change the opcode to load address.
1105 TmpInst
.setOpcode((!IsPPC64
) ? (PPC::LA
) : (PPC::LA8
));
1107 const MachineOperand
&MO
= MI
->getOperand(2);
1108 assert(MO
.isGlobal() && "Invalid operand for ADDItoc[8].");
1110 // Map the operand to its corresponding MCSymbol.
1111 const MCSymbol
*const MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1114 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_None
, OutContext
);
1116 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
1117 EmitToStreamer(*OutStreamer
, TmpInst
);
1124 // Transform %x3 = LDtoc @min1, %x2
1125 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1127 // Change the opcode to LD.
1128 TmpInst
.setOpcode(PPC::LD
);
1130 const MachineOperand
&MO
= MI
->getOperand(1);
1131 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
1132 "Invalid operand!");
1134 // Map the operand to its corresponding MCSymbol.
1135 const MCSymbol
*const MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1137 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1139 // Map the machine operand to its corresponding MCSymbol, then map the
1140 // global address operand to be a reference to the TOC entry we will
1141 // synthesize later.
1142 MCSymbol
*TOCEntry
=
1143 lookUpOrCreateTOCEntry(MOSymbol
, getTOCEntryTypeForMO(MO
), VK
);
1145 MCSymbolRefExpr::VariantKind VKExpr
=
1146 IsAIX
? MCSymbolRefExpr::VK_None
: MCSymbolRefExpr::VK_PPC_TOC
;
1147 const MCExpr
*Exp
= MCSymbolRefExpr::create(TOCEntry
, VKExpr
, OutContext
);
1148 TmpInst
.getOperand(1) = MCOperand::createExpr(
1149 IsAIX
? getTOCEntryLoadingExprForXCOFF(MOSymbol
, Exp
, VK
) : Exp
);
1151 // Print MO for better readability
1152 if (isVerbose() && IsAIX
)
1153 OutStreamer
->getCommentOS() << MO
<< '\n';
1154 EmitToStreamer(*OutStreamer
, TmpInst
);
1157 case PPC::ADDIStocHA
: {
1158 const MachineOperand
&MO
= MI
->getOperand(2);
1160 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
1161 "Invalid operand for ADDIStocHA.");
1162 assert((IsAIX
&& !IsPPC64
&&
1163 getCodeModel(*Subtarget
, TM
, MO
) == CodeModel::Large
) &&
1164 "This pseudo should only be selected for 32-bit large code model on"
1167 // Transform %rd = ADDIStocHA %rA, @sym(%r2)
1168 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1170 // Change the opcode to ADDIS.
1171 TmpInst
.setOpcode(PPC::ADDIS
);
1173 // Map the machine operand to its corresponding MCSymbol.
1174 MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1176 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1178 // Map the global address operand to be a reference to the TOC entry we
1179 // will synthesize later. 'TOCEntry' is a label used to reference the
1180 // storage allocated in the TOC which contains the address of 'MOSymbol'.
1181 // If the symbol does not have the toc-data attribute, then we create the
1182 // TOC entry on AIX. If the toc-data attribute is used, the TOC entry
1183 // contains the data rather than the address of the MOSymbol.
1184 if (![](const MachineOperand
&MO
) {
1188 const GlobalVariable
*GV
= dyn_cast
<GlobalVariable
>(MO
.getGlobal());
1191 return GV
->hasAttribute("toc-data");
1193 MOSymbol
= lookUpOrCreateTOCEntry(MOSymbol
, getTOCEntryTypeForMO(MO
), VK
);
1196 const MCExpr
*Exp
= MCSymbolRefExpr::create(
1197 MOSymbol
, MCSymbolRefExpr::VK_PPC_U
, OutContext
);
1198 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
1199 EmitToStreamer(*OutStreamer
, TmpInst
);
1202 case PPC::LWZtocL
: {
1203 const MachineOperand
&MO
= MI
->getOperand(1);
1205 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
1206 "Invalid operand for LWZtocL.");
1207 assert(IsAIX
&& !IsPPC64
&&
1208 getCodeModel(*Subtarget
, TM
, MO
) == CodeModel::Large
&&
1209 "This pseudo should only be selected for 32-bit large code model on"
1212 // Transform %rd = LWZtocL @sym, %rs.
1213 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1215 // Change the opcode to lwz.
1216 TmpInst
.setOpcode(PPC::LWZ
);
1218 // Map the machine operand to its corresponding MCSymbol.
1219 MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1221 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1223 // Always use TOC on AIX. Map the global address operand to be a reference
1224 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
1225 // reference the storage allocated in the TOC which contains the address of
1227 MCSymbol
*TOCEntry
=
1228 lookUpOrCreateTOCEntry(MOSymbol
, getTOCEntryTypeForMO(MO
), VK
);
1229 const MCExpr
*Exp
= MCSymbolRefExpr::create(TOCEntry
,
1230 MCSymbolRefExpr::VK_PPC_L
,
1232 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1233 EmitToStreamer(*OutStreamer
, TmpInst
);
1236 case PPC::ADDIStocHA8
: {
1237 // Transform %xd = ADDIStocHA8 %x2, @sym
1238 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1240 // Change the opcode to ADDIS8. If the global address is the address of
1241 // an external symbol, is a jump table address, is a block address, or is a
1242 // constant pool index with large code model enabled, then generate a TOC
1243 // entry and reference that. Otherwise, reference the symbol directly.
1244 TmpInst
.setOpcode(PPC::ADDIS8
);
1246 const MachineOperand
&MO
= MI
->getOperand(2);
1247 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
1248 "Invalid operand for ADDIStocHA8!");
1250 const MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1252 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1254 const bool GlobalToc
=
1255 MO
.isGlobal() && Subtarget
->isGVIndirectSymbol(MO
.getGlobal());
1257 const CodeModel::Model CM
=
1258 IsAIX
? getCodeModel(*Subtarget
, TM
, MO
) : TM
.getCodeModel();
1260 if (GlobalToc
|| MO
.isJTI() || MO
.isBlockAddress() ||
1261 (MO
.isCPI() && CM
== CodeModel::Large
))
1262 MOSymbol
= lookUpOrCreateTOCEntry(MOSymbol
, getTOCEntryTypeForMO(MO
), VK
);
1264 VK
= IsAIX
? MCSymbolRefExpr::VK_PPC_U
: MCSymbolRefExpr::VK_PPC_TOC_HA
;
1267 MCSymbolRefExpr::create(MOSymbol
, VK
, OutContext
);
1269 if (!MO
.isJTI() && MO
.getOffset())
1270 Exp
= MCBinaryExpr::createAdd(Exp
,
1271 MCConstantExpr::create(MO
.getOffset(),
1275 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
1276 EmitToStreamer(*OutStreamer
, TmpInst
);
1280 // Transform %xd = LDtocL @sym, %xs
1281 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1283 // Change the opcode to LD. If the global address is the address of
1284 // an external symbol, is a jump table address, is a block address, or is
1285 // a constant pool index with large code model enabled, then generate a
1286 // TOC entry and reference that. Otherwise, reference the symbol directly.
1287 TmpInst
.setOpcode(PPC::LD
);
1289 const MachineOperand
&MO
= MI
->getOperand(1);
1290 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() ||
1291 MO
.isBlockAddress()) &&
1292 "Invalid operand for LDtocL!");
1295 (!MO
.isGlobal() || Subtarget
->isGVIndirectSymbol(MO
.getGlobal())) &&
1296 "LDtocL used on symbol that could be accessed directly is "
1297 "invalid. Must match ADDIStocHA8."));
1299 const MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1301 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1302 CodeModel::Model CM
=
1303 IsAIX
? getCodeModel(*Subtarget
, TM
, MO
) : TM
.getCodeModel();
1304 if (!MO
.isCPI() || CM
== CodeModel::Large
)
1305 MOSymbol
= lookUpOrCreateTOCEntry(MOSymbol
, getTOCEntryTypeForMO(MO
), VK
);
1307 VK
= IsAIX
? MCSymbolRefExpr::VK_PPC_L
: MCSymbolRefExpr::VK_PPC_TOC_LO
;
1309 MCSymbolRefExpr::create(MOSymbol
, VK
, OutContext
);
1310 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1311 EmitToStreamer(*OutStreamer
, TmpInst
);
1315 case PPC::ADDItocL8
: {
1316 // Transform %xd = ADDItocL %xs, @sym
1317 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1319 unsigned Op
= MI
->getOpcode();
1321 // Change the opcode to load address for toc-data.
1322 // ADDItocL is only used for 32-bit toc-data on AIX and will always use LA.
1323 TmpInst
.setOpcode(Op
== PPC::ADDItocL8
? (IsAIX
? PPC::LA8
: PPC::ADDI8
)
1326 const MachineOperand
&MO
= MI
->getOperand(2);
1327 assert((Op
== PPC::ADDItocL8
)
1328 ? (MO
.isGlobal() || MO
.isCPI())
1329 : MO
.isGlobal() && "Invalid operand for ADDItocL8.");
1330 assert(!(MO
.isGlobal() && Subtarget
->isGVIndirectSymbol(MO
.getGlobal())) &&
1331 "Interposable definitions must use indirect accesses.");
1333 // Map the operand to its corresponding MCSymbol.
1334 const MCSymbol
*const MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1336 const MCExpr
*Exp
= MCSymbolRefExpr::create(
1338 IsAIX
? MCSymbolRefExpr::VK_PPC_L
: MCSymbolRefExpr::VK_PPC_TOC_LO
,
1341 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
1342 EmitToStreamer(*OutStreamer
, TmpInst
);
1345 case PPC::ADDISgotTprelHA
: {
1346 // Transform: %xd = ADDISgotTprelHA %x2, @sym
1347 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1348 assert(IsPPC64
&& "Not supported for 32-bit PowerPC");
1349 const MachineOperand
&MO
= MI
->getOperand(2);
1350 const GlobalValue
*GValue
= MO
.getGlobal();
1351 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1352 const MCExpr
*SymGotTprel
=
1353 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA
,
1355 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS8
)
1356 .addReg(MI
->getOperand(0).getReg())
1357 .addReg(MI
->getOperand(1).getReg())
1358 .addExpr(SymGotTprel
));
1361 case PPC::LDgotTprelL
:
1362 case PPC::LDgotTprelL32
: {
1363 // Transform %xd = LDgotTprelL @sym, %xs
1364 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1366 // Change the opcode to LD.
1367 TmpInst
.setOpcode(IsPPC64
? PPC::LD
: PPC::LWZ
);
1368 const MachineOperand
&MO
= MI
->getOperand(1);
1369 const GlobalValue
*GValue
= MO
.getGlobal();
1370 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1371 const MCExpr
*Exp
= MCSymbolRefExpr::create(
1372 MOSymbol
, IsPPC64
? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO
1373 : MCSymbolRefExpr::VK_PPC_GOT_TPREL
,
1375 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1376 EmitToStreamer(*OutStreamer
, TmpInst
);
1380 case PPC::PPC32PICGOT
: {
1381 MCSymbol
*GOTSymbol
= OutContext
.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1382 MCSymbol
*GOTRef
= OutContext
.createTempSymbol();
1383 MCSymbol
*NextInstr
= OutContext
.createTempSymbol();
1385 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BL
)
1386 // FIXME: We would like an efficient form for this, so we don't have to do
1387 // a lot of extra uniquing.
1388 .addExpr(MCSymbolRefExpr::create(NextInstr
, OutContext
)));
1389 const MCExpr
*OffsExpr
=
1390 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol
, OutContext
),
1391 MCSymbolRefExpr::create(GOTRef
, OutContext
),
1393 OutStreamer
->emitLabel(GOTRef
);
1394 OutStreamer
->emitValue(OffsExpr
, 4);
1395 OutStreamer
->emitLabel(NextInstr
);
1396 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MFLR
)
1397 .addReg(MI
->getOperand(0).getReg()));
1398 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LWZ
)
1399 .addReg(MI
->getOperand(1).getReg())
1401 .addReg(MI
->getOperand(0).getReg()));
1402 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADD4
)
1403 .addReg(MI
->getOperand(0).getReg())
1404 .addReg(MI
->getOperand(1).getReg())
1405 .addReg(MI
->getOperand(0).getReg()));
1408 case PPC::PPC32GOT
: {
1409 MCSymbol
*GOTSymbol
=
1410 OutContext
.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1411 const MCExpr
*SymGotTlsL
= MCSymbolRefExpr::create(
1412 GOTSymbol
, MCSymbolRefExpr::VK_PPC_LO
, OutContext
);
1413 const MCExpr
*SymGotTlsHA
= MCSymbolRefExpr::create(
1414 GOTSymbol
, MCSymbolRefExpr::VK_PPC_HA
, OutContext
);
1415 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LI
)
1416 .addReg(MI
->getOperand(0).getReg())
1417 .addExpr(SymGotTlsL
));
1418 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS
)
1419 .addReg(MI
->getOperand(0).getReg())
1420 .addReg(MI
->getOperand(0).getReg())
1421 .addExpr(SymGotTlsHA
));
1424 case PPC::ADDIStlsgdHA
: {
1425 // Transform: %xd = ADDIStlsgdHA %x2, @sym
1426 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1427 assert(IsPPC64
&& "Not supported for 32-bit PowerPC");
1428 const MachineOperand
&MO
= MI
->getOperand(2);
1429 const GlobalValue
*GValue
= MO
.getGlobal();
1430 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1431 const MCExpr
*SymGotTlsGD
=
1432 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA
,
1434 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS8
)
1435 .addReg(MI
->getOperand(0).getReg())
1436 .addReg(MI
->getOperand(1).getReg())
1437 .addExpr(SymGotTlsGD
));
1440 case PPC::ADDItlsgdL
:
1441 // Transform: %xd = ADDItlsgdL %xs, @sym
1442 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
1443 case PPC::ADDItlsgdL32
: {
1444 // Transform: %rd = ADDItlsgdL32 %rs, @sym
1445 // Into: %rd = ADDI %rs, sym@got@tlsgd
1446 const MachineOperand
&MO
= MI
->getOperand(2);
1447 const GlobalValue
*GValue
= MO
.getGlobal();
1448 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1449 const MCExpr
*SymGotTlsGD
= MCSymbolRefExpr::create(
1450 MOSymbol
, IsPPC64
? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
1451 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD
,
1453 EmitToStreamer(*OutStreamer
,
1454 MCInstBuilder(IsPPC64
? PPC::ADDI8
: PPC::ADDI
)
1455 .addReg(MI
->getOperand(0).getReg())
1456 .addReg(MI
->getOperand(1).getReg())
1457 .addExpr(SymGotTlsGD
));
1460 case PPC::GETtlsMOD32AIX
:
1461 case PPC::GETtlsMOD64AIX
:
1462 // Transform: %r3 = GETtlsMODNNAIX %r3 (for NN == 32/64).
1463 // Into: BLA .__tls_get_mod()
1464 // Input parameter is a module handle (_$TLSML[TC]@ml) for all variables.
1465 case PPC::GETtlsADDR
:
1466 // Transform: %x3 = GETtlsADDR %x3, @sym
1467 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
1468 case PPC::GETtlsADDRPCREL
:
1469 case PPC::GETtlsADDR32AIX
:
1470 case PPC::GETtlsADDR64AIX
:
1471 // Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64).
1472 // Into: BLA .__tls_get_addr()
1473 // Unlike on Linux, there is no symbol or relocation needed for this call.
1474 case PPC::GETtlsADDR32
: {
1475 // Transform: %r3 = GETtlsADDR32 %r3, @sym
1476 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
1477 EmitTlsCall(MI
, MCSymbolRefExpr::VK_PPC_TLSGD
);
1480 case PPC::GETtlsTpointer32AIX
: {
1481 // Transform: %r3 = GETtlsTpointer32AIX
1482 // Into: BLA .__get_tpointer()
1483 EmitAIXTlsCallHelper(MI
);
1486 case PPC::ADDIStlsldHA
: {
1487 // Transform: %xd = ADDIStlsldHA %x2, @sym
1488 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
1489 assert(IsPPC64
&& "Not supported for 32-bit PowerPC");
1490 const MachineOperand
&MO
= MI
->getOperand(2);
1491 const GlobalValue
*GValue
= MO
.getGlobal();
1492 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1493 const MCExpr
*SymGotTlsLD
=
1494 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA
,
1496 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS8
)
1497 .addReg(MI
->getOperand(0).getReg())
1498 .addReg(MI
->getOperand(1).getReg())
1499 .addExpr(SymGotTlsLD
));
1502 case PPC::ADDItlsldL
:
1503 // Transform: %xd = ADDItlsldL %xs, @sym
1504 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
1505 case PPC::ADDItlsldL32
: {
1506 // Transform: %rd = ADDItlsldL32 %rs, @sym
1507 // Into: %rd = ADDI %rs, sym@got@tlsld
1508 const MachineOperand
&MO
= MI
->getOperand(2);
1509 const GlobalValue
*GValue
= MO
.getGlobal();
1510 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1511 const MCExpr
*SymGotTlsLD
= MCSymbolRefExpr::create(
1512 MOSymbol
, IsPPC64
? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
1513 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD
,
1515 EmitToStreamer(*OutStreamer
,
1516 MCInstBuilder(IsPPC64
? PPC::ADDI8
: PPC::ADDI
)
1517 .addReg(MI
->getOperand(0).getReg())
1518 .addReg(MI
->getOperand(1).getReg())
1519 .addExpr(SymGotTlsLD
));
1522 case PPC::GETtlsldADDR
:
1523 // Transform: %x3 = GETtlsldADDR %x3, @sym
1524 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
1525 case PPC::GETtlsldADDRPCREL
:
1526 case PPC::GETtlsldADDR32
: {
1527 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
1528 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
1529 EmitTlsCall(MI
, MCSymbolRefExpr::VK_PPC_TLSLD
);
1532 case PPC::ADDISdtprelHA
:
1533 // Transform: %xd = ADDISdtprelHA %xs, @sym
1534 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1535 case PPC::ADDISdtprelHA32
: {
1536 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1537 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1538 const MachineOperand
&MO
= MI
->getOperand(2);
1539 const GlobalValue
*GValue
= MO
.getGlobal();
1540 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1541 const MCExpr
*SymDtprel
=
1542 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_DTPREL_HA
,
1546 MCInstBuilder(IsPPC64
? PPC::ADDIS8
: PPC::ADDIS
)
1547 .addReg(MI
->getOperand(0).getReg())
1548 .addReg(MI
->getOperand(1).getReg())
1549 .addExpr(SymDtprel
));
1552 case PPC::PADDIdtprel
: {
1553 // Transform: %rd = PADDIdtprel %rs, @sym
1554 // Into: %rd = PADDI8 %rs, sym@dtprel
1555 const MachineOperand
&MO
= MI
->getOperand(2);
1556 const GlobalValue
*GValue
= MO
.getGlobal();
1557 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1558 const MCExpr
*SymDtprel
= MCSymbolRefExpr::create(
1559 MOSymbol
, MCSymbolRefExpr::VK_DTPREL
, OutContext
);
1560 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::PADDI8
)
1561 .addReg(MI
->getOperand(0).getReg())
1562 .addReg(MI
->getOperand(1).getReg())
1563 .addExpr(SymDtprel
));
1567 case PPC::ADDIdtprelL
:
1568 // Transform: %xd = ADDIdtprelL %xs, @sym
1569 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1570 case PPC::ADDIdtprelL32
: {
1571 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1572 // Into: %rd = ADDI %rs, sym@dtprel@l
1573 const MachineOperand
&MO
= MI
->getOperand(2);
1574 const GlobalValue
*GValue
= MO
.getGlobal();
1575 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1576 const MCExpr
*SymDtprel
=
1577 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_DTPREL_LO
,
1579 EmitToStreamer(*OutStreamer
,
1580 MCInstBuilder(IsPPC64
? PPC::ADDI8
: PPC::ADDI
)
1581 .addReg(MI
->getOperand(0).getReg())
1582 .addReg(MI
->getOperand(1).getReg())
1583 .addExpr(SymDtprel
));
1588 if (!Subtarget
->hasMFOCRF()) {
1589 // Transform: %r3 = MFOCRF %cr7
1590 // Into: %r3 = MFCR ;; cr7
1591 unsigned NewOpcode
=
1592 MI
->getOpcode() == PPC::MFOCRF
? PPC::MFCR
: PPC::MFCR8
;
1593 OutStreamer
->AddComment(PPCInstPrinter::
1594 getRegisterName(MI
->getOperand(1).getReg()));
1595 EmitToStreamer(*OutStreamer
, MCInstBuilder(NewOpcode
)
1596 .addReg(MI
->getOperand(0).getReg()));
1602 if (!Subtarget
->hasMFOCRF()) {
1603 // Transform: %cr7 = MTOCRF %r3
1604 // Into: MTCRF mask, %r3 ;; cr7
1605 unsigned NewOpcode
=
1606 MI
->getOpcode() == PPC::MTOCRF
? PPC::MTCRF
: PPC::MTCRF8
;
1607 unsigned Mask
= 0x80 >> OutContext
.getRegisterInfo()
1608 ->getEncodingValue(MI
->getOperand(0).getReg());
1609 OutStreamer
->AddComment(PPCInstPrinter::
1610 getRegisterName(MI
->getOperand(0).getReg()));
1611 EmitToStreamer(*OutStreamer
, MCInstBuilder(NewOpcode
)
1613 .addReg(MI
->getOperand(1).getReg()));
1621 // Verify alignment is legal, so we don't create relocations
1622 // that can't be supported.
1623 unsigned OpNum
= (MI
->getOpcode() == PPC::STD
) ? 2 : 1;
1624 // For non-TOC-based local-exec TLS accesses with non-zero offsets, the
1625 // machine operand (which is a TargetGlobalTLSAddress) is expected to be
1626 // the same operand for both loads and stores.
1627 for (const MachineOperand
&TempMO
: MI
->operands()) {
1628 if (((TempMO
.getTargetFlags() == PPCII::MO_TPREL_FLAG
||
1629 TempMO
.getTargetFlags() == PPCII::MO_TLSLD_FLAG
)) &&
1630 TempMO
.getOperandNo() == 1)
1633 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
1634 if (MO
.isGlobal()) {
1635 const DataLayout
&DL
= MO
.getGlobal()->getDataLayout();
1636 if (MO
.getGlobal()->getPointerAlignment(DL
) < 4)
1637 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1639 // As these load/stores share common code with the following load/stores,
1640 // fall through to the subsequent cases in order to either process the
1641 // non-TOC-based local-exec sequence or to process the instruction normally.
1663 // A faster non-TOC-based local-[exec|dynamic] sequence is represented by
1664 // `addi` or a load/store instruction (that directly loads or stores off of
1665 // the thread pointer) with an immediate operand having the
1666 // [MO_TPREL_FLAG|MO_TLSLD_FLAG]. Such instructions do not otherwise arise.
1667 if (!HasAIXSmallLocalTLS
)
1669 bool IsMIADDI8
= MI
->getOpcode() == PPC::ADDI8
;
1670 unsigned OpNum
= IsMIADDI8
? 2 : 1;
1671 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
1672 unsigned Flag
= MO
.getTargetFlags();
1673 if (Flag
== PPCII::MO_TPREL_FLAG
||
1674 Flag
== PPCII::MO_GOT_TPREL_PCREL_FLAG
||
1675 Flag
== PPCII::MO_TPREL_PCREL_FLAG
|| Flag
== PPCII::MO_TLSLD_FLAG
) {
1676 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1678 const MCExpr
*Expr
= getAdjustedFasterLocalExpr(MO
, MO
.getOffset());
1680 TmpInst
.getOperand(OpNum
) = MCOperand::createExpr(Expr
);
1682 // Change the opcode to load address if the original opcode is an `addi`.
1684 TmpInst
.setOpcode(PPC::LA8
);
1686 EmitToStreamer(*OutStreamer
, TmpInst
);
1689 // Now process the instruction normally.
1692 case PPC::PseudoEIEIO
: {
1695 MCInstBuilder(PPC::ORI
).addReg(PPC::X2
).addReg(PPC::X2
).addImm(0));
1698 MCInstBuilder(PPC::ORI
).addReg(PPC::X2
).addReg(PPC::X2
).addImm(0));
1699 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::EnforceIEIO
));
1704 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1705 EmitToStreamer(*OutStreamer
, TmpInst
);
1708 // For non-TOC-based local-[exec|dynamic] variables that have a non-zero offset,
1709 // we need to create a new MCExpr that adds the non-zero offset to the address
1710 // of the local-[exec|dynamic] variable that will be used in either an addi,
1711 // load or store. However, the final displacement for these instructions must be
1712 // between [-32768, 32768), so if the TLS address + its non-zero offset is
1713 // greater than 32KB, a new MCExpr is produced to accommodate this situation.
1715 PPCAsmPrinter::getAdjustedFasterLocalExpr(const MachineOperand
&MO
,
1717 // Non-zero offsets (for loads, stores or `addi`) require additional handling.
1718 // When the offset is zero, there is no need to create an adjusted MCExpr.
1722 assert(MO
.isGlobal() && "Only expecting a global MachineOperand here!");
1723 const GlobalValue
*GValue
= MO
.getGlobal();
1724 TLSModel::Model Model
= TM
.getTLSModel(GValue
);
1725 assert((Model
== TLSModel::LocalExec
|| Model
== TLSModel::LocalDynamic
) &&
1726 "Only local-[exec|dynamic] accesses are handled!");
1728 bool IsGlobalADeclaration
= GValue
->isDeclarationForLinker();
1729 // Find the GlobalVariable that corresponds to the particular TLS variable
1730 // in the TLS variable-to-address mapping. All TLS variables should exist
1731 // within this map, with the exception of TLS variables marked as extern.
1732 const auto TLSVarsMapEntryIter
= TLSVarsToAddressMapping
.find(GValue
);
1733 if (TLSVarsMapEntryIter
== TLSVarsToAddressMapping
.end())
1734 assert(IsGlobalADeclaration
&&
1735 "Only expecting to find extern TLS variables not present in the TLS "
1736 "variable-to-address map!");
1738 unsigned TLSVarAddress
=
1739 IsGlobalADeclaration
? 0 : TLSVarsMapEntryIter
->second
;
1740 ptrdiff_t FinalAddress
= (TLSVarAddress
+ Offset
);
1741 // If the address of the TLS variable + the offset is less than 32KB,
1742 // or if the TLS variable is extern, we simply produce an MCExpr to add the
1743 // non-zero offset to the TLS variable address.
1744 // For when TLS variables are extern, this is safe to do because we can
1745 // assume that the address of extern TLS variables are zero.
1746 const MCExpr
*Expr
= MCSymbolRefExpr::create(
1748 Model
== TLSModel::LocalExec
? MCSymbolRefExpr::VK_PPC_AIX_TLSLE
1749 : MCSymbolRefExpr::VK_PPC_AIX_TLSLD
,
1751 Expr
= MCBinaryExpr::createAdd(
1752 Expr
, MCConstantExpr::create(Offset
, OutContext
), OutContext
);
1753 if (FinalAddress
>= 32768) {
1754 // Handle the written offset for cases where:
1755 // TLS variable address + Offset > 32KB.
1757 // The assembly that is printed will look like:
1758 // TLSVar@le + Offset - Delta
1759 // where Delta is a multiple of 64KB: ((FinalAddress + 32768) & ~0xFFFF).
1760 ptrdiff_t Delta
= ((FinalAddress
+ 32768) & ~0xFFFF);
1761 // Check that the total instruction displacement fits within [-32768,32768).
1762 [[maybe_unused
]] ptrdiff_t InstDisp
= TLSVarAddress
+ Offset
- Delta
;
1764 ((InstDisp
< 32768) && (InstDisp
>= -32768)) &&
1765 "Expecting the instruction displacement for local-[exec|dynamic] TLS "
1766 "variables to be between [-32768, 32768)!");
1767 Expr
= MCBinaryExpr::createAdd(
1768 Expr
, MCConstantExpr::create(-Delta
, OutContext
), OutContext
);
1774 void PPCLinuxAsmPrinter::emitGNUAttributes(Module
&M
) {
1775 // Emit float ABI into GNU attribute
1776 Metadata
*MD
= M
.getModuleFlag("float-abi");
1777 MDString
*FloatABI
= dyn_cast_or_null
<MDString
>(MD
);
1780 StringRef flt
= FloatABI
->getString();
1781 // TODO: Support emitting soft-fp and hard double/single attributes.
1782 if (flt
== "doubledouble")
1783 OutStreamer
->emitGNUAttribute(Tag_GNU_Power_ABI_FP
,
1784 Val_GNU_Power_ABI_HardFloat_DP
|
1785 Val_GNU_Power_ABI_LDBL_IBM128
);
1786 else if (flt
== "ieeequad")
1787 OutStreamer
->emitGNUAttribute(Tag_GNU_Power_ABI_FP
,
1788 Val_GNU_Power_ABI_HardFloat_DP
|
1789 Val_GNU_Power_ABI_LDBL_IEEE128
);
1790 else if (flt
== "ieeedouble")
1791 OutStreamer
->emitGNUAttribute(Tag_GNU_Power_ABI_FP
,
1792 Val_GNU_Power_ABI_HardFloat_DP
|
1793 Val_GNU_Power_ABI_LDBL_64
);
1796 void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr
*MI
) {
1797 if (!Subtarget
->isPPC64())
1798 return PPCAsmPrinter::emitInstruction(MI
);
1800 switch (MI
->getOpcode()) {
1803 case TargetOpcode::PATCHABLE_FUNCTION_ENTER
: {
1805 // b .end # lis 0, FuncId[16..32]
1806 // nop # li 0, FuncId[0..15]
1809 // bl __xray_FunctionEntry
1813 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1814 // of instructions change.
1815 // XRAY is only supported on PPC Linux little endian.
1816 if (!MAI
->isLittleEndian())
1818 MCSymbol
*BeginOfSled
= OutContext
.createTempSymbol();
1819 MCSymbol
*EndOfSled
= OutContext
.createTempSymbol();
1820 OutStreamer
->emitLabel(BeginOfSled
);
1821 EmitToStreamer(*OutStreamer
,
1822 MCInstBuilder(PPC::B
).addExpr(
1823 MCSymbolRefExpr::create(EndOfSled
, OutContext
)));
1824 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
1827 MCInstBuilder(PPC::STD
).addReg(PPC::X0
).addImm(-8).addReg(PPC::X1
));
1828 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MFLR8
).addReg(PPC::X0
));
1829 EmitToStreamer(*OutStreamer
,
1830 MCInstBuilder(PPC::BL8_NOP
)
1831 .addExpr(MCSymbolRefExpr::create(
1832 OutContext
.getOrCreateSymbol("__xray_FunctionEntry"),
1834 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MTLR8
).addReg(PPC::X0
));
1835 OutStreamer
->emitLabel(EndOfSled
);
1836 recordSled(BeginOfSled
, *MI
, SledKind::FUNCTION_ENTER
, 2);
1839 case TargetOpcode::PATCHABLE_RET
: {
1840 unsigned RetOpcode
= MI
->getOperand(0).getImm();
1842 RetInst
.setOpcode(RetOpcode
);
1843 for (const auto &MO
: llvm::drop_begin(MI
->operands())) {
1845 if (LowerPPCMachineOperandToMCOperand(MO
, MCOp
, *this))
1846 RetInst
.addOperand(MCOp
);
1850 if (RetOpcode
== PPC::BCCLR
) {
1851 IsConditional
= true;
1852 } else if (RetOpcode
== PPC::TCRETURNdi8
|| RetOpcode
== PPC::TCRETURNri8
||
1853 RetOpcode
== PPC::TCRETURNai8
) {
1855 } else if (RetOpcode
== PPC::BLR8
|| RetOpcode
== PPC::TAILB8
) {
1856 IsConditional
= false;
1858 EmitToStreamer(*OutStreamer
, RetInst
);
1862 MCSymbol
*FallthroughLabel
;
1863 if (IsConditional
) {
1871 // blr # lis 0, FuncId[16..32]
1872 // nop # li 0, FuncId[0..15]
1875 // bl __xray_FunctionExit
1880 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1881 // of instructions change.
1882 FallthroughLabel
= OutContext
.createTempSymbol();
1885 MCInstBuilder(PPC::BCC
)
1886 .addImm(PPC::InvertPredicate(
1887 static_cast<PPC::Predicate
>(MI
->getOperand(1).getImm())))
1888 .addReg(MI
->getOperand(2).getReg())
1889 .addExpr(MCSymbolRefExpr::create(FallthroughLabel
, OutContext
)));
1891 RetInst
.setOpcode(PPC::BLR8
);
1895 // b(lr)? # lis 0, FuncId[16..32]
1896 // nop # li 0, FuncId[0..15]
1899 // bl __xray_FunctionExit
1903 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1904 // of instructions change.
1905 OutStreamer
->emitCodeAlignment(Align(8), &getSubtargetInfo());
1906 MCSymbol
*BeginOfSled
= OutContext
.createTempSymbol();
1907 OutStreamer
->emitLabel(BeginOfSled
);
1908 EmitToStreamer(*OutStreamer
, RetInst
);
1909 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
1912 MCInstBuilder(PPC::STD
).addReg(PPC::X0
).addImm(-8).addReg(PPC::X1
));
1913 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MFLR8
).addReg(PPC::X0
));
1914 EmitToStreamer(*OutStreamer
,
1915 MCInstBuilder(PPC::BL8_NOP
)
1916 .addExpr(MCSymbolRefExpr::create(
1917 OutContext
.getOrCreateSymbol("__xray_FunctionExit"),
1919 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MTLR8
).addReg(PPC::X0
));
1920 EmitToStreamer(*OutStreamer
, RetInst
);
1922 OutStreamer
->emitLabel(FallthroughLabel
);
1923 recordSled(BeginOfSled
, *MI
, SledKind::FUNCTION_EXIT
, 2);
1926 case TargetOpcode::PATCHABLE_FUNCTION_EXIT
:
1927 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
1928 case TargetOpcode::PATCHABLE_TAIL_CALL
:
1929 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1930 // normal function exit from a tail exit.
1931 llvm_unreachable("Tail call is handled in the normal case. See comments "
1932 "around this assert.");
1934 return PPCAsmPrinter::emitInstruction(MI
);
1937 void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module
&M
) {
1938 if (static_cast<const PPCTargetMachine
&>(TM
).isELFv2ABI()) {
1939 PPCTargetStreamer
*TS
=
1940 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
1941 TS
->emitAbiVersion(2);
1944 if (static_cast<const PPCTargetMachine
&>(TM
).isPPC64() ||
1945 !isPositionIndependent())
1946 return AsmPrinter::emitStartOfAsmFile(M
);
1948 if (M
.getPICLevel() == PICLevel::SmallPIC
)
1949 return AsmPrinter::emitStartOfAsmFile(M
);
1951 OutStreamer
->switchSection(OutContext
.getELFSection(
1952 ".got2", ELF::SHT_PROGBITS
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
));
1954 MCSymbol
*TOCSym
= OutContext
.getOrCreateSymbol(Twine(".LTOC"));
1955 MCSymbol
*CurrentPos
= OutContext
.createTempSymbol();
1957 OutStreamer
->emitLabel(CurrentPos
);
1959 // The GOT pointer points to the middle of the GOT, in order to reference the
1960 // entire 64kB range. 0x8000 is the midpoint.
1961 const MCExpr
*tocExpr
=
1962 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos
, OutContext
),
1963 MCConstantExpr::create(0x8000, OutContext
),
1966 OutStreamer
->emitAssignment(TOCSym
, tocExpr
);
1968 OutStreamer
->switchSection(getObjFileLowering().getTextSection());
1971 void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1972 // linux/ppc32 - Normal entry label.
1973 if (!Subtarget
->isPPC64() &&
1974 (!isPositionIndependent() ||
1975 MF
->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC
))
1976 return AsmPrinter::emitFunctionEntryLabel();
1978 if (!Subtarget
->isPPC64()) {
1979 const PPCFunctionInfo
*PPCFI
= MF
->getInfo
<PPCFunctionInfo
>();
1980 if (PPCFI
->usesPICBase() && !Subtarget
->isSecurePlt()) {
1981 MCSymbol
*RelocSymbol
= PPCFI
->getPICOffsetSymbol(*MF
);
1982 MCSymbol
*PICBase
= MF
->getPICBaseSymbol();
1983 OutStreamer
->emitLabel(RelocSymbol
);
1985 const MCExpr
*OffsExpr
=
1986 MCBinaryExpr::createSub(
1987 MCSymbolRefExpr::create(OutContext
.getOrCreateSymbol(Twine(".LTOC")),
1989 MCSymbolRefExpr::create(PICBase
, OutContext
),
1991 OutStreamer
->emitValue(OffsExpr
, 4);
1992 OutStreamer
->emitLabel(CurrentFnSym
);
1995 return AsmPrinter::emitFunctionEntryLabel();
1998 // ELFv2 ABI - Normal entry label.
1999 if (Subtarget
->isELFv2ABI()) {
2000 // In the Large code model, we allow arbitrary displacements between
2001 // the text section and its associated TOC section. We place the
2002 // full 8-byte offset to the TOC in memory immediately preceding
2003 // the function global entry point.
2004 if (TM
.getCodeModel() == CodeModel::Large
2005 && !MF
->getRegInfo().use_empty(PPC::X2
)) {
2006 const PPCFunctionInfo
*PPCFI
= MF
->getInfo
<PPCFunctionInfo
>();
2008 MCSymbol
*TOCSymbol
= OutContext
.getOrCreateSymbol(StringRef(".TOC."));
2009 MCSymbol
*GlobalEPSymbol
= PPCFI
->getGlobalEPSymbol(*MF
);
2010 const MCExpr
*TOCDeltaExpr
=
2011 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol
, OutContext
),
2012 MCSymbolRefExpr::create(GlobalEPSymbol
,
2016 OutStreamer
->emitLabel(PPCFI
->getTOCOffsetSymbol(*MF
));
2017 OutStreamer
->emitValue(TOCDeltaExpr
, 8);
2019 return AsmPrinter::emitFunctionEntryLabel();
2022 // Emit an official procedure descriptor.
2023 MCSectionSubPair Current
= OutStreamer
->getCurrentSection();
2024 MCSectionELF
*Section
= OutStreamer
->getContext().getELFSection(
2025 ".opd", ELF::SHT_PROGBITS
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
);
2026 OutStreamer
->switchSection(Section
);
2027 OutStreamer
->emitLabel(CurrentFnSym
);
2028 OutStreamer
->emitValueToAlignment(Align(8));
2029 MCSymbol
*Symbol1
= CurrentFnSymForSize
;
2030 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
2032 OutStreamer
->emitValue(MCSymbolRefExpr::create(Symbol1
, OutContext
),
2034 MCSymbol
*Symbol2
= OutContext
.getOrCreateSymbol(StringRef(".TOC."));
2035 // Generates a R_PPC64_TOC relocation for TOC base insertion.
2036 OutStreamer
->emitValue(
2037 MCSymbolRefExpr::create(Symbol2
, MCSymbolRefExpr::VK_PPC_TOCBASE
, OutContext
),
2039 // Emit a null environment pointer.
2040 OutStreamer
->emitIntValue(0, 8 /* size */);
2041 OutStreamer
->switchSection(Current
.first
, Current
.second
);
2044 void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module
&M
) {
2045 const DataLayout
&DL
= getDataLayout();
2047 bool isPPC64
= DL
.getPointerSizeInBits() == 64;
2049 PPCTargetStreamer
*TS
=
2050 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
2052 // If we are using any values provided by Glibc at fixed addresses,
2053 // we need to ensure that the Glibc used at link time actually provides
2054 // those values. All versions of Glibc that do will define the symbol
2055 // named "__parse_hwcap_and_convert_at_platform".
2056 if (static_cast<const PPCTargetMachine
&>(TM
).hasGlibcHWCAPAccess())
2057 OutStreamer
->emitSymbolValue(
2058 GetExternalSymbolSymbol("__parse_hwcap_and_convert_at_platform"),
2059 MAI
->getCodePointerSize());
2060 emitGNUAttributes(M
);
2063 const char *Name
= isPPC64
? ".toc" : ".got2";
2064 MCSectionELF
*Section
= OutContext
.getELFSection(
2065 Name
, ELF::SHT_PROGBITS
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
);
2066 OutStreamer
->switchSection(Section
);
2068 OutStreamer
->emitValueToAlignment(Align(4));
2070 for (const auto &TOCMapPair
: TOC
) {
2071 const MCSymbol
*const TOCEntryTarget
= TOCMapPair
.first
.first
;
2072 MCSymbol
*const TOCEntryLabel
= TOCMapPair
.second
;
2074 OutStreamer
->emitLabel(TOCEntryLabel
);
2076 TS
->emitTCEntry(*TOCEntryTarget
, TOCMapPair
.first
.second
);
2078 OutStreamer
->emitSymbolValue(TOCEntryTarget
, 4);
2082 PPCAsmPrinter::emitEndOfAsmFile(M
);
2085 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
2086 void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
2087 // In the ELFv2 ABI, in functions that use the TOC register, we need to
2088 // provide two entry points. The ABI guarantees that when calling the
2089 // local entry point, r2 is set up by the caller to contain the TOC base
2090 // for this function, and when calling the global entry point, r12 is set
2091 // up by the caller to hold the address of the global entry point. We
2092 // thus emit a prefix sequence along the following lines:
2096 // # global entry point
2097 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
2098 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
2100 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
2101 // # local entry point, followed by function body
2103 // For the Large code model, we create
2106 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
2109 // # global entry point
2110 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
2113 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
2114 // # local entry point, followed by function body
2116 // This ensures we have r2 set up correctly while executing the function
2117 // body, no matter which entry point is called.
2118 const PPCFunctionInfo
*PPCFI
= MF
->getInfo
<PPCFunctionInfo
>();
2119 const bool UsesX2OrR2
= !MF
->getRegInfo().use_empty(PPC::X2
) ||
2120 !MF
->getRegInfo().use_empty(PPC::R2
);
2121 const bool PCrelGEPRequired
= Subtarget
->isUsingPCRelativeCalls() &&
2122 UsesX2OrR2
&& PPCFI
->usesTOCBasePtr();
2123 const bool NonPCrelGEPRequired
= !Subtarget
->isUsingPCRelativeCalls() &&
2124 Subtarget
->isELFv2ABI() && UsesX2OrR2
;
2126 // Only do all that if the function uses R2 as the TOC pointer
2127 // in the first place. We don't need the global entry point if the
2128 // function uses R2 as an allocatable register.
2129 if (NonPCrelGEPRequired
|| PCrelGEPRequired
) {
2130 // Note: The logic here must be synchronized with the code in the
2131 // branch-selection pass which sets the offset of the first block in the
2132 // function. This matters because it affects the alignment.
2133 MCSymbol
*GlobalEntryLabel
= PPCFI
->getGlobalEPSymbol(*MF
);
2134 OutStreamer
->emitLabel(GlobalEntryLabel
);
2135 const MCSymbolRefExpr
*GlobalEntryLabelExp
=
2136 MCSymbolRefExpr::create(GlobalEntryLabel
, OutContext
);
2138 if (TM
.getCodeModel() != CodeModel::Large
) {
2139 MCSymbol
*TOCSymbol
= OutContext
.getOrCreateSymbol(StringRef(".TOC."));
2140 const MCExpr
*TOCDeltaExpr
=
2141 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol
, OutContext
),
2142 GlobalEntryLabelExp
, OutContext
);
2144 const MCExpr
*TOCDeltaHi
= PPCMCExpr::createHa(TOCDeltaExpr
, OutContext
);
2145 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS
)
2148 .addExpr(TOCDeltaHi
));
2150 const MCExpr
*TOCDeltaLo
= PPCMCExpr::createLo(TOCDeltaExpr
, OutContext
);
2151 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDI
)
2154 .addExpr(TOCDeltaLo
));
2156 MCSymbol
*TOCOffset
= PPCFI
->getTOCOffsetSymbol(*MF
);
2157 const MCExpr
*TOCOffsetDeltaExpr
=
2158 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset
, OutContext
),
2159 GlobalEntryLabelExp
, OutContext
);
2161 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
2163 .addExpr(TOCOffsetDeltaExpr
)
2165 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADD8
)
2171 MCSymbol
*LocalEntryLabel
= PPCFI
->getLocalEPSymbol(*MF
);
2172 OutStreamer
->emitLabel(LocalEntryLabel
);
2173 const MCSymbolRefExpr
*LocalEntryLabelExp
=
2174 MCSymbolRefExpr::create(LocalEntryLabel
, OutContext
);
2175 const MCExpr
*LocalOffsetExp
=
2176 MCBinaryExpr::createSub(LocalEntryLabelExp
,
2177 GlobalEntryLabelExp
, OutContext
);
2179 PPCTargetStreamer
*TS
=
2180 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
2181 TS
->emitLocalEntry(cast
<MCSymbolELF
>(CurrentFnSym
), LocalOffsetExp
);
2182 } else if (Subtarget
->isUsingPCRelativeCalls()) {
2183 // When generating the entry point for a function we have a few scenarios
2184 // based on whether or not that function uses R2 and whether or not that
2185 // function makes calls (or is a leaf function).
2186 // 1) A leaf function that does not use R2 (or treats it as callee-saved
2187 // and preserves it). In this case st_other=0 and both
2188 // the local and global entry points for the function are the same.
2189 // No special entry point code is required.
2190 // 2) A function uses the TOC pointer R2. This function may or may not have
2191 // calls. In this case st_other=[2,6] and the global and local entry
2192 // points are different. Code to correctly setup the TOC pointer in R2
2193 // is put between the global and local entry points. This case is
2194 // covered by the if statatement above.
2195 // 3) A function does not use the TOC pointer R2 but does have calls.
2196 // In this case st_other=1 since we do not know whether or not any
2197 // of the callees clobber R2. This case is dealt with in this else if
2198 // block. Tail calls are considered calls and the st_other should also
2199 // be set to 1 in that case as well.
2200 // 4) The function does not use the TOC pointer but R2 is used inside
2201 // the function. In this case st_other=1 once again.
2202 // 5) This function uses inline asm. We mark R2 as reserved if the function
2203 // has inline asm as we have to assume that it may be used.
2204 if (MF
->getFrameInfo().hasCalls() || MF
->getFrameInfo().hasTailCall() ||
2205 MF
->hasInlineAsm() || (!PPCFI
->usesTOCBasePtr() && UsesX2OrR2
)) {
2206 PPCTargetStreamer
*TS
=
2207 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
2208 TS
->emitLocalEntry(cast
<MCSymbolELF
>(CurrentFnSym
),
2209 MCConstantExpr::create(1, OutContext
));
2214 /// EmitFunctionBodyEnd - Print the traceback table before the .size
2217 void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
2218 // Only the 64-bit target requires a traceback table. For now,
2219 // we only emit the word of zeroes that GDB requires to find
2220 // the end of the function, and zeroes for the eight-byte
2221 // mandatory fields.
2222 // FIXME: We should fill in the eight-byte mandatory fields as described in
2223 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
2224 // currently make use of these fields).
2225 if (Subtarget
->isPPC64()) {
2226 OutStreamer
->emitIntValue(0, 4/*size*/);
2227 OutStreamer
->emitIntValue(0, 8/*size*/);
2231 void PPCAIXAsmPrinter::emitLinkage(const GlobalValue
*GV
,
2232 MCSymbol
*GVSym
) const {
2233 MCSymbolAttr LinkageAttr
= MCSA_Invalid
;
2234 switch (GV
->getLinkage()) {
2235 case GlobalValue::ExternalLinkage
:
2236 LinkageAttr
= GV
->isDeclaration() ? MCSA_Extern
: MCSA_Global
;
2238 case GlobalValue::LinkOnceAnyLinkage
:
2239 case GlobalValue::LinkOnceODRLinkage
:
2240 case GlobalValue::WeakAnyLinkage
:
2241 case GlobalValue::WeakODRLinkage
:
2242 case GlobalValue::ExternalWeakLinkage
:
2243 LinkageAttr
= MCSA_Weak
;
2245 case GlobalValue::AvailableExternallyLinkage
:
2246 LinkageAttr
= MCSA_Extern
;
2248 case GlobalValue::PrivateLinkage
:
2250 case GlobalValue::InternalLinkage
:
2251 assert(GV
->getVisibility() == GlobalValue::DefaultVisibility
&&
2252 "InternalLinkage should not have other visibility setting.");
2253 LinkageAttr
= MCSA_LGlobal
;
2255 case GlobalValue::AppendingLinkage
:
2256 llvm_unreachable("Should never emit this");
2257 case GlobalValue::CommonLinkage
:
2258 llvm_unreachable("CommonLinkage of XCOFF should not come to this path");
2261 assert(LinkageAttr
!= MCSA_Invalid
&& "LinkageAttr should not MCSA_Invalid.");
2263 MCSymbolAttr VisibilityAttr
= MCSA_Invalid
;
2264 if (!TM
.getIgnoreXCOFFVisibility()) {
2265 if (GV
->hasDLLExportStorageClass() && !GV
->hasDefaultVisibility())
2267 "Cannot not be both dllexport and non-default visibility");
2268 switch (GV
->getVisibility()) {
2270 // TODO: "internal" Visibility needs to go here.
2271 case GlobalValue::DefaultVisibility
:
2272 if (GV
->hasDLLExportStorageClass())
2273 VisibilityAttr
= MAI
->getExportedVisibilityAttr();
2275 case GlobalValue::HiddenVisibility
:
2276 VisibilityAttr
= MAI
->getHiddenVisibilityAttr();
2278 case GlobalValue::ProtectedVisibility
:
2279 VisibilityAttr
= MAI
->getProtectedVisibilityAttr();
2284 // Do not emit the _$TLSML symbol.
2285 if (GV
->getThreadLocalMode() == GlobalVariable::LocalDynamicTLSModel
&&
2286 GV
->hasName() && GV
->getName() == "_$TLSML")
2289 OutStreamer
->emitXCOFFSymbolLinkageWithVisibility(GVSym
, LinkageAttr
,
2293 void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction
&MF
) {
2294 // Setup CurrentFnDescSym and its containing csect.
2295 MCSectionXCOFF
*FnDescSec
=
2296 cast
<MCSectionXCOFF
>(getObjFileLowering().getSectionForFunctionDescriptor(
2297 &MF
.getFunction(), TM
));
2298 FnDescSec
->setAlignment(Align(Subtarget
->isPPC64() ? 8 : 4));
2300 CurrentFnDescSym
= FnDescSec
->getQualNameSymbol();
2302 return AsmPrinter::SetupMachineFunction(MF
);
2305 uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
2306 // Calculate the number of VRs be saved.
2307 // Vector registers 20 through 31 are marked as reserved and cannot be used
2308 // in the default ABI.
2309 const PPCSubtarget
&Subtarget
= MF
->getSubtarget
<PPCSubtarget
>();
2310 if (Subtarget
.isAIXABI() && Subtarget
.hasAltivec() &&
2311 TM
.getAIXExtendedAltivecABI()) {
2312 const MachineRegisterInfo
&MRI
= MF
->getRegInfo();
2313 for (unsigned Reg
= PPC::V20
; Reg
<= PPC::V31
; ++Reg
)
2314 if (MRI
.isPhysRegModified(Reg
))
2315 // Number of VRs saved.
2316 return PPC::V31
- Reg
+ 1;
2321 void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
2323 if (!TM
.getXCOFFTracebackTable())
2326 emitTracebackTable();
2328 // If ShouldEmitEHBlock returns true, then the eh info table
2329 // will be emitted via `AIXException::endFunction`. Otherwise, we
2330 // need to emit a dumy eh info table when VRs are saved. We could not
2331 // consolidate these two places into one because there is no easy way
2332 // to access register information in `AIXException` class.
2333 if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF
) &&
2334 (getNumberOfVRSaved() > 0)) {
2335 // Emit dummy EH Info Table.
2336 OutStreamer
->switchSection(getObjFileLowering().getCompactUnwindSection());
2337 MCSymbol
*EHInfoLabel
=
2338 TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF
);
2339 OutStreamer
->emitLabel(EHInfoLabel
);
2342 OutStreamer
->emitInt32(0);
2344 const DataLayout
&DL
= MMI
->getModule()->getDataLayout();
2345 const unsigned PointerSize
= DL
.getPointerSize();
2346 // Add necessary paddings in 64 bit mode.
2347 OutStreamer
->emitValueToAlignment(Align(PointerSize
));
2349 OutStreamer
->emitIntValue(0, PointerSize
);
2350 OutStreamer
->emitIntValue(0, PointerSize
);
2351 OutStreamer
->switchSection(MF
->getSection());
2355 void PPCAIXAsmPrinter::emitTracebackTable() {
2357 // Create a symbol for the end of function.
2358 MCSymbol
*FuncEnd
= createTempSymbol(MF
->getName());
2359 OutStreamer
->emitLabel(FuncEnd
);
2361 OutStreamer
->AddComment("Traceback table begin");
2362 // Begin with a fullword of zero.
2363 OutStreamer
->emitIntValueInHexWithPadding(0, 4 /*size*/);
2365 SmallString
<128> CommentString
;
2366 raw_svector_ostream
CommentOS(CommentString
);
2368 auto EmitComment
= [&]() {
2369 OutStreamer
->AddComment(CommentOS
.str());
2370 CommentString
.clear();
2373 auto EmitCommentAndValue
= [&](uint64_t Value
, int Size
) {
2375 OutStreamer
->emitIntValueInHexWithPadding(Value
, Size
);
2378 unsigned int Version
= 0;
2379 CommentOS
<< "Version = " << Version
;
2380 EmitCommentAndValue(Version
, 1);
2382 // There is a lack of information in the IR to assist with determining the
2383 // source language. AIX exception handling mechanism would only search for
2384 // personality routine and LSDA area when such language supports exception
2385 // handling. So to be conservatively correct and allow runtime to do its job,
2386 // we need to set it to C++ for now.
2387 TracebackTable::LanguageID LanguageIdentifier
=
2388 TracebackTable::CPlusPlus
; // C++
2390 CommentOS
<< "Language = "
2391 << getNameForTracebackTableLanguageId(LanguageIdentifier
);
2392 EmitCommentAndValue(LanguageIdentifier
, 1);
2394 // This is only populated for the third and fourth bytes.
2395 uint32_t FirstHalfOfMandatoryField
= 0;
2397 // Emit the 3rd byte of the mandatory field.
2399 // We always set traceback offset bit to true.
2400 FirstHalfOfMandatoryField
|= TracebackTable::HasTraceBackTableOffsetMask
;
2402 const PPCFunctionInfo
*FI
= MF
->getInfo
<PPCFunctionInfo
>();
2403 const MachineRegisterInfo
&MRI
= MF
->getRegInfo();
2405 // Check the function uses floating-point processor instructions or not
2406 for (unsigned Reg
= PPC::F0
; Reg
<= PPC::F31
; ++Reg
) {
2407 if (MRI
.isPhysRegUsed(Reg
, /* SkipRegMaskTest */ true)) {
2408 FirstHalfOfMandatoryField
|= TracebackTable::IsFloatingPointPresentMask
;
2413 #define GENBOOLCOMMENT(Prefix, V, Field) \
2414 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
2417 #define GENVALUECOMMENT(PrefixAndName, V, Field) \
2418 CommentOS << (PrefixAndName) << " = " \
2419 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2420 (TracebackTable::Field##Shift))
2422 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, IsGlobaLinkage
);
2423 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsOutOfLineEpilogOrPrologue
);
2426 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, HasTraceBackTableOffset
);
2427 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsInternalProcedure
);
2430 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, HasControlledStorage
);
2431 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsTOCless
);
2434 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, IsFloatingPointPresent
);
2436 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
,
2437 IsFloatingPointOperationLogOrAbortEnabled
);
2440 OutStreamer
->emitIntValueInHexWithPadding(
2441 (FirstHalfOfMandatoryField
& 0x0000ff00) >> 8, 1);
2443 // Set the 4th byte of the mandatory field.
2444 FirstHalfOfMandatoryField
|= TracebackTable::IsFunctionNamePresentMask
;
2446 const PPCRegisterInfo
*RegInfo
=
2447 static_cast<const PPCRegisterInfo
*>(Subtarget
->getRegisterInfo());
2448 Register FrameReg
= RegInfo
->getFrameRegister(*MF
);
2449 if (FrameReg
== (Subtarget
->isPPC64() ? PPC::X31
: PPC::R31
))
2450 FirstHalfOfMandatoryField
|= TracebackTable::IsAllocaUsedMask
;
2452 const SmallVectorImpl
<Register
> &MustSaveCRs
= FI
->getMustSaveCRs();
2453 if (!MustSaveCRs
.empty())
2454 FirstHalfOfMandatoryField
|= TracebackTable::IsCRSavedMask
;
2456 if (FI
->mustSaveLR())
2457 FirstHalfOfMandatoryField
|= TracebackTable::IsLRSavedMask
;
2459 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, IsInterruptHandler
);
2460 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsFunctionNamePresent
);
2461 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsAllocaUsed
);
2463 GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField
,
2464 OnConditionDirective
);
2465 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsCRSaved
);
2466 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsLRSaved
);
2468 OutStreamer
->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField
& 0xff),
2471 // Set the 5th byte of mandatory field.
2472 uint32_t SecondHalfOfMandatoryField
= 0;
2474 SecondHalfOfMandatoryField
|= MF
->getFrameInfo().getStackSize()
2475 ? TracebackTable::IsBackChainStoredMask
2478 uint32_t FPRSaved
= 0;
2479 for (unsigned Reg
= PPC::F14
; Reg
<= PPC::F31
; ++Reg
) {
2480 if (MRI
.isPhysRegModified(Reg
)) {
2481 FPRSaved
= PPC::F31
- Reg
+ 1;
2485 SecondHalfOfMandatoryField
|= (FPRSaved
<< TracebackTable::FPRSavedShift
) &
2486 TracebackTable::FPRSavedMask
;
2487 GENBOOLCOMMENT("", SecondHalfOfMandatoryField
, IsBackChainStored
);
2488 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField
, IsFixup
);
2489 GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField
, FPRSaved
);
2491 OutStreamer
->emitIntValueInHexWithPadding(
2492 (SecondHalfOfMandatoryField
& 0xff000000) >> 24, 1);
2494 // Set the 6th byte of mandatory field.
2496 // Check whether has Vector Instruction,We only treat instructions uses vector
2497 // register as vector instructions.
2498 bool HasVectorInst
= false;
2499 for (unsigned Reg
= PPC::V0
; Reg
<= PPC::V31
; ++Reg
)
2500 if (MRI
.isPhysRegUsed(Reg
, /* SkipRegMaskTest */ true)) {
2501 // Has VMX instruction.
2502 HasVectorInst
= true;
2506 if (FI
->hasVectorParms() || HasVectorInst
)
2507 SecondHalfOfMandatoryField
|= TracebackTable::HasVectorInfoMask
;
2509 uint16_t NumOfVRSaved
= getNumberOfVRSaved();
2510 bool ShouldEmitEHBlock
=
2511 TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF
) || NumOfVRSaved
> 0;
2513 if (ShouldEmitEHBlock
)
2514 SecondHalfOfMandatoryField
|= TracebackTable::HasExtensionTableMask
;
2516 uint32_t GPRSaved
= 0;
2518 // X13 is reserved under 64-bit environment.
2519 unsigned GPRBegin
= Subtarget
->isPPC64() ? PPC::X14
: PPC::R13
;
2520 unsigned GPREnd
= Subtarget
->isPPC64() ? PPC::X31
: PPC::R31
;
2522 for (unsigned Reg
= GPRBegin
; Reg
<= GPREnd
; ++Reg
) {
2523 if (MRI
.isPhysRegModified(Reg
)) {
2524 GPRSaved
= GPREnd
- Reg
+ 1;
2529 SecondHalfOfMandatoryField
|= (GPRSaved
<< TracebackTable::GPRSavedShift
) &
2530 TracebackTable::GPRSavedMask
;
2532 GENBOOLCOMMENT("", SecondHalfOfMandatoryField
, HasExtensionTable
);
2533 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField
, HasVectorInfo
);
2534 GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField
, GPRSaved
);
2536 OutStreamer
->emitIntValueInHexWithPadding(
2537 (SecondHalfOfMandatoryField
& 0x00ff0000) >> 16, 1);
2539 // Set the 7th byte of mandatory field.
2540 uint32_t NumberOfFixedParms
= FI
->getFixedParmsNum();
2541 SecondHalfOfMandatoryField
|=
2542 (NumberOfFixedParms
<< TracebackTable::NumberOfFixedParmsShift
) &
2543 TracebackTable::NumberOfFixedParmsMask
;
2544 GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField
,
2545 NumberOfFixedParms
);
2547 OutStreamer
->emitIntValueInHexWithPadding(
2548 (SecondHalfOfMandatoryField
& 0x0000ff00) >> 8, 1);
2550 // Set the 8th byte of mandatory field.
2552 // Always set parameter on stack.
2553 SecondHalfOfMandatoryField
|= TracebackTable::HasParmsOnStackMask
;
2555 uint32_t NumberOfFPParms
= FI
->getFloatingPointParmsNum();
2556 SecondHalfOfMandatoryField
|=
2557 (NumberOfFPParms
<< TracebackTable::NumberOfFloatingPointParmsShift
) &
2558 TracebackTable::NumberOfFloatingPointParmsMask
;
2560 GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField
,
2561 NumberOfFloatingPointParms
);
2562 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField
, HasParmsOnStack
);
2564 OutStreamer
->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField
& 0xff,
2567 // Generate the optional fields of traceback table.
2570 if (NumberOfFixedParms
|| NumberOfFPParms
) {
2571 uint32_t ParmsTypeValue
= FI
->getParmsType();
2573 Expected
<SmallString
<32>> ParmsType
=
2574 FI
->hasVectorParms()
2575 ? XCOFF::parseParmsTypeWithVecInfo(
2576 ParmsTypeValue
, NumberOfFixedParms
, NumberOfFPParms
,
2577 FI
->getVectorParmsNum())
2578 : XCOFF::parseParmsType(ParmsTypeValue
, NumberOfFixedParms
,
2581 assert(ParmsType
&& toString(ParmsType
.takeError()).c_str());
2583 CommentOS
<< "Parameter type = " << ParmsType
.get();
2586 OutStreamer
->emitIntValueInHexWithPadding(ParmsTypeValue
,
2587 sizeof(ParmsTypeValue
));
2589 // Traceback table offset.
2590 OutStreamer
->AddComment("Function size");
2591 if (FirstHalfOfMandatoryField
& TracebackTable::HasTraceBackTableOffsetMask
) {
2592 MCSymbol
*FuncSectSym
= getObjFileLowering().getFunctionEntryPointSymbol(
2593 &(MF
->getFunction()), TM
);
2594 OutStreamer
->emitAbsoluteSymbolDiff(FuncEnd
, FuncSectSym
, 4);
2597 // Since we unset the Int_Handler.
2598 if (FirstHalfOfMandatoryField
& TracebackTable::IsInterruptHandlerMask
)
2599 report_fatal_error("Hand_Mask not implement yet");
2601 if (FirstHalfOfMandatoryField
& TracebackTable::HasControlledStorageMask
)
2602 report_fatal_error("Ctl_Info not implement yet");
2604 if (FirstHalfOfMandatoryField
& TracebackTable::IsFunctionNamePresentMask
) {
2605 StringRef Name
= MF
->getName().substr(0, INT16_MAX
);
2606 int16_t NameLength
= Name
.size();
2607 CommentOS
<< "Function name len = "
2608 << static_cast<unsigned int>(NameLength
);
2609 EmitCommentAndValue(NameLength
, 2);
2610 OutStreamer
->AddComment("Function Name");
2611 OutStreamer
->emitBytes(Name
);
2614 if (FirstHalfOfMandatoryField
& TracebackTable::IsAllocaUsedMask
) {
2615 uint8_t AllocReg
= XCOFF::AllocRegNo
;
2616 OutStreamer
->AddComment("AllocaUsed");
2617 OutStreamer
->emitIntValueInHex(AllocReg
, sizeof(AllocReg
));
2620 if (SecondHalfOfMandatoryField
& TracebackTable::HasVectorInfoMask
) {
2621 uint16_t VRData
= 0;
2623 // Number of VRs saved.
2624 VRData
|= (NumOfVRSaved
<< TracebackTable::NumberOfVRSavedShift
) &
2625 TracebackTable::NumberOfVRSavedMask
;
2626 // This bit is supposed to set only when the special register
2627 // VRSAVE is saved on stack.
2628 // However, IBM XL compiler sets the bit when any vector registers
2629 // are saved on the stack. We will follow XL's behavior on AIX
2630 // so that we don't get surprise behavior change for C code.
2631 VRData
|= TracebackTable::IsVRSavedOnStackMask
;
2635 if (FI
->getVarArgsFrameIndex())
2636 VRData
|= TracebackTable::HasVarArgsMask
;
2638 // Vector parameters number.
2639 unsigned VectorParmsNum
= FI
->getVectorParmsNum();
2640 VRData
|= (VectorParmsNum
<< TracebackTable::NumberOfVectorParmsShift
) &
2641 TracebackTable::NumberOfVectorParmsMask
;
2644 VRData
|= TracebackTable::HasVMXInstructionMask
;
2646 GENVALUECOMMENT("NumOfVRsSaved", VRData
, NumberOfVRSaved
);
2647 GENBOOLCOMMENT(", ", VRData
, IsVRSavedOnStack
);
2648 GENBOOLCOMMENT(", ", VRData
, HasVarArgs
);
2650 OutStreamer
->emitIntValueInHexWithPadding((VRData
& 0xff00) >> 8, 1);
2652 GENVALUECOMMENT("NumOfVectorParams", VRData
, NumberOfVectorParms
);
2653 GENBOOLCOMMENT(", ", VRData
, HasVMXInstruction
);
2655 OutStreamer
->emitIntValueInHexWithPadding(VRData
& 0x00ff, 1);
2657 uint32_t VecParmTypeValue
= FI
->getVecExtParmsType();
2659 Expected
<SmallString
<32>> VecParmsType
=
2660 XCOFF::parseVectorParmsType(VecParmTypeValue
, VectorParmsNum
);
2661 assert(VecParmsType
&& toString(VecParmsType
.takeError()).c_str());
2663 CommentOS
<< "Vector Parameter type = " << VecParmsType
.get();
2666 OutStreamer
->emitIntValueInHexWithPadding(VecParmTypeValue
,
2667 sizeof(VecParmTypeValue
));
2669 CommentOS
<< "Padding";
2670 EmitCommentAndValue(0, 2);
2673 uint8_t ExtensionTableFlag
= 0;
2674 if (SecondHalfOfMandatoryField
& TracebackTable::HasExtensionTableMask
) {
2675 if (ShouldEmitEHBlock
)
2676 ExtensionTableFlag
|= ExtendedTBTableFlag::TB_EH_INFO
;
2677 if (EnableSSPCanaryBitInTB
&&
2678 TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB(MF
))
2679 ExtensionTableFlag
|= ExtendedTBTableFlag::TB_SSP_CANARY
;
2681 CommentOS
<< "ExtensionTableFlag = "
2682 << getExtendedTBTableFlagString(ExtensionTableFlag
);
2683 EmitCommentAndValue(ExtensionTableFlag
, sizeof(ExtensionTableFlag
));
2686 if (ExtensionTableFlag
& ExtendedTBTableFlag::TB_EH_INFO
) {
2687 auto &Ctx
= OutStreamer
->getContext();
2688 MCSymbol
*EHInfoSym
=
2689 TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF
);
2690 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(EHInfoSym
, TOCType_EHBlock
);
2691 const MCSymbol
*TOCBaseSym
=
2692 cast
<MCSectionXCOFF
>(getObjFileLowering().getTOCBaseSection())
2693 ->getQualNameSymbol();
2695 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry
, Ctx
),
2696 MCSymbolRefExpr::create(TOCBaseSym
, Ctx
), Ctx
);
2698 const DataLayout
&DL
= getDataLayout();
2699 OutStreamer
->emitValueToAlignment(Align(4));
2700 OutStreamer
->AddComment("EHInfo Table");
2701 OutStreamer
->emitValue(Exp
, DL
.getPointerSize());
2703 #undef GENBOOLCOMMENT
2704 #undef GENVALUECOMMENT
2707 static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable
*GV
) {
2708 return GV
->hasAppendingLinkage() &&
2709 StringSwitch
<bool>(GV
->getName())
2710 // TODO: Linker could still eliminate the GV if we just skip
2711 // handling llvm.used array. Skipping them for now until we or the
2712 // AIX OS team come up with a good solution.
2713 .Case("llvm.used", true)
2714 // It's correct to just skip llvm.compiler.used array here.
2715 .Case("llvm.compiler.used", true)
2719 static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable
*GV
) {
2720 return StringSwitch
<bool>(GV
->getName())
2721 .Cases("llvm.global_ctors", "llvm.global_dtors", true)
2725 uint64_t PPCAIXAsmPrinter::getAliasOffset(const Constant
*C
) {
2726 if (auto *GA
= dyn_cast
<GlobalAlias
>(C
))
2727 return getAliasOffset(GA
->getAliasee());
2728 if (auto *CE
= dyn_cast
<ConstantExpr
>(C
)) {
2729 const MCExpr
*LowC
= lowerConstant(CE
);
2730 const MCBinaryExpr
*CBE
= dyn_cast
<MCBinaryExpr
>(LowC
);
2733 if (CBE
->getOpcode() != MCBinaryExpr::Add
)
2734 report_fatal_error("Only adding an offset is supported now.");
2735 auto *RHS
= dyn_cast
<MCConstantExpr
>(CBE
->getRHS());
2737 report_fatal_error("Unable to get the offset of alias.");
2738 return RHS
->getValue();
2743 static void tocDataChecks(unsigned PointerSize
, const GlobalVariable
*GV
) {
2744 // TODO: These asserts should be updated as more support for the toc data
2745 // transformation is added (struct support, etc.).
2747 PointerSize
>= GV
->getAlign().valueOrOne().value() &&
2748 "GlobalVariables with an alignment requirement stricter than TOC entry "
2749 "size not supported by the toc data transformation.");
2751 Type
*GVType
= GV
->getValueType();
2752 assert(GVType
->isSized() && "A GlobalVariable's size must be known to be "
2753 "supported by the toc data transformation.");
2754 if (GV
->getDataLayout().getTypeSizeInBits(GVType
) >
2757 "A GlobalVariable with size larger than a TOC entry is not currently "
2758 "supported by the toc data transformation.");
2759 if (GV
->hasPrivateLinkage())
2760 report_fatal_error("A GlobalVariable with private linkage is not "
2761 "currently supported by the toc data transformation.");
2764 void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable
*GV
) {
2765 // Special LLVM global arrays have been handled at the initialization.
2766 if (isSpecialLLVMGlobalArrayToSkip(GV
) || isSpecialLLVMGlobalArrayForStaticInit(GV
))
2769 // If the Global Variable has the toc-data attribute, it needs to be emitted
2770 // when we emit the .toc section.
2771 if (GV
->hasAttribute("toc-data")) {
2772 unsigned PointerSize
= GV
->getDataLayout().getPointerSize();
2773 tocDataChecks(PointerSize
, GV
);
2774 TOCDataGlobalVars
.push_back(GV
);
2778 emitGlobalVariableHelper(GV
);
2781 void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable
*GV
) {
2782 assert(!GV
->getName().starts_with("llvm.") &&
2783 "Unhandled intrinsic global variable.");
2785 if (GV
->hasComdat())
2786 report_fatal_error("COMDAT not yet supported by AIX.");
2788 MCSymbolXCOFF
*GVSym
= cast
<MCSymbolXCOFF
>(getSymbol(GV
));
2790 if (GV
->isDeclarationForLinker()) {
2791 emitLinkage(GV
, GVSym
);
2795 SectionKind GVKind
= getObjFileLowering().getKindForGlobal(GV
, TM
);
2796 if (!GVKind
.isGlobalWriteableData() && !GVKind
.isReadOnly() &&
2797 !GVKind
.isThreadLocal()) // Checks for both ThreadData and ThreadBSS.
2798 report_fatal_error("Encountered a global variable kind that is "
2799 "not supported yet.");
2801 // Print GV in verbose mode
2803 if (GV
->hasInitializer()) {
2804 GV
->printAsOperand(OutStreamer
->getCommentOS(),
2805 /*PrintType=*/false, GV
->getParent());
2806 OutStreamer
->getCommentOS() << '\n';
2810 MCSectionXCOFF
*Csect
= cast
<MCSectionXCOFF
>(
2811 getObjFileLowering().SectionForGlobal(GV
, GVKind
, TM
));
2813 // Switch to the containing csect.
2814 OutStreamer
->switchSection(Csect
);
2816 const DataLayout
&DL
= GV
->getDataLayout();
2818 // Handle common and zero-initialized local symbols.
2819 if (GV
->hasCommonLinkage() || GVKind
.isBSSLocal() ||
2820 GVKind
.isThreadBSSLocal()) {
2821 Align Alignment
= GV
->getAlign().value_or(DL
.getPreferredAlign(GV
));
2822 uint64_t Size
= DL
.getTypeAllocSize(GV
->getValueType());
2823 GVSym
->setStorageClass(
2824 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV
));
2826 if (GVKind
.isBSSLocal() && Csect
->getMappingClass() == XCOFF::XMC_TD
) {
2827 OutStreamer
->emitZeros(Size
);
2828 } else if (GVKind
.isBSSLocal() || GVKind
.isThreadBSSLocal()) {
2829 assert(Csect
->getMappingClass() != XCOFF::XMC_TD
&&
2830 "BSS local toc-data already handled and TLS variables "
2831 "incompatible with XMC_TD");
2832 OutStreamer
->emitXCOFFLocalCommonSymbol(
2833 OutContext
.getOrCreateSymbol(GVSym
->getSymbolTableName()), Size
,
2836 OutStreamer
->emitCommonSymbol(GVSym
, Size
, Alignment
);
2841 MCSymbol
*EmittedInitSym
= GVSym
;
2843 // Emit linkage for the global variable and its aliases.
2844 emitLinkage(GV
, EmittedInitSym
);
2845 for (const GlobalAlias
*GA
: GOAliasMap
[GV
])
2846 emitLinkage(GA
, getSymbol(GA
));
2848 emitAlignment(getGVAlignment(GV
, DL
), GV
);
2850 // When -fdata-sections is enabled, every GlobalVariable will
2851 // be put into its own csect; therefore, label is not necessary here.
2852 if (!TM
.getDataSections() || GV
->hasSection()) {
2853 if (Csect
->getMappingClass() != XCOFF::XMC_TD
)
2854 OutStreamer
->emitLabel(EmittedInitSym
);
2857 // No alias to emit.
2858 if (!GOAliasMap
[GV
].size()) {
2859 emitGlobalConstant(GV
->getDataLayout(), GV
->getInitializer());
2863 // Aliases with the same offset should be aligned. Record the list of aliases
2864 // associated with the offset.
2865 AliasMapTy AliasList
;
2866 for (const GlobalAlias
*GA
: GOAliasMap
[GV
])
2867 AliasList
[getAliasOffset(GA
->getAliasee())].push_back(GA
);
2869 // Emit alias label and element value for global variable.
2870 emitGlobalConstant(GV
->getDataLayout(), GV
->getInitializer(),
2874 void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2875 const DataLayout
&DL
= getDataLayout();
2876 const unsigned PointerSize
= DL
.getPointerSizeInBits() == 64 ? 8 : 4;
2878 MCSectionSubPair Current
= OutStreamer
->getCurrentSection();
2879 // Emit function descriptor.
2880 OutStreamer
->switchSection(
2881 cast
<MCSymbolXCOFF
>(CurrentFnDescSym
)->getRepresentedCsect());
2883 // Emit aliasing label for function descriptor csect.
2884 for (const GlobalAlias
*Alias
: GOAliasMap
[&MF
->getFunction()])
2885 OutStreamer
->emitLabel(getSymbol(Alias
));
2887 // Emit function entry point address.
2888 OutStreamer
->emitValue(MCSymbolRefExpr::create(CurrentFnSym
, OutContext
),
2890 // Emit TOC base address.
2891 const MCSymbol
*TOCBaseSym
=
2892 cast
<MCSectionXCOFF
>(getObjFileLowering().getTOCBaseSection())
2893 ->getQualNameSymbol();
2894 OutStreamer
->emitValue(MCSymbolRefExpr::create(TOCBaseSym
, OutContext
),
2896 // Emit a null environment pointer.
2897 OutStreamer
->emitIntValue(0, PointerSize
);
2899 OutStreamer
->switchSection(Current
.first
, Current
.second
);
2902 void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2903 // For functions without user defined section, it's not necessary to emit the
2904 // label when we have individual function in its own csect.
2905 if (!TM
.getFunctionSections() || MF
->getFunction().hasSection())
2906 PPCAsmPrinter::emitFunctionEntryLabel();
2908 // Emit aliasing label for function entry point label.
2909 for (const GlobalAlias
*Alias
: GOAliasMap
[&MF
->getFunction()])
2910 OutStreamer
->emitLabel(
2911 getObjFileLowering().getFunctionEntryPointSymbol(Alias
, TM
));
2914 void PPCAIXAsmPrinter::emitPGORefs(Module
&M
) {
2915 if (!OutContext
.hasXCOFFSection(
2917 XCOFF::CsectProperties(XCOFF::XMC_RW
, XCOFF::XTY_SD
)))
2920 // When inside a csect `foo`, a .ref directive referring to a csect `bar`
2921 // translates into a relocation entry from `foo` to` bar`. The referring
2922 // csect, `foo`, is identified by its address. If multiple csects have the
2923 // same address (because one or more of them are zero-length), the referring
2924 // csect cannot be determined. Hence, we don't generate the .ref directives
2925 // if `__llvm_prf_cnts` is an empty section.
2926 bool HasNonZeroLengthPrfCntsSection
= false;
2927 const DataLayout
&DL
= M
.getDataLayout();
2928 for (GlobalVariable
&GV
: M
.globals())
2929 if (GV
.hasSection() && GV
.getSection() == "__llvm_prf_cnts" &&
2930 DL
.getTypeAllocSize(GV
.getValueType()) > 0) {
2931 HasNonZeroLengthPrfCntsSection
= true;
2935 if (HasNonZeroLengthPrfCntsSection
) {
2936 MCSection
*CntsSection
= OutContext
.getXCOFFSection(
2937 "__llvm_prf_cnts", SectionKind::getData(),
2938 XCOFF::CsectProperties(XCOFF::XMC_RW
, XCOFF::XTY_SD
),
2939 /*MultiSymbolsAllowed*/ true);
2941 OutStreamer
->switchSection(CntsSection
);
2942 if (OutContext
.hasXCOFFSection(
2944 XCOFF::CsectProperties(XCOFF::XMC_RW
, XCOFF::XTY_SD
))) {
2945 MCSymbol
*S
= OutContext
.getOrCreateSymbol("__llvm_prf_data[RW]");
2946 OutStreamer
->emitXCOFFRefDirective(S
);
2948 if (OutContext
.hasXCOFFSection(
2950 XCOFF::CsectProperties(XCOFF::XMC_RO
, XCOFF::XTY_SD
))) {
2951 MCSymbol
*S
= OutContext
.getOrCreateSymbol("__llvm_prf_names[RO]");
2952 OutStreamer
->emitXCOFFRefDirective(S
);
2954 if (OutContext
.hasXCOFFSection(
2956 XCOFF::CsectProperties(XCOFF::XMC_RW
, XCOFF::XTY_SD
))) {
2957 MCSymbol
*S
= OutContext
.getOrCreateSymbol("__llvm_prf_vnds[RW]");
2958 OutStreamer
->emitXCOFFRefDirective(S
);
2963 void PPCAIXAsmPrinter::emitGCOVRefs() {
2964 if (!OutContext
.hasXCOFFSection(
2965 "__llvm_gcov_ctr_section",
2966 XCOFF::CsectProperties(XCOFF::XMC_RW
, XCOFF::XTY_SD
)))
2969 MCSection
*CtrSection
= OutContext
.getXCOFFSection(
2970 "__llvm_gcov_ctr_section", SectionKind::getData(),
2971 XCOFF::CsectProperties(XCOFF::XMC_RW
, XCOFF::XTY_SD
),
2972 /*MultiSymbolsAllowed*/ true);
2974 OutStreamer
->switchSection(CtrSection
);
2975 const XCOFF::StorageMappingClass MappingClass
=
2976 TM
.Options
.XCOFFReadOnlyPointers
? XCOFF::XMC_RO
: XCOFF::XMC_RW
;
2977 if (OutContext
.hasXCOFFSection(
2979 XCOFF::CsectProperties(MappingClass
, XCOFF::XTY_SD
))) {
2980 const char *SymbolStr
= TM
.Options
.XCOFFReadOnlyPointers
2981 ? "__llvm_covinit[RO]"
2982 : "__llvm_covinit[RW]";
2983 MCSymbol
*S
= OutContext
.getOrCreateSymbol(SymbolStr
);
2984 OutStreamer
->emitXCOFFRefDirective(S
);
2988 void PPCAIXAsmPrinter::emitEndOfAsmFile(Module
&M
) {
2989 // If there are no functions and there are no toc-data definitions in this
2990 // module, we will never need to reference the TOC base.
2991 if (M
.empty() && TOCDataGlobalVars
.empty())
2997 // Switch to section to emit TOC base.
2998 OutStreamer
->switchSection(getObjFileLowering().getTOCBaseSection());
3000 PPCTargetStreamer
*TS
=
3001 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
3003 for (auto &I
: TOC
) {
3004 MCSectionXCOFF
*TCEntry
;
3005 // Setup the csect for the current TC entry. If the variant kind is
3006 // VK_PPC_AIX_TLSGDM the entry represents the region handle, we create a
3007 // new symbol to prefix the name with a dot.
3008 // If TLS model opt is turned on, create a new symbol to prefix the name
3010 if (I
.first
.second
== MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM
||
3011 (Subtarget
->hasAIXShLibTLSModelOpt() &&
3012 I
.first
.second
== MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSLD
)) {
3013 SmallString
<128> Name
;
3014 StringRef Prefix
= ".";
3016 Name
+= cast
<MCSymbolXCOFF
>(I
.first
.first
)->getSymbolTableName();
3017 MCSymbol
*S
= OutContext
.getOrCreateSymbol(Name
);
3018 TCEntry
= cast
<MCSectionXCOFF
>(
3019 getObjFileLowering().getSectionForTOCEntry(S
, TM
));
3021 TCEntry
= cast
<MCSectionXCOFF
>(
3022 getObjFileLowering().getSectionForTOCEntry(I
.first
.first
, TM
));
3024 OutStreamer
->switchSection(TCEntry
);
3026 OutStreamer
->emitLabel(I
.second
);
3027 TS
->emitTCEntry(*I
.first
.first
, I
.first
.second
);
3030 // Traverse the list of global variables twice, emitting all of the
3031 // non-common global variables before the common ones, as emitting a
3032 // .comm directive changes the scope from .toc to the common symbol.
3033 for (const auto *GV
: TOCDataGlobalVars
) {
3034 if (!GV
->hasCommonLinkage())
3035 emitGlobalVariableHelper(GV
);
3037 for (const auto *GV
: TOCDataGlobalVars
) {
3038 if (GV
->hasCommonLinkage())
3039 emitGlobalVariableHelper(GV
);
3043 bool PPCAIXAsmPrinter::doInitialization(Module
&M
) {
3044 const bool Result
= PPCAsmPrinter::doInitialization(M
);
3046 // Emit the .machine directive on AIX.
3047 const Triple
&Target
= TM
.getTargetTriple();
3048 XCOFF::CFileCpuId TargetCpuId
= XCOFF::TCPU_INVALID
;
3049 // Walk through the "target-cpu" attribute of functions and use the newest
3050 // level as the CPU of the module.
3052 XCOFF::CFileCpuId FunCpuId
=
3053 XCOFF::getCpuID(TM
.getSubtargetImpl(F
)->getCPU());
3054 if (FunCpuId
> TargetCpuId
)
3055 TargetCpuId
= FunCpuId
;
3057 // If there is no "target-cpu" attribute within the functions, take the
3058 // "-mcpu" value. If both are omitted, use getNormalizedPPCTargetCPU() to
3059 // determine the default CPU.
3061 StringRef TargetCPU
= TM
.getTargetCPU();
3062 TargetCpuId
= XCOFF::getCpuID(
3063 TargetCPU
.empty() ? PPC::getNormalizedPPCTargetCPU(Target
) : TargetCPU
);
3066 PPCTargetStreamer
*TS
=
3067 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
3068 TS
->emitMachine(XCOFF::getTCPUString(TargetCpuId
));
3070 auto setCsectAlignment
= [this](const GlobalObject
*GO
) {
3071 // Declarations have 0 alignment which is set by default.
3072 if (GO
->isDeclarationForLinker())
3075 SectionKind GOKind
= getObjFileLowering().getKindForGlobal(GO
, TM
);
3076 MCSectionXCOFF
*Csect
= cast
<MCSectionXCOFF
>(
3077 getObjFileLowering().SectionForGlobal(GO
, GOKind
, TM
));
3079 Align GOAlign
= getGVAlignment(GO
, GO
->getDataLayout());
3080 Csect
->ensureMinAlignment(GOAlign
);
3083 // For all TLS variables, calculate their corresponding addresses and store
3084 // them into TLSVarsToAddressMapping, which will be used to determine whether
3085 // or not local-exec TLS variables require special assembly printing.
3086 uint64_t TLSVarAddress
= 0;
3087 auto DL
= M
.getDataLayout();
3088 for (const auto &G
: M
.globals()) {
3089 if (G
.isThreadLocal() && !G
.isDeclaration()) {
3090 TLSVarAddress
= alignTo(TLSVarAddress
, getGVAlignment(&G
, DL
));
3091 TLSVarsToAddressMapping
[&G
] = TLSVarAddress
;
3092 TLSVarAddress
+= DL
.getTypeAllocSize(G
.getValueType());
3096 // We need to know, up front, the alignment of csects for the assembly path,
3097 // because once a .csect directive gets emitted, we could not change the
3098 // alignment value on it.
3099 for (const auto &G
: M
.globals()) {
3100 if (isSpecialLLVMGlobalArrayToSkip(&G
))
3103 if (isSpecialLLVMGlobalArrayForStaticInit(&G
)) {
3104 // Generate a format indicator and a unique module id to be a part of
3105 // the sinit and sterm function names.
3106 if (FormatIndicatorAndUniqueModId
.empty()) {
3107 std::string UniqueModuleId
= getUniqueModuleId(&M
);
3108 if (UniqueModuleId
!= "")
3109 // TODO: Use source file full path to generate the unique module id
3110 // and add a format indicator as a part of function name in case we
3111 // will support more than one format.
3112 FormatIndicatorAndUniqueModId
= "clang_" + UniqueModuleId
.substr(1);
3114 // Use threadId, Pid, and current time as the unique module id when we
3115 // cannot generate one based on a module's strong external symbols.
3117 std::chrono::duration_cast
<std::chrono::nanoseconds
>(
3118 std::chrono::steady_clock::now().time_since_epoch())
3120 FormatIndicatorAndUniqueModId
=
3121 "clangPidTidTime_" + llvm::itostr(sys::Process::getProcessId()) +
3122 "_" + llvm::itostr(llvm::get_threadid()) + "_" +
3123 llvm::itostr(CurTime
);
3127 emitSpecialLLVMGlobal(&G
);
3131 setCsectAlignment(&G
);
3132 std::optional
<CodeModel::Model
> OptionalCodeModel
= G
.getCodeModel();
3133 if (OptionalCodeModel
)
3134 setOptionalCodeModel(cast
<MCSymbolXCOFF
>(getSymbol(&G
)),
3135 *OptionalCodeModel
);
3138 for (const auto &F
: M
)
3139 setCsectAlignment(&F
);
3141 // Construct an aliasing list for each GlobalObject.
3142 for (const auto &Alias
: M
.aliases()) {
3143 const GlobalObject
*Aliasee
= Alias
.getAliaseeObject();
3146 "alias without a base object is not yet supported on AIX");
3148 if (Aliasee
->hasCommonLinkage()) {
3149 report_fatal_error("Aliases to common variables are not allowed on AIX:"
3150 "\n\tAlias attribute for " +
3151 Alias
.getGlobalIdentifier() +
3152 " is invalid because " + Aliasee
->getName() +
3157 const GlobalVariable
*GVar
=
3158 dyn_cast_or_null
<GlobalVariable
>(Alias
.getAliaseeObject());
3160 std::optional
<CodeModel::Model
> OptionalCodeModel
= GVar
->getCodeModel();
3161 if (OptionalCodeModel
)
3162 setOptionalCodeModel(cast
<MCSymbolXCOFF
>(getSymbol(&Alias
)),
3163 *OptionalCodeModel
);
3166 GOAliasMap
[Aliasee
].push_back(&Alias
);
3172 void PPCAIXAsmPrinter::emitInstruction(const MachineInstr
*MI
) {
3173 switch (MI
->getOpcode()) {
3180 if (MI
->getNumOperands() < 5)
3182 const MachineOperand
&LangMO
= MI
->getOperand(3);
3183 const MachineOperand
&ReasonMO
= MI
->getOperand(4);
3184 if (!LangMO
.isImm() || !ReasonMO
.isImm())
3186 MCSymbol
*TempSym
= OutContext
.createNamedTempSymbol();
3187 OutStreamer
->emitLabel(TempSym
);
3188 OutStreamer
->emitXCOFFExceptDirective(
3189 CurrentFnSym
, TempSym
, LangMO
.getImm(), ReasonMO
.getImm(),
3190 Subtarget
->isPPC64() ? MI
->getMF()->getInstructionCount() * 8
3191 : MI
->getMF()->getInstructionCount() * 4,
3195 case PPC::GETtlsMOD32AIX
:
3196 case PPC::GETtlsMOD64AIX
:
3197 case PPC::GETtlsTpointer32AIX
:
3198 case PPC::GETtlsADDR64AIX
:
3199 case PPC::GETtlsADDR32AIX
: {
3200 // A reference to .__tls_get_mod/.__tls_get_addr/.__get_tpointer is unknown
3201 // to the assembler so we need to emit an external symbol reference.
3202 MCSymbol
*TlsGetAddr
=
3203 createMCSymbolForTlsGetAddr(OutContext
, MI
->getOpcode());
3204 ExtSymSDNodeSymbols
.insert(TlsGetAddr
);
3211 const MachineOperand
&MO
= MI
->getOperand(0);
3212 if (MO
.isSymbol()) {
3214 cast
<MCSymbolXCOFF
>(OutContext
.getOrCreateSymbol(MO
.getSymbolName()));
3215 ExtSymSDNodeSymbols
.insert(S
);
3221 case PPC::BL8_NOP_TLS
:
3222 report_fatal_error("TLS call not yet implemented");
3228 case PPC::TAILBCTR8
:
3229 if (MI
->getOperand(0).isSymbol())
3230 report_fatal_error("Tail call for extern symbol not yet supported.");
3242 MCInstBuilder(PPC::ORI
).addReg(PPC::R0
).addReg(PPC::R0
).addImm(0));
3245 return PPCAsmPrinter::emitInstruction(MI
);
3248 bool PPCAIXAsmPrinter::doFinalization(Module
&M
) {
3249 // Do streamer related finalization for DWARF.
3250 if (hasDebugInfo()) {
3251 // Emit section end. This is used to tell the debug line section where the
3252 // end is for a text section if we don't use .loc to represent the debug
3254 auto *Sec
= OutContext
.getObjectFileInfo()->getTextSection();
3255 OutStreamer
->switchSectionNoPrint(Sec
);
3256 MCSymbol
*Sym
= Sec
->getEndSymbol(OutContext
);
3257 OutStreamer
->emitLabel(Sym
);
3260 for (MCSymbol
*Sym
: ExtSymSDNodeSymbols
)
3261 OutStreamer
->emitSymbolAttribute(Sym
, MCSA_Extern
);
3262 return PPCAsmPrinter::doFinalization(M
);
3265 static unsigned mapToSinitPriority(int P
) {
3266 if (P
< 0 || P
> 65535)
3267 report_fatal_error("invalid init priority");
3273 return 20 + (P
- 20) * 16;
3276 return 1004 + (P
- 81);
3279 return 2047 + (P
- 1124) * 33878;
3281 return 2147482625u + (P
- 64512);
3284 static std::string
convertToSinitPriority(int Priority
) {
3285 // This helper function converts clang init priority to values used in sinit
3286 // and sterm functions.
3288 // The conversion strategies are:
3289 // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm
3290 // reserved priority range [0, 1023] by
3291 // - directly mapping the first 21 and the last 20 elements of the ranges
3292 // - linear interpolating the intermediate values with a step size of 16.
3294 // We map the non reserved clang/gnu priority range of [101, 65535] into the
3295 // sinit/sterm priority range [1024, 2147483648] by:
3296 // - directly mapping the first and the last 1024 elements of the ranges
3297 // - linear interpolating the intermediate values with a step size of 33878.
3298 unsigned int P
= mapToSinitPriority(Priority
);
3300 std::string PrioritySuffix
;
3301 llvm::raw_string_ostream
os(PrioritySuffix
);
3302 os
<< llvm::format_hex_no_prefix(P
, 8);
3303 return PrioritySuffix
;
3306 void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout
&DL
,
3307 const Constant
*List
, bool IsCtor
) {
3308 SmallVector
<Structor
, 8> Structors
;
3309 preprocessXXStructorList(DL
, List
, Structors
);
3310 if (Structors
.empty())
3314 for (Structor
&S
: Structors
) {
3315 if (const ConstantExpr
*CE
= dyn_cast
<ConstantExpr
>(S
.Func
))
3316 S
.Func
= CE
->getOperand(0);
3318 llvm::GlobalAlias::create(
3319 GlobalValue::ExternalLinkage
,
3320 (IsCtor
? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +
3321 llvm::Twine(convertToSinitPriority(S
.Priority
)) +
3322 llvm::Twine("_", FormatIndicatorAndUniqueModId
) +
3323 llvm::Twine("_", llvm::utostr(Index
++)),
3324 cast
<Function
>(S
.Func
));
3328 void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue
*GV
,
3329 unsigned Encoding
) {
3331 TOCEntryType GlobalType
= TOCType_GlobalInternal
;
3332 GlobalValue::LinkageTypes Linkage
= GV
->getLinkage();
3333 if (Linkage
== GlobalValue::ExternalLinkage
||
3334 Linkage
== GlobalValue::AvailableExternallyLinkage
||
3335 Linkage
== GlobalValue::ExternalWeakLinkage
)
3336 GlobalType
= TOCType_GlobalExternal
;
3337 MCSymbol
*TypeInfoSym
= TM
.getSymbol(GV
);
3338 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(TypeInfoSym
, GlobalType
);
3339 const MCSymbol
*TOCBaseSym
=
3340 cast
<MCSectionXCOFF
>(getObjFileLowering().getTOCBaseSection())
3341 ->getQualNameSymbol();
3342 auto &Ctx
= OutStreamer
->getContext();
3344 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry
, Ctx
),
3345 MCSymbolRefExpr::create(TOCBaseSym
, Ctx
), Ctx
);
3346 OutStreamer
->emitValue(Exp
, GetSizeOfEncodedValue(Encoding
));
3348 OutStreamer
->emitIntValue(0, GetSizeOfEncodedValue(Encoding
));
3351 // Return a pass that prints the PPC assembly code for a MachineFunction to the
3352 // given output stream.
3354 createPPCAsmPrinterPass(TargetMachine
&tm
,
3355 std::unique_ptr
<MCStreamer
> &&Streamer
) {
3356 if (tm
.getTargetTriple().isOSAIX())
3357 return new PPCAIXAsmPrinter(tm
, std::move(Streamer
));
3359 return new PPCLinuxAsmPrinter(tm
, std::move(Streamer
));
3362 void PPCAIXAsmPrinter::emitModuleCommandLines(Module
&M
) {
3363 const NamedMDNode
*NMD
= M
.getNamedMetadata("llvm.commandline");
3364 if (!NMD
|| !NMD
->getNumOperands())
3368 raw_string_ostream
RSOS(S
);
3369 for (unsigned i
= 0, e
= NMD
->getNumOperands(); i
!= e
; ++i
) {
3370 const MDNode
*N
= NMD
->getOperand(i
);
3371 assert(N
->getNumOperands() == 1 &&
3372 "llvm.commandline metadata entry can have only one operand");
3373 const MDString
*MDS
= cast
<MDString
>(N
->getOperand(0));
3374 // Add "@(#)" to support retrieving the command line information with the
3375 // AIX "what" command
3376 RSOS
<< "@(#)opt " << MDS
->getString() << "\n";
3379 OutStreamer
->emitXCOFFCInfoSym(".GCC.command.line", RSOS
.str());
3382 // Force static initialization.
3383 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializePowerPCAsmPrinter() {
3384 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
3385 createPPCAsmPrinterPass
);
3386 TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
3387 createPPCAsmPrinterPass
);
3388 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
3389 createPPCAsmPrinterPass
);
3390 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
3391 createPPCAsmPrinterPass
);