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/SmallPtrSet.h"
31 #include "llvm/ADT/StringRef.h"
32 #include "llvm/ADT/Triple.h"
33 #include "llvm/ADT/Twine.h"
34 #include "llvm/BinaryFormat/ELF.h"
35 #include "llvm/CodeGen/AsmPrinter.h"
36 #include "llvm/CodeGen/MachineBasicBlock.h"
37 #include "llvm/CodeGen/MachineFunction.h"
38 #include "llvm/CodeGen/MachineInstr.h"
39 #include "llvm/CodeGen/MachineModuleInfoImpls.h"
40 #include "llvm/CodeGen/MachineOperand.h"
41 #include "llvm/CodeGen/MachineRegisterInfo.h"
42 #include "llvm/CodeGen/StackMaps.h"
43 #include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
44 #include "llvm/IR/DataLayout.h"
45 #include "llvm/IR/GlobalValue.h"
46 #include "llvm/IR/GlobalVariable.h"
47 #include "llvm/IR/Module.h"
48 #include "llvm/MC/MCAsmInfo.h"
49 #include "llvm/MC/MCContext.h"
50 #include "llvm/MC/MCDirectives.h"
51 #include "llvm/MC/MCExpr.h"
52 #include "llvm/MC/MCInst.h"
53 #include "llvm/MC/MCInstBuilder.h"
54 #include "llvm/MC/MCSectionELF.h"
55 #include "llvm/MC/MCSectionXCOFF.h"
56 #include "llvm/MC/MCStreamer.h"
57 #include "llvm/MC/MCSymbol.h"
58 #include "llvm/MC/MCSymbolELF.h"
59 #include "llvm/MC/MCSymbolXCOFF.h"
60 #include "llvm/MC/SectionKind.h"
61 #include "llvm/Support/Casting.h"
62 #include "llvm/Support/CodeGen.h"
63 #include "llvm/Support/Debug.h"
64 #include "llvm/Support/Error.h"
65 #include "llvm/Support/ErrorHandling.h"
66 #include "llvm/Support/Process.h"
67 #include "llvm/Support/TargetRegistry.h"
68 #include "llvm/Support/raw_ostream.h"
69 #include "llvm/Target/TargetMachine.h"
70 #include "llvm/Transforms/Utils/ModuleUtils.h"
78 using namespace llvm::XCOFF
;
80 #define DEBUG_TYPE "asmprinter"
82 static cl::opt
<bool> EnableSSPCanaryBitInTB(
83 "aix-ssp-tb-bit", cl::init(false),
84 cl::desc("Enable Passing SSP Canary info in Trackback on AIX"), cl::Hidden
);
86 // Specialize DenseMapInfo to allow
87 // std::pair<const MCSymbol *, MCSymbolRefExpr::VariantKind> in DenseMap.
88 // This specialization is needed here because that type is used as keys in the
89 // map representing TOC entries.
92 struct DenseMapInfo
<std::pair
<const MCSymbol
*, MCSymbolRefExpr::VariantKind
>> {
93 using TOCKey
= std::pair
<const MCSymbol
*, MCSymbolRefExpr::VariantKind
>;
95 static inline TOCKey
getEmptyKey() {
96 return {nullptr, MCSymbolRefExpr::VariantKind::VK_None
};
98 static inline TOCKey
getTombstoneKey() {
99 return {nullptr, MCSymbolRefExpr::VariantKind::VK_Invalid
};
101 static unsigned getHashValue(const TOCKey
&PairVal
) {
102 return detail::combineHashValue(
103 DenseMapInfo
<const MCSymbol
*>::getHashValue(PairVal
.first
),
104 DenseMapInfo
<int>::getHashValue(PairVal
.second
));
106 static bool isEqual(const TOCKey
&A
, const TOCKey
&B
) { return A
== B
; }
108 } // end namespace llvm
112 class PPCAsmPrinter
: public AsmPrinter
{
114 // For TLS on AIX, we need to be able to identify TOC entries of specific
115 // VariantKind so we can add the right relocations when we generate the
116 // entries. So each entry is represented by a pair of MCSymbol and
117 // VariantKind. For example, we need to be able to identify the following
118 // entry as a TLSGD entry so we can add the @m relocation:
119 // .tc .i[TC],i[TL]@m
120 // By default, VK_None is used for the VariantKind.
121 MapVector
<std::pair
<const MCSymbol
*, MCSymbolRefExpr::VariantKind
>,
124 const PPCSubtarget
*Subtarget
= nullptr;
128 explicit PPCAsmPrinter(TargetMachine
&TM
,
129 std::unique_ptr
<MCStreamer
> Streamer
)
130 : AsmPrinter(TM
, std::move(Streamer
)), SM(*this) {}
132 StringRef
getPassName() const override
{ return "PowerPC Assembly Printer"; }
134 MCSymbol
*lookUpOrCreateTOCEntry(const MCSymbol
*Sym
,
135 MCSymbolRefExpr::VariantKind Kind
=
136 MCSymbolRefExpr::VariantKind::VK_None
);
138 bool doInitialization(Module
&M
) override
{
141 return AsmPrinter::doInitialization(M
);
144 void emitInstruction(const MachineInstr
*MI
) override
;
146 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
147 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
148 /// The \p MI would be INLINEASM ONLY.
149 void printOperand(const MachineInstr
*MI
, unsigned OpNo
, raw_ostream
&O
);
151 void PrintSymbolOperand(const MachineOperand
&MO
, raw_ostream
&O
) override
;
152 bool PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
153 const char *ExtraCode
, raw_ostream
&O
) override
;
154 bool PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
155 const char *ExtraCode
, raw_ostream
&O
) override
;
157 void emitEndOfAsmFile(Module
&M
) override
;
159 void LowerSTACKMAP(StackMaps
&SM
, const MachineInstr
&MI
);
160 void LowerPATCHPOINT(StackMaps
&SM
, const MachineInstr
&MI
);
161 void EmitTlsCall(const MachineInstr
*MI
, MCSymbolRefExpr::VariantKind VK
);
162 bool runOnMachineFunction(MachineFunction
&MF
) override
{
163 Subtarget
= &MF
.getSubtarget
<PPCSubtarget
>();
164 bool Changed
= AsmPrinter::runOnMachineFunction(MF
);
170 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
171 class PPCLinuxAsmPrinter
: public PPCAsmPrinter
{
173 explicit PPCLinuxAsmPrinter(TargetMachine
&TM
,
174 std::unique_ptr
<MCStreamer
> Streamer
)
175 : PPCAsmPrinter(TM
, std::move(Streamer
)) {}
177 StringRef
getPassName() const override
{
178 return "Linux PPC Assembly Printer";
181 void emitStartOfAsmFile(Module
&M
) override
;
182 void emitEndOfAsmFile(Module
&) override
;
184 void emitFunctionEntryLabel() override
;
186 void emitFunctionBodyStart() override
;
187 void emitFunctionBodyEnd() override
;
188 void emitInstruction(const MachineInstr
*MI
) override
;
191 class PPCAIXAsmPrinter
: public PPCAsmPrinter
{
193 /// Symbols lowered from ExternalSymbolSDNodes, we will need to emit extern
194 /// linkage for them in AIX.
195 SmallPtrSet
<MCSymbol
*, 8> ExtSymSDNodeSymbols
;
197 /// A format indicator and unique trailing identifier to form part of the
198 /// sinit/sterm function names.
199 std::string FormatIndicatorAndUniqueModId
;
201 // Record a list of GlobalAlias associated with a GlobalObject.
202 // This is used for AIX's extra-label-at-definition aliasing strategy.
203 DenseMap
<const GlobalObject
*, SmallVector
<const GlobalAlias
*, 1>>
206 uint16_t getNumberOfVRSaved();
207 void emitTracebackTable();
209 SmallVector
<const GlobalVariable
*, 8> TOCDataGlobalVars
;
211 void emitGlobalVariableHelper(const GlobalVariable
*);
214 PPCAIXAsmPrinter(TargetMachine
&TM
, std::unique_ptr
<MCStreamer
> Streamer
)
215 : PPCAsmPrinter(TM
, std::move(Streamer
)) {
216 if (MAI
->isLittleEndian())
218 "cannot create AIX PPC Assembly Printer for a little-endian target");
221 StringRef
getPassName() const override
{ return "AIX PPC Assembly Printer"; }
223 bool doInitialization(Module
&M
) override
;
225 void emitXXStructorList(const DataLayout
&DL
, const Constant
*List
,
226 bool IsCtor
) override
;
228 void SetupMachineFunction(MachineFunction
&MF
) override
;
230 void emitGlobalVariable(const GlobalVariable
*GV
) override
;
232 void emitFunctionDescriptor() override
;
234 void emitFunctionEntryLabel() override
;
236 void emitFunctionBodyEnd() override
;
238 void emitEndOfAsmFile(Module
&) override
;
240 void emitLinkage(const GlobalValue
*GV
, MCSymbol
*GVSym
) const override
;
242 void emitInstruction(const MachineInstr
*MI
) override
;
244 bool doFinalization(Module
&M
) override
;
246 void emitTTypeReference(const GlobalValue
*GV
, unsigned Encoding
) override
;
249 } // end anonymous namespace
251 void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand
&MO
,
253 // Computing the address of a global symbol, not calling it.
254 const GlobalValue
*GV
= MO
.getGlobal();
255 getSymbol(GV
)->print(O
, MAI
);
256 printOffset(MO
.getOffset(), O
);
259 void PPCAsmPrinter::printOperand(const MachineInstr
*MI
, unsigned OpNo
,
261 const DataLayout
&DL
= getDataLayout();
262 const MachineOperand
&MO
= MI
->getOperand(OpNo
);
264 switch (MO
.getType()) {
265 case MachineOperand::MO_Register
: {
266 // The MI is INLINEASM ONLY and UseVSXReg is always false.
267 const char *RegName
= PPCInstPrinter::getRegisterName(MO
.getReg());
269 // Linux assembler (Others?) does not take register mnemonics.
270 // FIXME - What about special registers used in mfspr/mtspr?
271 O
<< PPCRegisterInfo::stripRegisterPrefix(RegName
);
274 case MachineOperand::MO_Immediate
:
278 case MachineOperand::MO_MachineBasicBlock
:
279 MO
.getMBB()->getSymbol()->print(O
, MAI
);
281 case MachineOperand::MO_ConstantPoolIndex
:
282 O
<< DL
.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
285 case MachineOperand::MO_BlockAddress
:
286 GetBlockAddressSymbol(MO
.getBlockAddress())->print(O
, MAI
);
288 case MachineOperand::MO_GlobalAddress
: {
289 PrintSymbolOperand(MO
, O
);
294 O
<< "<unknown operand type: " << (unsigned)MO
.getType() << ">";
299 /// PrintAsmOperand - Print out an operand for an inline asm expression.
301 bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr
*MI
, unsigned OpNo
,
302 const char *ExtraCode
, raw_ostream
&O
) {
303 // Does this asm operand have a single letter operand modifier?
304 if (ExtraCode
&& ExtraCode
[0]) {
305 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
307 switch (ExtraCode
[0]) {
309 // See if this is a generic print operand
310 return AsmPrinter::PrintAsmOperand(MI
, OpNo
, ExtraCode
, O
);
311 case 'L': // Write second word of DImode reference.
312 // Verify that this operand has two consecutive registers.
313 if (!MI
->getOperand(OpNo
).isReg() ||
314 OpNo
+1 == MI
->getNumOperands() ||
315 !MI
->getOperand(OpNo
+1).isReg())
317 ++OpNo
; // Return the high-part.
320 // Write 'i' if an integer constant, otherwise nothing. Used to print
322 if (MI
->getOperand(OpNo
).isImm())
326 if(!MI
->getOperand(OpNo
).isReg())
328 // This operand uses VSX numbering.
329 // If the operand is a VMX register, convert it to a VSX register.
330 Register Reg
= MI
->getOperand(OpNo
).getReg();
331 if (PPCInstrInfo::isVRRegister(Reg
))
332 Reg
= PPC::VSX32
+ (Reg
- PPC::V0
);
333 else if (PPCInstrInfo::isVFRegister(Reg
))
334 Reg
= PPC::VSX32
+ (Reg
- PPC::VF0
);
336 RegName
= PPCInstPrinter::getRegisterName(Reg
);
337 RegName
= PPCRegisterInfo::stripRegisterPrefix(RegName
);
343 printOperand(MI
, OpNo
, O
);
347 // At the moment, all inline asm memory operands are a single register.
348 // In any case, the output of this routine should always be just one
349 // assembler operand.
351 bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr
*MI
, unsigned OpNo
,
352 const char *ExtraCode
,
354 if (ExtraCode
&& ExtraCode
[0]) {
355 if (ExtraCode
[1] != 0) return true; // Unknown modifier.
357 switch (ExtraCode
[0]) {
358 default: return true; // Unknown modifier.
359 case 'L': // A memory reference to the upper word of a double word op.
360 O
<< getDataLayout().getPointerSize() << "(";
361 printOperand(MI
, OpNo
, O
);
364 case 'y': // A memory reference for an X-form instruction
366 printOperand(MI
, OpNo
, O
);
369 // Write 'i' if an integer constant, otherwise nothing. Used to print
371 if (MI
->getOperand(OpNo
).isImm())
374 case 'U': // Print 'u' for update form.
375 case 'X': // Print 'x' for indexed form.
376 // FIXME: Currently for PowerPC memory operands are always loaded
377 // into a register, so we never get an update or indexed form.
378 // This is bad even for offset forms, since even if we know we
379 // have a value in -16(r1), we will generate a load into r<n>
380 // and then load from 0(r<n>). Until that issue is fixed,
381 // tolerate 'U' and 'X' but don't output anything.
382 assert(MI
->getOperand(OpNo
).isReg());
387 assert(MI
->getOperand(OpNo
).isReg());
389 printOperand(MI
, OpNo
, O
);
394 /// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
395 /// exists for it. If not, create one. Then return a symbol that references
398 PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol
*Sym
,
399 MCSymbolRefExpr::VariantKind Kind
) {
400 MCSymbol
*&TOCEntry
= TOC
[{Sym
, Kind
}];
402 TOCEntry
= createTempSymbol("C");
406 void PPCAsmPrinter::emitEndOfAsmFile(Module
&M
) {
410 void PPCAsmPrinter::LowerSTACKMAP(StackMaps
&SM
, const MachineInstr
&MI
) {
411 unsigned NumNOPBytes
= MI
.getOperand(1).getImm();
413 auto &Ctx
= OutStreamer
->getContext();
414 MCSymbol
*MILabel
= Ctx
.createTempSymbol();
415 OutStreamer
->emitLabel(MILabel
);
417 SM
.recordStackMap(*MILabel
, MI
);
418 assert(NumNOPBytes
% 4 == 0 && "Invalid number of NOP bytes requested!");
420 // Scan ahead to trim the shadow.
421 const MachineBasicBlock
&MBB
= *MI
.getParent();
422 MachineBasicBlock::const_iterator
MII(MI
);
424 while (NumNOPBytes
> 0) {
425 if (MII
== MBB
.end() || MII
->isCall() ||
426 MII
->getOpcode() == PPC::DBG_VALUE
||
427 MII
->getOpcode() == TargetOpcode::PATCHPOINT
||
428 MII
->getOpcode() == TargetOpcode::STACKMAP
)
435 for (unsigned i
= 0; i
< NumNOPBytes
; i
+= 4)
436 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
439 // Lower a patchpoint of the form:
440 // [<def>], <id>, <numBytes>, <target>, <numArgs>
441 void PPCAsmPrinter::LowerPATCHPOINT(StackMaps
&SM
, const MachineInstr
&MI
) {
442 auto &Ctx
= OutStreamer
->getContext();
443 MCSymbol
*MILabel
= Ctx
.createTempSymbol();
444 OutStreamer
->emitLabel(MILabel
);
446 SM
.recordPatchPoint(*MILabel
, MI
);
447 PatchPointOpers
Opers(&MI
);
449 unsigned EncodedBytes
= 0;
450 const MachineOperand
&CalleeMO
= Opers
.getCallTarget();
452 if (CalleeMO
.isImm()) {
453 int64_t CallTarget
= CalleeMO
.getImm();
455 assert((CallTarget
& 0xFFFFFFFFFFFF) == CallTarget
&&
456 "High 16 bits of call target should be zero.");
457 Register ScratchReg
= MI
.getOperand(Opers
.getNextScratchIdx()).getReg();
459 // Materialize the jump address:
460 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LI8
)
462 .addImm((CallTarget
>> 32) & 0xFFFF));
464 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::RLDIC
)
467 .addImm(32).addImm(16));
469 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ORIS8
)
472 .addImm((CallTarget
>> 16) & 0xFFFF));
474 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ORI8
)
477 .addImm(CallTarget
& 0xFFFF));
479 // Save the current TOC pointer before the remote call.
480 int TOCSaveOffset
= Subtarget
->getFrameLowering()->getTOCSaveOffset();
481 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::STD
)
483 .addImm(TOCSaveOffset
)
487 // If we're on ELFv1, then we need to load the actual function pointer
488 // from the function descriptor.
489 if (!Subtarget
->isELFv2ABI()) {
490 // Load the new TOC pointer and the function address, but not r11
491 // (needing this is rare, and loading it here would prevent passing it
492 // via a 'nest' parameter.
493 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
496 .addReg(ScratchReg
));
498 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
501 .addReg(ScratchReg
));
505 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MTCTR8
)
506 .addReg(ScratchReg
));
508 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BCTRL8
));
511 // Restore the TOC pointer after the call.
512 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
514 .addImm(TOCSaveOffset
)
518 } else if (CalleeMO
.isGlobal()) {
519 const GlobalValue
*GValue
= CalleeMO
.getGlobal();
520 MCSymbol
*MOSymbol
= getSymbol(GValue
);
521 const MCExpr
*SymVar
= MCSymbolRefExpr::create(MOSymbol
, OutContext
);
523 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BL8_NOP
)
528 // Each instruction is 4 bytes.
532 unsigned NumBytes
= Opers
.getNumPatchBytes();
533 assert(NumBytes
>= EncodedBytes
&&
534 "Patchpoint can't request size less than the length of a call.");
535 assert((NumBytes
- EncodedBytes
) % 4 == 0 &&
536 "Invalid number of NOP bytes requested!");
537 for (unsigned i
= EncodedBytes
; i
< NumBytes
; i
+= 4)
538 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
541 /// This helper function creates the TlsGetAddr MCSymbol for AIX. We will
542 /// create the csect and use the qual-name symbol instead of creating just the
544 static MCSymbol
*createMCSymbolForTlsGetAddr(MCContext
&Ctx
) {
546 .getXCOFFSection(".__tls_get_addr", SectionKind::getText(),
547 XCOFF::CsectProperties(XCOFF::XMC_PR
, XCOFF::XTY_ER
))
548 ->getQualNameSymbol();
551 /// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
552 /// call to __tls_get_addr to the current output stream.
553 void PPCAsmPrinter::EmitTlsCall(const MachineInstr
*MI
,
554 MCSymbolRefExpr::VariantKind VK
) {
555 MCSymbolRefExpr::VariantKind Kind
= MCSymbolRefExpr::VK_None
;
556 unsigned Opcode
= PPC::BL8_NOP_TLS
;
558 assert(MI
->getNumOperands() >= 3 && "Expecting at least 3 operands from MI");
559 if (MI
->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSGD_PCREL_FLAG
||
560 MI
->getOperand(2).getTargetFlags() == PPCII::MO_GOT_TLSLD_PCREL_FLAG
) {
561 Kind
= MCSymbolRefExpr::VK_PPC_NOTOC
;
562 Opcode
= PPC::BL8_NOTOC_TLS
;
564 const Module
*M
= MF
->getFunction().getParent();
566 assert(MI
->getOperand(0).isReg() &&
567 ((Subtarget
->isPPC64() && MI
->getOperand(0).getReg() == PPC::X3
) ||
568 (!Subtarget
->isPPC64() && MI
->getOperand(0).getReg() == PPC::R3
)) &&
569 "GETtls[ld]ADDR[32] must define GPR3");
570 assert(MI
->getOperand(1).isReg() &&
571 ((Subtarget
->isPPC64() && MI
->getOperand(1).getReg() == PPC::X3
) ||
572 (!Subtarget
->isPPC64() && MI
->getOperand(1).getReg() == PPC::R3
)) &&
573 "GETtls[ld]ADDR[32] must read GPR3");
575 if (Subtarget
->isAIXABI()) {
576 // On AIX, the variable offset should already be in R4 and the region handle
577 // should already be in R3.
578 // For TLSGD, which currently is the only supported access model, we only
579 // need to generate an absolute branch to .__tls_get_addr.
580 Register VarOffsetReg
= Subtarget
->isPPC64() ? PPC::X4
: PPC::R4
;
582 assert(MI
->getOperand(2).isReg() &&
583 MI
->getOperand(2).getReg() == VarOffsetReg
&&
584 "GETtls[ld]ADDR[32] must read GPR4");
585 MCSymbol
*TlsGetAddr
= createMCSymbolForTlsGetAddr(OutContext
);
586 const MCExpr
*TlsRef
= MCSymbolRefExpr::create(
587 TlsGetAddr
, MCSymbolRefExpr::VK_None
, OutContext
);
588 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BLA
).addExpr(TlsRef
));
592 MCSymbol
*TlsGetAddr
= OutContext
.getOrCreateSymbol("__tls_get_addr");
594 if (Subtarget
->is32BitELFABI() && isPositionIndependent())
595 Kind
= MCSymbolRefExpr::VK_PLT
;
597 const MCExpr
*TlsRef
=
598 MCSymbolRefExpr::create(TlsGetAddr
, Kind
, OutContext
);
600 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
601 if (Kind
== MCSymbolRefExpr::VK_PLT
&& Subtarget
->isSecurePlt() &&
602 M
->getPICLevel() == PICLevel::BigPIC
)
603 TlsRef
= MCBinaryExpr::createAdd(
604 TlsRef
, MCConstantExpr::create(32768, OutContext
), OutContext
);
605 const MachineOperand
&MO
= MI
->getOperand(2);
606 const GlobalValue
*GValue
= MO
.getGlobal();
607 MCSymbol
*MOSymbol
= getSymbol(GValue
);
608 const MCExpr
*SymVar
= MCSymbolRefExpr::create(MOSymbol
, VK
, OutContext
);
609 EmitToStreamer(*OutStreamer
,
610 MCInstBuilder(Subtarget
->isPPC64() ? Opcode
611 : (unsigned)PPC::BL_TLS
)
616 /// Map a machine operand for a TOC pseudo-machine instruction to its
617 /// corresponding MCSymbol.
618 static MCSymbol
*getMCSymbolForTOCPseudoMO(const MachineOperand
&MO
,
620 switch (MO
.getType()) {
621 case MachineOperand::MO_GlobalAddress
:
622 return AP
.getSymbol(MO
.getGlobal());
623 case MachineOperand::MO_ConstantPoolIndex
:
624 return AP
.GetCPISymbol(MO
.getIndex());
625 case MachineOperand::MO_JumpTableIndex
:
626 return AP
.GetJTISymbol(MO
.getIndex());
627 case MachineOperand::MO_BlockAddress
:
628 return AP
.GetBlockAddressSymbol(MO
.getBlockAddress());
630 llvm_unreachable("Unexpected operand type to get symbol.");
634 /// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
635 /// the current output stream.
637 void PPCAsmPrinter::emitInstruction(const MachineInstr
*MI
) {
639 const bool IsPPC64
= Subtarget
->isPPC64();
640 const bool IsAIX
= Subtarget
->isAIXABI();
641 const Module
*M
= MF
->getFunction().getParent();
642 PICLevel::Level PL
= M
->getPICLevel();
645 // Validate that SPE and FPU are mutually exclusive in codegen
646 if (!MI
->isInlineAsm()) {
647 for (const MachineOperand
&MO
: MI
->operands()) {
649 Register Reg
= MO
.getReg();
650 if (Subtarget
->hasSPE()) {
651 if (PPC::F4RCRegClass
.contains(Reg
) ||
652 PPC::F8RCRegClass
.contains(Reg
) ||
653 PPC::VFRCRegClass
.contains(Reg
) ||
654 PPC::VRRCRegClass
.contains(Reg
) ||
655 PPC::VSFRCRegClass
.contains(Reg
) ||
656 PPC::VSSRCRegClass
.contains(Reg
)
658 llvm_unreachable("SPE targets cannot have FPRegs!");
660 if (PPC::SPERCRegClass
.contains(Reg
))
661 llvm_unreachable("SPE register found in FPU-targeted code!");
668 auto getTOCRelocAdjustedExprForXCOFF
= [this](const MCExpr
*Expr
,
669 ptrdiff_t OriginalOffset
) {
670 // Apply an offset to the TOC-based expression such that the adjusted
671 // notional offset from the TOC base (to be encoded into the instruction's D
672 // or DS field) is the signed 16-bit truncation of the original notional
673 // offset from the TOC base.
674 // This is consistent with the treatment used both by XL C/C++ and
676 ptrdiff_t Adjustment
=
677 OriginalOffset
- llvm::SignExtend32
<16>(OriginalOffset
);
678 return MCBinaryExpr::createAdd(
679 Expr
, MCConstantExpr::create(-Adjustment
, OutContext
), OutContext
);
682 auto getTOCEntryLoadingExprForXCOFF
=
683 [IsPPC64
, getTOCRelocAdjustedExprForXCOFF
,
684 this](const MCSymbol
*MOSymbol
, const MCExpr
*Expr
,
685 MCSymbolRefExpr::VariantKind VK
=
686 MCSymbolRefExpr::VariantKind::VK_None
) -> const MCExpr
* {
687 const unsigned EntryByteSize
= IsPPC64
? 8 : 4;
688 const auto TOCEntryIter
= TOC
.find({MOSymbol
, VK
});
689 assert(TOCEntryIter
!= TOC
.end() &&
690 "Could not find the TOC entry for this symbol.");
691 const ptrdiff_t EntryDistanceFromTOCBase
=
692 (TOCEntryIter
- TOC
.begin()) * EntryByteSize
;
693 constexpr int16_t PositiveTOCRange
= INT16_MAX
;
695 if (EntryDistanceFromTOCBase
> PositiveTOCRange
)
696 return getTOCRelocAdjustedExprForXCOFF(Expr
, EntryDistanceFromTOCBase
);
700 auto GetVKForMO
= [&](const MachineOperand
&MO
) {
701 // For GD TLS access on AIX, we have two TOC entries for the symbol (one for
702 // the variable offset and the other for the region handle). They are
703 // differentiated by MO_TLSGD_FLAG and MO_TLSGDM_FLAG.
704 if (MO
.getTargetFlags() & PPCII::MO_TLSGDM_FLAG
)
705 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM
;
706 if (MO
.getTargetFlags() & PPCII::MO_TLSGD_FLAG
)
707 return MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGD
;
708 return MCSymbolRefExpr::VariantKind::VK_None
;
711 // Lower multi-instruction pseudo operations.
712 switch (MI
->getOpcode()) {
714 case TargetOpcode::DBG_VALUE
:
715 llvm_unreachable("Should be handled target independently");
716 case TargetOpcode::STACKMAP
:
717 return LowerSTACKMAP(SM
, *MI
);
718 case TargetOpcode::PATCHPOINT
:
719 return LowerPATCHPOINT(SM
, *MI
);
721 case PPC::MoveGOTtoLR
: {
722 // Transform %lr = MoveGOTtoLR
723 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
724 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
725 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
727 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
728 MCSymbol
*GOTSymbol
=
729 OutContext
.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
730 const MCExpr
*OffsExpr
=
731 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol
,
732 MCSymbolRefExpr::VK_PPC_LOCAL
,
734 MCConstantExpr::create(4, OutContext
),
738 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BL
).addExpr(OffsExpr
));
741 case PPC::MovePCtoLR
:
742 case PPC::MovePCtoLR8
: {
743 // Transform %lr = MovePCtoLR
744 // Into this, where the label is the PIC base:
747 MCSymbol
*PICBase
= MF
->getPICBaseSymbol();
750 EmitToStreamer(*OutStreamer
,
751 MCInstBuilder(PPC::BL
)
752 // FIXME: We would like an efficient form for this, so we
753 // don't have to do a lot of extra uniquing.
754 .addExpr(MCSymbolRefExpr::create(PICBase
, OutContext
)));
757 OutStreamer
->emitLabel(PICBase
);
760 case PPC::UpdateGBR
: {
761 // Transform %rd = UpdateGBR(%rt, %ri)
762 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
764 // or into (if secure plt mode is on):
765 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
766 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
767 // Get the offset from the GOT Base Register to the GOT
768 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
769 if (Subtarget
->isSecurePlt() && isPositionIndependent() ) {
770 unsigned PICR
= TmpInst
.getOperand(0).getReg();
771 MCSymbol
*BaseSymbol
= OutContext
.getOrCreateSymbol(
772 M
->getPICLevel() == PICLevel::SmallPIC
? "_GLOBAL_OFFSET_TABLE_"
775 MCSymbolRefExpr::create(MF
->getPICBaseSymbol(), OutContext
);
777 const MCExpr
*DeltaExpr
= MCBinaryExpr::createSub(
778 MCSymbolRefExpr::create(BaseSymbol
, OutContext
), PB
, OutContext
);
780 const MCExpr
*DeltaHi
= PPCMCExpr::createHa(DeltaExpr
, OutContext
);
783 MCInstBuilder(PPC::ADDIS
).addReg(PICR
).addReg(PICR
).addExpr(DeltaHi
));
785 const MCExpr
*DeltaLo
= PPCMCExpr::createLo(DeltaExpr
, OutContext
);
788 MCInstBuilder(PPC::ADDI
).addReg(PICR
).addReg(PICR
).addExpr(DeltaLo
));
791 MCSymbol
*PICOffset
=
792 MF
->getInfo
<PPCFunctionInfo
>()->getPICOffsetSymbol(*MF
);
793 TmpInst
.setOpcode(PPC::LWZ
);
795 MCSymbolRefExpr::create(PICOffset
, MCSymbolRefExpr::VK_None
, OutContext
);
797 MCSymbolRefExpr::create(MF
->getPICBaseSymbol(),
798 MCSymbolRefExpr::VK_None
,
800 const MCOperand TR
= TmpInst
.getOperand(1);
801 const MCOperand PICR
= TmpInst
.getOperand(0);
803 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
804 TmpInst
.getOperand(1) =
805 MCOperand::createExpr(MCBinaryExpr::createSub(Exp
, PB
, OutContext
));
806 TmpInst
.getOperand(0) = TR
;
807 TmpInst
.getOperand(2) = PICR
;
808 EmitToStreamer(*OutStreamer
, TmpInst
);
810 TmpInst
.setOpcode(PPC::ADD4
);
811 TmpInst
.getOperand(0) = PICR
;
812 TmpInst
.getOperand(1) = TR
;
813 TmpInst
.getOperand(2) = PICR
;
814 EmitToStreamer(*OutStreamer
, TmpInst
);
819 // Transform %rN = LWZtoc @op1, %r2
820 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
822 // Change the opcode to LWZ.
823 TmpInst
.setOpcode(PPC::LWZ
);
825 const MachineOperand
&MO
= MI
->getOperand(1);
826 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
827 "Invalid operand for LWZtoc.");
829 // Map the operand to its corresponding MCSymbol.
830 const MCSymbol
*const MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
832 // Create a reference to the GOT entry for the symbol. The GOT entry will be
833 // synthesized later.
834 if (PL
== PICLevel::SmallPIC
&& !IsAIX
) {
836 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_GOT
,
838 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
839 EmitToStreamer(*OutStreamer
, TmpInst
);
843 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
845 // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the
846 // storage allocated in the TOC which contains the address of
847 // 'MOSymbol'. Said TOC entry will be synthesized later.
848 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(MOSymbol
, VK
);
850 MCSymbolRefExpr::create(TOCEntry
, MCSymbolRefExpr::VK_None
, OutContext
);
852 // AIX uses the label directly as the lwz displacement operand for
853 // references into the toc section. The displacement value will be generated
854 // relative to the toc-base.
857 TM
.getCodeModel() == CodeModel::Small
&&
858 "This pseudo should only be selected for 32-bit small code model.");
859 Exp
= getTOCEntryLoadingExprForXCOFF(MOSymbol
, Exp
, VK
);
860 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
862 // Print MO for better readability
864 OutStreamer
->GetCommentOS() << MO
<< '\n';
865 EmitToStreamer(*OutStreamer
, TmpInst
);
869 // Create an explicit subtract expression between the local symbol and
870 // '.LTOC' to manifest the toc-relative offset.
871 const MCExpr
*PB
= MCSymbolRefExpr::create(
872 OutContext
.getOrCreateSymbol(Twine(".LTOC")), OutContext
);
873 Exp
= MCBinaryExpr::createSub(Exp
, PB
, OutContext
);
874 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
875 EmitToStreamer(*OutStreamer
, TmpInst
);
879 assert(IsAIX
&& TM
.getCodeModel() == CodeModel::Small
&&
880 "Operand only valid in AIX 32 bit mode");
882 // Transform %rN = ADDItoc @op1, %r2.
883 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
885 // Change the opcode to load address.
886 TmpInst
.setOpcode(PPC::LA
);
888 const MachineOperand
&MO
= MI
->getOperand(1);
889 assert(MO
.isGlobal() && "Invalid operand for ADDItoc.");
891 // Map the operand to its corresponding MCSymbol.
892 const MCSymbol
*const MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
895 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_None
, OutContext
);
897 TmpInst
.getOperand(1) = TmpInst
.getOperand(2);
898 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
899 EmitToStreamer(*OutStreamer
, TmpInst
);
906 // Transform %x3 = LDtoc @min1, %x2
907 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
909 // Change the opcode to LD.
910 TmpInst
.setOpcode(PPC::LD
);
912 const MachineOperand
&MO
= MI
->getOperand(1);
913 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
916 // Map the operand to its corresponding MCSymbol.
917 const MCSymbol
*const MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
919 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
921 // Map the machine operand to its corresponding MCSymbol, then map the
922 // global address operand to be a reference to the TOC entry we will
924 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(MOSymbol
, VK
);
926 MCSymbolRefExpr::VariantKind VKExpr
=
927 IsAIX
? MCSymbolRefExpr::VK_None
: MCSymbolRefExpr::VK_PPC_TOC
;
928 const MCExpr
*Exp
= MCSymbolRefExpr::create(TOCEntry
, VKExpr
, OutContext
);
929 TmpInst
.getOperand(1) = MCOperand::createExpr(
930 IsAIX
? getTOCEntryLoadingExprForXCOFF(MOSymbol
, Exp
, VK
) : Exp
);
932 // Print MO for better readability
933 if (isVerbose() && IsAIX
)
934 OutStreamer
->GetCommentOS() << MO
<< '\n';
935 EmitToStreamer(*OutStreamer
, TmpInst
);
938 case PPC::ADDIStocHA
: {
939 assert((IsAIX
&& !IsPPC64
&& TM
.getCodeModel() == CodeModel::Large
) &&
940 "This pseudo should only be selected for 32-bit large code model on"
943 // Transform %rd = ADDIStocHA %rA, @sym(%r2)
944 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
946 // Change the opcode to ADDIS.
947 TmpInst
.setOpcode(PPC::ADDIS
);
949 const MachineOperand
&MO
= MI
->getOperand(2);
950 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
951 "Invalid operand for ADDIStocHA.");
953 // Map the machine operand to its corresponding MCSymbol.
954 MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
956 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
958 // Always use TOC on AIX. Map the global address operand to be a reference
959 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
960 // reference the storage allocated in the TOC which contains the address of
962 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(MOSymbol
, VK
);
963 const MCExpr
*Exp
= MCSymbolRefExpr::create(TOCEntry
,
964 MCSymbolRefExpr::VK_PPC_U
,
966 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
967 EmitToStreamer(*OutStreamer
, TmpInst
);
971 assert(IsAIX
&& !IsPPC64
&& TM
.getCodeModel() == CodeModel::Large
&&
972 "This pseudo should only be selected for 32-bit large code model on"
975 // Transform %rd = LWZtocL @sym, %rs.
976 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
978 // Change the opcode to lwz.
979 TmpInst
.setOpcode(PPC::LWZ
);
981 const MachineOperand
&MO
= MI
->getOperand(1);
982 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
983 "Invalid operand for LWZtocL.");
985 // Map the machine operand to its corresponding MCSymbol.
986 MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
988 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
990 // Always use TOC on AIX. Map the global address operand to be a reference
991 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
992 // reference the storage allocated in the TOC which contains the address of
994 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(MOSymbol
, VK
);
995 const MCExpr
*Exp
= MCSymbolRefExpr::create(TOCEntry
,
996 MCSymbolRefExpr::VK_PPC_L
,
998 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
999 EmitToStreamer(*OutStreamer
, TmpInst
);
1002 case PPC::ADDIStocHA8
: {
1003 // Transform %xd = ADDIStocHA8 %x2, @sym
1004 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1006 // Change the opcode to ADDIS8. If the global address is the address of
1007 // an external symbol, is a jump table address, is a block address, or is a
1008 // constant pool index with large code model enabled, then generate a TOC
1009 // entry and reference that. Otherwise, reference the symbol directly.
1010 TmpInst
.setOpcode(PPC::ADDIS8
);
1012 const MachineOperand
&MO
= MI
->getOperand(2);
1013 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() || MO
.isBlockAddress()) &&
1014 "Invalid operand for ADDIStocHA8!");
1016 const MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1018 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1020 const bool GlobalToc
=
1021 MO
.isGlobal() && Subtarget
->isGVIndirectSymbol(MO
.getGlobal());
1022 if (GlobalToc
|| MO
.isJTI() || MO
.isBlockAddress() ||
1023 (MO
.isCPI() && TM
.getCodeModel() == CodeModel::Large
))
1024 MOSymbol
= lookUpOrCreateTOCEntry(MOSymbol
, VK
);
1026 VK
= IsAIX
? MCSymbolRefExpr::VK_PPC_U
: MCSymbolRefExpr::VK_PPC_TOC_HA
;
1029 MCSymbolRefExpr::create(MOSymbol
, VK
, OutContext
);
1031 if (!MO
.isJTI() && MO
.getOffset())
1032 Exp
= MCBinaryExpr::createAdd(Exp
,
1033 MCConstantExpr::create(MO
.getOffset(),
1037 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
1038 EmitToStreamer(*OutStreamer
, TmpInst
);
1042 // Transform %xd = LDtocL @sym, %xs
1043 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1045 // Change the opcode to LD. If the global address is the address of
1046 // an external symbol, is a jump table address, is a block address, or is
1047 // a constant pool index with large code model enabled, then generate a
1048 // TOC entry and reference that. Otherwise, reference the symbol directly.
1049 TmpInst
.setOpcode(PPC::LD
);
1051 const MachineOperand
&MO
= MI
->getOperand(1);
1052 assert((MO
.isGlobal() || MO
.isCPI() || MO
.isJTI() ||
1053 MO
.isBlockAddress()) &&
1054 "Invalid operand for LDtocL!");
1057 (!MO
.isGlobal() || Subtarget
->isGVIndirectSymbol(MO
.getGlobal())) &&
1058 "LDtocL used on symbol that could be accessed directly is "
1059 "invalid. Must match ADDIStocHA8."));
1061 const MCSymbol
*MOSymbol
= getMCSymbolForTOCPseudoMO(MO
, *this);
1063 MCSymbolRefExpr::VariantKind VK
= GetVKForMO(MO
);
1065 if (!MO
.isCPI() || TM
.getCodeModel() == CodeModel::Large
)
1066 MOSymbol
= lookUpOrCreateTOCEntry(MOSymbol
, VK
);
1068 VK
= IsAIX
? MCSymbolRefExpr::VK_PPC_L
: MCSymbolRefExpr::VK_PPC_TOC_LO
;
1070 MCSymbolRefExpr::create(MOSymbol
, VK
, OutContext
);
1071 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1072 EmitToStreamer(*OutStreamer
, TmpInst
);
1075 case PPC::ADDItocL
: {
1076 // Transform %xd = ADDItocL %xs, @sym
1077 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1079 // Change the opcode to ADDI8. If the global address is external, then
1080 // generate a TOC entry and reference that. Otherwise, reference the
1082 TmpInst
.setOpcode(PPC::ADDI8
);
1084 const MachineOperand
&MO
= MI
->getOperand(2);
1085 assert((MO
.isGlobal() || MO
.isCPI()) && "Invalid operand for ADDItocL.");
1088 !(MO
.isGlobal() && Subtarget
->isGVIndirectSymbol(MO
.getGlobal())) &&
1089 "Interposable definitions must use indirect access."));
1092 MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO
, *this),
1093 MCSymbolRefExpr::VK_PPC_TOC_LO
, OutContext
);
1094 TmpInst
.getOperand(2) = MCOperand::createExpr(Exp
);
1095 EmitToStreamer(*OutStreamer
, TmpInst
);
1098 case PPC::ADDISgotTprelHA
: {
1099 // Transform: %xd = ADDISgotTprelHA %x2, @sym
1100 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1101 assert(IsPPC64
&& "Not supported for 32-bit PowerPC");
1102 const MachineOperand
&MO
= MI
->getOperand(2);
1103 const GlobalValue
*GValue
= MO
.getGlobal();
1104 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1105 const MCExpr
*SymGotTprel
=
1106 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA
,
1108 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS8
)
1109 .addReg(MI
->getOperand(0).getReg())
1110 .addReg(MI
->getOperand(1).getReg())
1111 .addExpr(SymGotTprel
));
1114 case PPC::LDgotTprelL
:
1115 case PPC::LDgotTprelL32
: {
1116 // Transform %xd = LDgotTprelL @sym, %xs
1117 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1119 // Change the opcode to LD.
1120 TmpInst
.setOpcode(IsPPC64
? PPC::LD
: PPC::LWZ
);
1121 const MachineOperand
&MO
= MI
->getOperand(1);
1122 const GlobalValue
*GValue
= MO
.getGlobal();
1123 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1124 const MCExpr
*Exp
= MCSymbolRefExpr::create(
1125 MOSymbol
, IsPPC64
? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO
1126 : MCSymbolRefExpr::VK_PPC_GOT_TPREL
,
1128 TmpInst
.getOperand(1) = MCOperand::createExpr(Exp
);
1129 EmitToStreamer(*OutStreamer
, TmpInst
);
1133 case PPC::PPC32PICGOT
: {
1134 MCSymbol
*GOTSymbol
= OutContext
.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1135 MCSymbol
*GOTRef
= OutContext
.createTempSymbol();
1136 MCSymbol
*NextInstr
= OutContext
.createTempSymbol();
1138 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::BL
)
1139 // FIXME: We would like an efficient form for this, so we don't have to do
1140 // a lot of extra uniquing.
1141 .addExpr(MCSymbolRefExpr::create(NextInstr
, OutContext
)));
1142 const MCExpr
*OffsExpr
=
1143 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol
, OutContext
),
1144 MCSymbolRefExpr::create(GOTRef
, OutContext
),
1146 OutStreamer
->emitLabel(GOTRef
);
1147 OutStreamer
->emitValue(OffsExpr
, 4);
1148 OutStreamer
->emitLabel(NextInstr
);
1149 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MFLR
)
1150 .addReg(MI
->getOperand(0).getReg()));
1151 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LWZ
)
1152 .addReg(MI
->getOperand(1).getReg())
1154 .addReg(MI
->getOperand(0).getReg()));
1155 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADD4
)
1156 .addReg(MI
->getOperand(0).getReg())
1157 .addReg(MI
->getOperand(1).getReg())
1158 .addReg(MI
->getOperand(0).getReg()));
1161 case PPC::PPC32GOT
: {
1162 MCSymbol
*GOTSymbol
=
1163 OutContext
.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
1164 const MCExpr
*SymGotTlsL
= MCSymbolRefExpr::create(
1165 GOTSymbol
, MCSymbolRefExpr::VK_PPC_LO
, OutContext
);
1166 const MCExpr
*SymGotTlsHA
= MCSymbolRefExpr::create(
1167 GOTSymbol
, MCSymbolRefExpr::VK_PPC_HA
, OutContext
);
1168 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LI
)
1169 .addReg(MI
->getOperand(0).getReg())
1170 .addExpr(SymGotTlsL
));
1171 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS
)
1172 .addReg(MI
->getOperand(0).getReg())
1173 .addReg(MI
->getOperand(0).getReg())
1174 .addExpr(SymGotTlsHA
));
1177 case PPC::ADDIStlsgdHA
: {
1178 // Transform: %xd = ADDIStlsgdHA %x2, @sym
1179 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
1180 assert(IsPPC64
&& "Not supported for 32-bit PowerPC");
1181 const MachineOperand
&MO
= MI
->getOperand(2);
1182 const GlobalValue
*GValue
= MO
.getGlobal();
1183 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1184 const MCExpr
*SymGotTlsGD
=
1185 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA
,
1187 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS8
)
1188 .addReg(MI
->getOperand(0).getReg())
1189 .addReg(MI
->getOperand(1).getReg())
1190 .addExpr(SymGotTlsGD
));
1193 case PPC::ADDItlsgdL
:
1194 // Transform: %xd = ADDItlsgdL %xs, @sym
1195 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
1196 case PPC::ADDItlsgdL32
: {
1197 // Transform: %rd = ADDItlsgdL32 %rs, @sym
1198 // Into: %rd = ADDI %rs, sym@got@tlsgd
1199 const MachineOperand
&MO
= MI
->getOperand(2);
1200 const GlobalValue
*GValue
= MO
.getGlobal();
1201 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1202 const MCExpr
*SymGotTlsGD
= MCSymbolRefExpr::create(
1203 MOSymbol
, IsPPC64
? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
1204 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD
,
1206 EmitToStreamer(*OutStreamer
,
1207 MCInstBuilder(IsPPC64
? PPC::ADDI8
: PPC::ADDI
)
1208 .addReg(MI
->getOperand(0).getReg())
1209 .addReg(MI
->getOperand(1).getReg())
1210 .addExpr(SymGotTlsGD
));
1213 case PPC::GETtlsADDR
:
1214 // Transform: %x3 = GETtlsADDR %x3, @sym
1215 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
1216 case PPC::GETtlsADDRPCREL
:
1217 case PPC::GETtlsADDR32AIX
:
1218 case PPC::GETtlsADDR64AIX
:
1219 // Transform: %r3 = GETtlsADDRNNAIX %r3, %r4 (for NN == 32/64).
1220 // Into: BLA .__tls_get_addr()
1221 // Unlike on Linux, there is no symbol or relocation needed for this call.
1222 case PPC::GETtlsADDR32
: {
1223 // Transform: %r3 = GETtlsADDR32 %r3, @sym
1224 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
1225 EmitTlsCall(MI
, MCSymbolRefExpr::VK_PPC_TLSGD
);
1228 case PPC::ADDIStlsldHA
: {
1229 // Transform: %xd = ADDIStlsldHA %x2, @sym
1230 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
1231 assert(IsPPC64
&& "Not supported for 32-bit PowerPC");
1232 const MachineOperand
&MO
= MI
->getOperand(2);
1233 const GlobalValue
*GValue
= MO
.getGlobal();
1234 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1235 const MCExpr
*SymGotTlsLD
=
1236 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA
,
1238 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS8
)
1239 .addReg(MI
->getOperand(0).getReg())
1240 .addReg(MI
->getOperand(1).getReg())
1241 .addExpr(SymGotTlsLD
));
1244 case PPC::ADDItlsldL
:
1245 // Transform: %xd = ADDItlsldL %xs, @sym
1246 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
1247 case PPC::ADDItlsldL32
: {
1248 // Transform: %rd = ADDItlsldL32 %rs, @sym
1249 // Into: %rd = ADDI %rs, sym@got@tlsld
1250 const MachineOperand
&MO
= MI
->getOperand(2);
1251 const GlobalValue
*GValue
= MO
.getGlobal();
1252 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1253 const MCExpr
*SymGotTlsLD
= MCSymbolRefExpr::create(
1254 MOSymbol
, IsPPC64
? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
1255 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD
,
1257 EmitToStreamer(*OutStreamer
,
1258 MCInstBuilder(IsPPC64
? PPC::ADDI8
: PPC::ADDI
)
1259 .addReg(MI
->getOperand(0).getReg())
1260 .addReg(MI
->getOperand(1).getReg())
1261 .addExpr(SymGotTlsLD
));
1264 case PPC::GETtlsldADDR
:
1265 // Transform: %x3 = GETtlsldADDR %x3, @sym
1266 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
1267 case PPC::GETtlsldADDRPCREL
:
1268 case PPC::GETtlsldADDR32
: {
1269 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
1270 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
1271 EmitTlsCall(MI
, MCSymbolRefExpr::VK_PPC_TLSLD
);
1274 case PPC::ADDISdtprelHA
:
1275 // Transform: %xd = ADDISdtprelHA %xs, @sym
1276 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1277 case PPC::ADDISdtprelHA32
: {
1278 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1279 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1280 const MachineOperand
&MO
= MI
->getOperand(2);
1281 const GlobalValue
*GValue
= MO
.getGlobal();
1282 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1283 const MCExpr
*SymDtprel
=
1284 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_DTPREL_HA
,
1288 MCInstBuilder(IsPPC64
? PPC::ADDIS8
: PPC::ADDIS
)
1289 .addReg(MI
->getOperand(0).getReg())
1290 .addReg(MI
->getOperand(1).getReg())
1291 .addExpr(SymDtprel
));
1294 case PPC::PADDIdtprel
: {
1295 // Transform: %rd = PADDIdtprel %rs, @sym
1296 // Into: %rd = PADDI8 %rs, sym@dtprel
1297 const MachineOperand
&MO
= MI
->getOperand(2);
1298 const GlobalValue
*GValue
= MO
.getGlobal();
1299 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1300 const MCExpr
*SymDtprel
= MCSymbolRefExpr::create(
1301 MOSymbol
, MCSymbolRefExpr::VK_DTPREL
, OutContext
);
1302 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::PADDI8
)
1303 .addReg(MI
->getOperand(0).getReg())
1304 .addReg(MI
->getOperand(1).getReg())
1305 .addExpr(SymDtprel
));
1309 case PPC::ADDIdtprelL
:
1310 // Transform: %xd = ADDIdtprelL %xs, @sym
1311 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1312 case PPC::ADDIdtprelL32
: {
1313 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1314 // Into: %rd = ADDI %rs, sym@dtprel@l
1315 const MachineOperand
&MO
= MI
->getOperand(2);
1316 const GlobalValue
*GValue
= MO
.getGlobal();
1317 MCSymbol
*MOSymbol
= getSymbol(GValue
);
1318 const MCExpr
*SymDtprel
=
1319 MCSymbolRefExpr::create(MOSymbol
, MCSymbolRefExpr::VK_PPC_DTPREL_LO
,
1321 EmitToStreamer(*OutStreamer
,
1322 MCInstBuilder(IsPPC64
? PPC::ADDI8
: PPC::ADDI
)
1323 .addReg(MI
->getOperand(0).getReg())
1324 .addReg(MI
->getOperand(1).getReg())
1325 .addExpr(SymDtprel
));
1330 if (!Subtarget
->hasMFOCRF()) {
1331 // Transform: %r3 = MFOCRF %cr7
1332 // Into: %r3 = MFCR ;; cr7
1333 unsigned NewOpcode
=
1334 MI
->getOpcode() == PPC::MFOCRF
? PPC::MFCR
: PPC::MFCR8
;
1335 OutStreamer
->AddComment(PPCInstPrinter::
1336 getRegisterName(MI
->getOperand(1).getReg()));
1337 EmitToStreamer(*OutStreamer
, MCInstBuilder(NewOpcode
)
1338 .addReg(MI
->getOperand(0).getReg()));
1344 if (!Subtarget
->hasMFOCRF()) {
1345 // Transform: %cr7 = MTOCRF %r3
1346 // Into: MTCRF mask, %r3 ;; cr7
1347 unsigned NewOpcode
=
1348 MI
->getOpcode() == PPC::MTOCRF
? PPC::MTCRF
: PPC::MTCRF8
;
1349 unsigned Mask
= 0x80 >> OutContext
.getRegisterInfo()
1350 ->getEncodingValue(MI
->getOperand(0).getReg());
1351 OutStreamer
->AddComment(PPCInstPrinter::
1352 getRegisterName(MI
->getOperand(0).getReg()));
1353 EmitToStreamer(*OutStreamer
, MCInstBuilder(NewOpcode
)
1355 .addReg(MI
->getOperand(1).getReg()));
1363 // Verify alignment is legal, so we don't create relocations
1364 // that can't be supported.
1365 unsigned OpNum
= (MI
->getOpcode() == PPC::STD
) ? 2 : 1;
1366 const MachineOperand
&MO
= MI
->getOperand(OpNum
);
1367 if (MO
.isGlobal()) {
1368 const DataLayout
&DL
= MO
.getGlobal()->getParent()->getDataLayout();
1369 if (MO
.getGlobal()->getPointerAlignment(DL
) < 4)
1370 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1372 // Now process the instruction normally.
1375 case PPC::PseudoEIEIO
: {
1378 MCInstBuilder(PPC::ORI
).addReg(PPC::X2
).addReg(PPC::X2
).addImm(0));
1381 MCInstBuilder(PPC::ORI
).addReg(PPC::X2
).addReg(PPC::X2
).addImm(0));
1382 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::EnforceIEIO
));
1387 LowerPPCMachineInstrToMCInst(MI
, TmpInst
, *this);
1388 EmitToStreamer(*OutStreamer
, TmpInst
);
1391 void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr
*MI
) {
1392 if (!Subtarget
->isPPC64())
1393 return PPCAsmPrinter::emitInstruction(MI
);
1395 switch (MI
->getOpcode()) {
1397 return PPCAsmPrinter::emitInstruction(MI
);
1398 case TargetOpcode::PATCHABLE_FUNCTION_ENTER
: {
1400 // b .end # lis 0, FuncId[16..32]
1401 // nop # li 0, FuncId[0..15]
1404 // bl __xray_FunctionEntry
1408 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1409 // of instructions change.
1410 MCSymbol
*BeginOfSled
= OutContext
.createTempSymbol();
1411 MCSymbol
*EndOfSled
= OutContext
.createTempSymbol();
1412 OutStreamer
->emitLabel(BeginOfSled
);
1413 EmitToStreamer(*OutStreamer
,
1414 MCInstBuilder(PPC::B
).addExpr(
1415 MCSymbolRefExpr::create(EndOfSled
, OutContext
)));
1416 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
1419 MCInstBuilder(PPC::STD
).addReg(PPC::X0
).addImm(-8).addReg(PPC::X1
));
1420 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MFLR8
).addReg(PPC::X0
));
1421 EmitToStreamer(*OutStreamer
,
1422 MCInstBuilder(PPC::BL8_NOP
)
1423 .addExpr(MCSymbolRefExpr::create(
1424 OutContext
.getOrCreateSymbol("__xray_FunctionEntry"),
1426 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MTLR8
).addReg(PPC::X0
));
1427 OutStreamer
->emitLabel(EndOfSled
);
1428 recordSled(BeginOfSled
, *MI
, SledKind::FUNCTION_ENTER
, 2);
1431 case TargetOpcode::PATCHABLE_RET
: {
1432 unsigned RetOpcode
= MI
->getOperand(0).getImm();
1434 RetInst
.setOpcode(RetOpcode
);
1435 for (const auto &MO
: llvm::drop_begin(MI
->operands())) {
1437 if (LowerPPCMachineOperandToMCOperand(MO
, MCOp
, *this))
1438 RetInst
.addOperand(MCOp
);
1442 if (RetOpcode
== PPC::BCCLR
) {
1443 IsConditional
= true;
1444 } else if (RetOpcode
== PPC::TCRETURNdi8
|| RetOpcode
== PPC::TCRETURNri8
||
1445 RetOpcode
== PPC::TCRETURNai8
) {
1447 } else if (RetOpcode
== PPC::BLR8
|| RetOpcode
== PPC::TAILB8
) {
1448 IsConditional
= false;
1450 EmitToStreamer(*OutStreamer
, RetInst
);
1454 MCSymbol
*FallthroughLabel
;
1455 if (IsConditional
) {
1463 // blr # lis 0, FuncId[16..32]
1464 // nop # li 0, FuncId[0..15]
1467 // bl __xray_FunctionExit
1472 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1473 // of instructions change.
1474 FallthroughLabel
= OutContext
.createTempSymbol();
1477 MCInstBuilder(PPC::BCC
)
1478 .addImm(PPC::InvertPredicate(
1479 static_cast<PPC::Predicate
>(MI
->getOperand(1).getImm())))
1480 .addReg(MI
->getOperand(2).getReg())
1481 .addExpr(MCSymbolRefExpr::create(FallthroughLabel
, OutContext
)));
1483 RetInst
.setOpcode(PPC::BLR8
);
1487 // b(lr)? # lis 0, FuncId[16..32]
1488 // nop # li 0, FuncId[0..15]
1491 // bl __xray_FunctionExit
1495 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1496 // of instructions change.
1497 OutStreamer
->emitCodeAlignment(8);
1498 MCSymbol
*BeginOfSled
= OutContext
.createTempSymbol();
1499 OutStreamer
->emitLabel(BeginOfSled
);
1500 EmitToStreamer(*OutStreamer
, RetInst
);
1501 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::NOP
));
1504 MCInstBuilder(PPC::STD
).addReg(PPC::X0
).addImm(-8).addReg(PPC::X1
));
1505 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MFLR8
).addReg(PPC::X0
));
1506 EmitToStreamer(*OutStreamer
,
1507 MCInstBuilder(PPC::BL8_NOP
)
1508 .addExpr(MCSymbolRefExpr::create(
1509 OutContext
.getOrCreateSymbol("__xray_FunctionExit"),
1511 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::MTLR8
).addReg(PPC::X0
));
1512 EmitToStreamer(*OutStreamer
, RetInst
);
1514 OutStreamer
->emitLabel(FallthroughLabel
);
1515 recordSled(BeginOfSled
, *MI
, SledKind::FUNCTION_EXIT
, 2);
1518 case TargetOpcode::PATCHABLE_FUNCTION_EXIT
:
1519 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
1520 case TargetOpcode::PATCHABLE_TAIL_CALL
:
1521 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1522 // normal function exit from a tail exit.
1523 llvm_unreachable("Tail call is handled in the normal case. See comments "
1524 "around this assert.");
1528 void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module
&M
) {
1529 if (static_cast<const PPCTargetMachine
&>(TM
).isELFv2ABI()) {
1530 PPCTargetStreamer
*TS
=
1531 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
1534 TS
->emitAbiVersion(2);
1537 if (static_cast<const PPCTargetMachine
&>(TM
).isPPC64() ||
1538 !isPositionIndependent())
1539 return AsmPrinter::emitStartOfAsmFile(M
);
1541 if (M
.getPICLevel() == PICLevel::SmallPIC
)
1542 return AsmPrinter::emitStartOfAsmFile(M
);
1544 OutStreamer
->SwitchSection(OutContext
.getELFSection(
1545 ".got2", ELF::SHT_PROGBITS
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
));
1547 MCSymbol
*TOCSym
= OutContext
.getOrCreateSymbol(Twine(".LTOC"));
1548 MCSymbol
*CurrentPos
= OutContext
.createTempSymbol();
1550 OutStreamer
->emitLabel(CurrentPos
);
1552 // The GOT pointer points to the middle of the GOT, in order to reference the
1553 // entire 64kB range. 0x8000 is the midpoint.
1554 const MCExpr
*tocExpr
=
1555 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos
, OutContext
),
1556 MCConstantExpr::create(0x8000, OutContext
),
1559 OutStreamer
->emitAssignment(TOCSym
, tocExpr
);
1561 OutStreamer
->SwitchSection(getObjFileLowering().getTextSection());
1564 void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1565 // linux/ppc32 - Normal entry label.
1566 if (!Subtarget
->isPPC64() &&
1567 (!isPositionIndependent() ||
1568 MF
->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC
))
1569 return AsmPrinter::emitFunctionEntryLabel();
1571 if (!Subtarget
->isPPC64()) {
1572 const PPCFunctionInfo
*PPCFI
= MF
->getInfo
<PPCFunctionInfo
>();
1573 if (PPCFI
->usesPICBase() && !Subtarget
->isSecurePlt()) {
1574 MCSymbol
*RelocSymbol
= PPCFI
->getPICOffsetSymbol(*MF
);
1575 MCSymbol
*PICBase
= MF
->getPICBaseSymbol();
1576 OutStreamer
->emitLabel(RelocSymbol
);
1578 const MCExpr
*OffsExpr
=
1579 MCBinaryExpr::createSub(
1580 MCSymbolRefExpr::create(OutContext
.getOrCreateSymbol(Twine(".LTOC")),
1582 MCSymbolRefExpr::create(PICBase
, OutContext
),
1584 OutStreamer
->emitValue(OffsExpr
, 4);
1585 OutStreamer
->emitLabel(CurrentFnSym
);
1588 return AsmPrinter::emitFunctionEntryLabel();
1591 // ELFv2 ABI - Normal entry label.
1592 if (Subtarget
->isELFv2ABI()) {
1593 // In the Large code model, we allow arbitrary displacements between
1594 // the text section and its associated TOC section. We place the
1595 // full 8-byte offset to the TOC in memory immediately preceding
1596 // the function global entry point.
1597 if (TM
.getCodeModel() == CodeModel::Large
1598 && !MF
->getRegInfo().use_empty(PPC::X2
)) {
1599 const PPCFunctionInfo
*PPCFI
= MF
->getInfo
<PPCFunctionInfo
>();
1601 MCSymbol
*TOCSymbol
= OutContext
.getOrCreateSymbol(StringRef(".TOC."));
1602 MCSymbol
*GlobalEPSymbol
= PPCFI
->getGlobalEPSymbol(*MF
);
1603 const MCExpr
*TOCDeltaExpr
=
1604 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol
, OutContext
),
1605 MCSymbolRefExpr::create(GlobalEPSymbol
,
1609 OutStreamer
->emitLabel(PPCFI
->getTOCOffsetSymbol(*MF
));
1610 OutStreamer
->emitValue(TOCDeltaExpr
, 8);
1612 return AsmPrinter::emitFunctionEntryLabel();
1615 // Emit an official procedure descriptor.
1616 MCSectionSubPair Current
= OutStreamer
->getCurrentSection();
1617 MCSectionELF
*Section
= OutStreamer
->getContext().getELFSection(
1618 ".opd", ELF::SHT_PROGBITS
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
);
1619 OutStreamer
->SwitchSection(Section
);
1620 OutStreamer
->emitLabel(CurrentFnSym
);
1621 OutStreamer
->emitValueToAlignment(8);
1622 MCSymbol
*Symbol1
= CurrentFnSymForSize
;
1623 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1625 OutStreamer
->emitValue(MCSymbolRefExpr::create(Symbol1
, OutContext
),
1627 MCSymbol
*Symbol2
= OutContext
.getOrCreateSymbol(StringRef(".TOC."));
1628 // Generates a R_PPC64_TOC relocation for TOC base insertion.
1629 OutStreamer
->emitValue(
1630 MCSymbolRefExpr::create(Symbol2
, MCSymbolRefExpr::VK_PPC_TOCBASE
, OutContext
),
1632 // Emit a null environment pointer.
1633 OutStreamer
->emitIntValue(0, 8 /* size */);
1634 OutStreamer
->SwitchSection(Current
.first
, Current
.second
);
1637 void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module
&M
) {
1638 const DataLayout
&DL
= getDataLayout();
1640 bool isPPC64
= DL
.getPointerSizeInBits() == 64;
1642 PPCTargetStreamer
*TS
=
1643 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
1646 const char *Name
= isPPC64
? ".toc" : ".got2";
1647 MCSectionELF
*Section
= OutContext
.getELFSection(
1648 Name
, ELF::SHT_PROGBITS
, ELF::SHF_WRITE
| ELF::SHF_ALLOC
);
1649 OutStreamer
->SwitchSection(Section
);
1651 OutStreamer
->emitValueToAlignment(4);
1653 for (const auto &TOCMapPair
: TOC
) {
1654 const MCSymbol
*const TOCEntryTarget
= TOCMapPair
.first
.first
;
1655 MCSymbol
*const TOCEntryLabel
= TOCMapPair
.second
;
1657 OutStreamer
->emitLabel(TOCEntryLabel
);
1658 if (isPPC64
&& TS
!= nullptr)
1659 TS
->emitTCEntry(*TOCEntryTarget
, TOCMapPair
.first
.second
);
1661 OutStreamer
->emitSymbolValue(TOCEntryTarget
, 4);
1665 PPCAsmPrinter::emitEndOfAsmFile(M
);
1668 /// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
1669 void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
1670 // In the ELFv2 ABI, in functions that use the TOC register, we need to
1671 // provide two entry points. The ABI guarantees that when calling the
1672 // local entry point, r2 is set up by the caller to contain the TOC base
1673 // for this function, and when calling the global entry point, r12 is set
1674 // up by the caller to hold the address of the global entry point. We
1675 // thus emit a prefix sequence along the following lines:
1679 // # global entry point
1680 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1681 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
1683 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1684 // # local entry point, followed by function body
1686 // For the Large code model, we create
1689 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
1692 // # global entry point
1693 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1696 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1697 // # local entry point, followed by function body
1699 // This ensures we have r2 set up correctly while executing the function
1700 // body, no matter which entry point is called.
1701 const PPCFunctionInfo
*PPCFI
= MF
->getInfo
<PPCFunctionInfo
>();
1702 const bool UsesX2OrR2
= !MF
->getRegInfo().use_empty(PPC::X2
) ||
1703 !MF
->getRegInfo().use_empty(PPC::R2
);
1704 const bool PCrelGEPRequired
= Subtarget
->isUsingPCRelativeCalls() &&
1705 UsesX2OrR2
&& PPCFI
->usesTOCBasePtr();
1706 const bool NonPCrelGEPRequired
= !Subtarget
->isUsingPCRelativeCalls() &&
1707 Subtarget
->isELFv2ABI() && UsesX2OrR2
;
1709 // Only do all that if the function uses R2 as the TOC pointer
1710 // in the first place. We don't need the global entry point if the
1711 // function uses R2 as an allocatable register.
1712 if (NonPCrelGEPRequired
|| PCrelGEPRequired
) {
1713 // Note: The logic here must be synchronized with the code in the
1714 // branch-selection pass which sets the offset of the first block in the
1715 // function. This matters because it affects the alignment.
1716 MCSymbol
*GlobalEntryLabel
= PPCFI
->getGlobalEPSymbol(*MF
);
1717 OutStreamer
->emitLabel(GlobalEntryLabel
);
1718 const MCSymbolRefExpr
*GlobalEntryLabelExp
=
1719 MCSymbolRefExpr::create(GlobalEntryLabel
, OutContext
);
1721 if (TM
.getCodeModel() != CodeModel::Large
) {
1722 MCSymbol
*TOCSymbol
= OutContext
.getOrCreateSymbol(StringRef(".TOC."));
1723 const MCExpr
*TOCDeltaExpr
=
1724 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol
, OutContext
),
1725 GlobalEntryLabelExp
, OutContext
);
1727 const MCExpr
*TOCDeltaHi
= PPCMCExpr::createHa(TOCDeltaExpr
, OutContext
);
1728 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDIS
)
1731 .addExpr(TOCDeltaHi
));
1733 const MCExpr
*TOCDeltaLo
= PPCMCExpr::createLo(TOCDeltaExpr
, OutContext
);
1734 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADDI
)
1737 .addExpr(TOCDeltaLo
));
1739 MCSymbol
*TOCOffset
= PPCFI
->getTOCOffsetSymbol(*MF
);
1740 const MCExpr
*TOCOffsetDeltaExpr
=
1741 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset
, OutContext
),
1742 GlobalEntryLabelExp
, OutContext
);
1744 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::LD
)
1746 .addExpr(TOCOffsetDeltaExpr
)
1748 EmitToStreamer(*OutStreamer
, MCInstBuilder(PPC::ADD8
)
1754 MCSymbol
*LocalEntryLabel
= PPCFI
->getLocalEPSymbol(*MF
);
1755 OutStreamer
->emitLabel(LocalEntryLabel
);
1756 const MCSymbolRefExpr
*LocalEntryLabelExp
=
1757 MCSymbolRefExpr::create(LocalEntryLabel
, OutContext
);
1758 const MCExpr
*LocalOffsetExp
=
1759 MCBinaryExpr::createSub(LocalEntryLabelExp
,
1760 GlobalEntryLabelExp
, OutContext
);
1762 PPCTargetStreamer
*TS
=
1763 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
1766 TS
->emitLocalEntry(cast
<MCSymbolELF
>(CurrentFnSym
), LocalOffsetExp
);
1767 } else if (Subtarget
->isUsingPCRelativeCalls()) {
1768 // When generating the entry point for a function we have a few scenarios
1769 // based on whether or not that function uses R2 and whether or not that
1770 // function makes calls (or is a leaf function).
1771 // 1) A leaf function that does not use R2 (or treats it as callee-saved
1772 // and preserves it). In this case st_other=0 and both
1773 // the local and global entry points for the function are the same.
1774 // No special entry point code is required.
1775 // 2) A function uses the TOC pointer R2. This function may or may not have
1776 // calls. In this case st_other=[2,6] and the global and local entry
1777 // points are different. Code to correctly setup the TOC pointer in R2
1778 // is put between the global and local entry points. This case is
1779 // covered by the if statatement above.
1780 // 3) A function does not use the TOC pointer R2 but does have calls.
1781 // In this case st_other=1 since we do not know whether or not any
1782 // of the callees clobber R2. This case is dealt with in this else if
1783 // block. Tail calls are considered calls and the st_other should also
1784 // be set to 1 in that case as well.
1785 // 4) The function does not use the TOC pointer but R2 is used inside
1786 // the function. In this case st_other=1 once again.
1787 // 5) This function uses inline asm. We mark R2 as reserved if the function
1788 // has inline asm as we have to assume that it may be used.
1789 if (MF
->getFrameInfo().hasCalls() || MF
->getFrameInfo().hasTailCall() ||
1790 MF
->hasInlineAsm() || (!PPCFI
->usesTOCBasePtr() && UsesX2OrR2
)) {
1791 PPCTargetStreamer
*TS
=
1792 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
1794 TS
->emitLocalEntry(cast
<MCSymbolELF
>(CurrentFnSym
),
1795 MCConstantExpr::create(1, OutContext
));
1800 /// EmitFunctionBodyEnd - Print the traceback table before the .size
1803 void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
1804 // Only the 64-bit target requires a traceback table. For now,
1805 // we only emit the word of zeroes that GDB requires to find
1806 // the end of the function, and zeroes for the eight-byte
1807 // mandatory fields.
1808 // FIXME: We should fill in the eight-byte mandatory fields as described in
1809 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1810 // currently make use of these fields).
1811 if (Subtarget
->isPPC64()) {
1812 OutStreamer
->emitIntValue(0, 4/*size*/);
1813 OutStreamer
->emitIntValue(0, 8/*size*/);
1817 void PPCAIXAsmPrinter::emitLinkage(const GlobalValue
*GV
,
1818 MCSymbol
*GVSym
) const {
1820 assert(MAI
->hasVisibilityOnlyWithLinkage() &&
1821 "AIX's linkage directives take a visibility setting.");
1823 MCSymbolAttr LinkageAttr
= MCSA_Invalid
;
1824 switch (GV
->getLinkage()) {
1825 case GlobalValue::ExternalLinkage
:
1826 LinkageAttr
= GV
->isDeclaration() ? MCSA_Extern
: MCSA_Global
;
1828 case GlobalValue::LinkOnceAnyLinkage
:
1829 case GlobalValue::LinkOnceODRLinkage
:
1830 case GlobalValue::WeakAnyLinkage
:
1831 case GlobalValue::WeakODRLinkage
:
1832 case GlobalValue::ExternalWeakLinkage
:
1833 LinkageAttr
= MCSA_Weak
;
1835 case GlobalValue::AvailableExternallyLinkage
:
1836 LinkageAttr
= MCSA_Extern
;
1838 case GlobalValue::PrivateLinkage
:
1840 case GlobalValue::InternalLinkage
:
1841 assert(GV
->getVisibility() == GlobalValue::DefaultVisibility
&&
1842 "InternalLinkage should not have other visibility setting.");
1843 LinkageAttr
= MCSA_LGlobal
;
1845 case GlobalValue::AppendingLinkage
:
1846 llvm_unreachable("Should never emit this");
1847 case GlobalValue::CommonLinkage
:
1848 llvm_unreachable("CommonLinkage of XCOFF should not come to this path");
1851 assert(LinkageAttr
!= MCSA_Invalid
&& "LinkageAttr should not MCSA_Invalid.");
1853 MCSymbolAttr VisibilityAttr
= MCSA_Invalid
;
1854 if (!TM
.getIgnoreXCOFFVisibility()) {
1855 switch (GV
->getVisibility()) {
1857 // TODO: "exported" and "internal" Visibility needs to go here.
1858 case GlobalValue::DefaultVisibility
:
1860 case GlobalValue::HiddenVisibility
:
1861 VisibilityAttr
= MAI
->getHiddenVisibilityAttr();
1863 case GlobalValue::ProtectedVisibility
:
1864 VisibilityAttr
= MAI
->getProtectedVisibilityAttr();
1869 OutStreamer
->emitXCOFFSymbolLinkageWithVisibility(GVSym
, LinkageAttr
,
1873 void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction
&MF
) {
1874 // Setup CurrentFnDescSym and its containing csect.
1875 MCSectionXCOFF
*FnDescSec
=
1876 cast
<MCSectionXCOFF
>(getObjFileLowering().getSectionForFunctionDescriptor(
1877 &MF
.getFunction(), TM
));
1878 FnDescSec
->setAlignment(Align(Subtarget
->isPPC64() ? 8 : 4));
1880 CurrentFnDescSym
= FnDescSec
->getQualNameSymbol();
1882 return AsmPrinter::SetupMachineFunction(MF
);
1885 uint16_t PPCAIXAsmPrinter::getNumberOfVRSaved() {
1886 // Calculate the number of VRs be saved.
1887 // Vector registers 20 through 31 are marked as reserved and cannot be used
1888 // in the default ABI.
1889 const PPCSubtarget
&Subtarget
= MF
->getSubtarget
<PPCSubtarget
>();
1890 if (Subtarget
.isAIXABI() && Subtarget
.hasAltivec() &&
1891 TM
.getAIXExtendedAltivecABI()) {
1892 const MachineRegisterInfo
&MRI
= MF
->getRegInfo();
1893 for (unsigned Reg
= PPC::V20
; Reg
<= PPC::V31
; ++Reg
)
1894 if (MRI
.isPhysRegModified(Reg
))
1895 // Number of VRs saved.
1896 return PPC::V31
- Reg
+ 1;
1901 void PPCAIXAsmPrinter::emitFunctionBodyEnd() {
1903 if (!TM
.getXCOFFTracebackTable())
1906 emitTracebackTable();
1908 // If ShouldEmitEHBlock returns true, then the eh info table
1909 // will be emitted via `AIXException::endFunction`. Otherwise, we
1910 // need to emit a dumy eh info table when VRs are saved. We could not
1911 // consolidate these two places into one because there is no easy way
1912 // to access register information in `AIXException` class.
1913 if (!TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF
) &&
1914 (getNumberOfVRSaved() > 0)) {
1915 // Emit dummy EH Info Table.
1916 OutStreamer
->SwitchSection(getObjFileLowering().getCompactUnwindSection());
1917 MCSymbol
*EHInfoLabel
=
1918 TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF
);
1919 OutStreamer
->emitLabel(EHInfoLabel
);
1922 OutStreamer
->emitInt32(0);
1924 const DataLayout
&DL
= MMI
->getModule()->getDataLayout();
1925 const unsigned PointerSize
= DL
.getPointerSize();
1926 // Add necessary paddings in 64 bit mode.
1927 OutStreamer
->emitValueToAlignment(PointerSize
);
1929 OutStreamer
->emitIntValue(0, PointerSize
);
1930 OutStreamer
->emitIntValue(0, PointerSize
);
1931 OutStreamer
->SwitchSection(MF
->getSection());
1935 void PPCAIXAsmPrinter::emitTracebackTable() {
1937 // Create a symbol for the end of function.
1938 MCSymbol
*FuncEnd
= createTempSymbol(MF
->getName());
1939 OutStreamer
->emitLabel(FuncEnd
);
1941 OutStreamer
->AddComment("Traceback table begin");
1942 // Begin with a fullword of zero.
1943 OutStreamer
->emitIntValueInHexWithPadding(0, 4 /*size*/);
1945 SmallString
<128> CommentString
;
1946 raw_svector_ostream
CommentOS(CommentString
);
1948 auto EmitComment
= [&]() {
1949 OutStreamer
->AddComment(CommentOS
.str());
1950 CommentString
.clear();
1953 auto EmitCommentAndValue
= [&](uint64_t Value
, int Size
) {
1955 OutStreamer
->emitIntValueInHexWithPadding(Value
, Size
);
1958 unsigned int Version
= 0;
1959 CommentOS
<< "Version = " << Version
;
1960 EmitCommentAndValue(Version
, 1);
1962 // There is a lack of information in the IR to assist with determining the
1963 // source language. AIX exception handling mechanism would only search for
1964 // personality routine and LSDA area when such language supports exception
1965 // handling. So to be conservatively correct and allow runtime to do its job,
1966 // we need to set it to C++ for now.
1967 TracebackTable::LanguageID LanguageIdentifier
=
1968 TracebackTable::CPlusPlus
; // C++
1970 CommentOS
<< "Language = "
1971 << getNameForTracebackTableLanguageId(LanguageIdentifier
);
1972 EmitCommentAndValue(LanguageIdentifier
, 1);
1974 // This is only populated for the third and fourth bytes.
1975 uint32_t FirstHalfOfMandatoryField
= 0;
1977 // Emit the 3rd byte of the mandatory field.
1979 // We always set traceback offset bit to true.
1980 FirstHalfOfMandatoryField
|= TracebackTable::HasTraceBackTableOffsetMask
;
1982 const PPCFunctionInfo
*FI
= MF
->getInfo
<PPCFunctionInfo
>();
1983 const MachineRegisterInfo
&MRI
= MF
->getRegInfo();
1985 // Check the function uses floating-point processor instructions or not
1986 for (unsigned Reg
= PPC::F0
; Reg
<= PPC::F31
; ++Reg
) {
1987 if (MRI
.isPhysRegUsed(Reg
, /* SkipRegMaskTest */ true)) {
1988 FirstHalfOfMandatoryField
|= TracebackTable::IsFloatingPointPresentMask
;
1993 #define GENBOOLCOMMENT(Prefix, V, Field) \
1994 CommentOS << (Prefix) << ((V) & (TracebackTable::Field##Mask) ? "+" : "-") \
1997 #define GENVALUECOMMENT(PrefixAndName, V, Field) \
1998 CommentOS << (PrefixAndName) << " = " \
1999 << static_cast<unsigned>(((V) & (TracebackTable::Field##Mask)) >> \
2000 (TracebackTable::Field##Shift))
2002 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, IsGlobaLinkage
);
2003 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsOutOfLineEpilogOrPrologue
);
2006 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, HasTraceBackTableOffset
);
2007 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsInternalProcedure
);
2010 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, HasControlledStorage
);
2011 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsTOCless
);
2014 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, IsFloatingPointPresent
);
2016 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
,
2017 IsFloatingPointOperationLogOrAbortEnabled
);
2020 OutStreamer
->emitIntValueInHexWithPadding(
2021 (FirstHalfOfMandatoryField
& 0x0000ff00) >> 8, 1);
2023 // Set the 4th byte of the mandatory field.
2024 FirstHalfOfMandatoryField
|= TracebackTable::IsFunctionNamePresentMask
;
2026 static_assert(XCOFF::AllocRegNo
== 31, "Unexpected register usage!");
2027 if (MRI
.isPhysRegUsed(Subtarget
->isPPC64() ? PPC::X31
: PPC::R31
,
2028 /* SkipRegMaskTest */ true))
2029 FirstHalfOfMandatoryField
|= TracebackTable::IsAllocaUsedMask
;
2031 const SmallVectorImpl
<Register
> &MustSaveCRs
= FI
->getMustSaveCRs();
2032 if (!MustSaveCRs
.empty())
2033 FirstHalfOfMandatoryField
|= TracebackTable::IsCRSavedMask
;
2035 if (FI
->mustSaveLR())
2036 FirstHalfOfMandatoryField
|= TracebackTable::IsLRSavedMask
;
2038 GENBOOLCOMMENT("", FirstHalfOfMandatoryField
, IsInterruptHandler
);
2039 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsFunctionNamePresent
);
2040 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsAllocaUsed
);
2042 GENVALUECOMMENT("OnConditionDirective", FirstHalfOfMandatoryField
,
2043 OnConditionDirective
);
2044 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsCRSaved
);
2045 GENBOOLCOMMENT(", ", FirstHalfOfMandatoryField
, IsLRSaved
);
2047 OutStreamer
->emitIntValueInHexWithPadding((FirstHalfOfMandatoryField
& 0xff),
2050 // Set the 5th byte of mandatory field.
2051 uint32_t SecondHalfOfMandatoryField
= 0;
2053 // Always store back chain.
2054 SecondHalfOfMandatoryField
|= TracebackTable::IsBackChainStoredMask
;
2056 uint32_t FPRSaved
= 0;
2057 for (unsigned Reg
= PPC::F14
; Reg
<= PPC::F31
; ++Reg
) {
2058 if (MRI
.isPhysRegModified(Reg
)) {
2059 FPRSaved
= PPC::F31
- Reg
+ 1;
2063 SecondHalfOfMandatoryField
|= (FPRSaved
<< TracebackTable::FPRSavedShift
) &
2064 TracebackTable::FPRSavedMask
;
2065 GENBOOLCOMMENT("", SecondHalfOfMandatoryField
, IsBackChainStored
);
2066 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField
, IsFixup
);
2067 GENVALUECOMMENT(", NumOfFPRsSaved", SecondHalfOfMandatoryField
, FPRSaved
);
2069 OutStreamer
->emitIntValueInHexWithPadding(
2070 (SecondHalfOfMandatoryField
& 0xff000000) >> 24, 1);
2072 // Set the 6th byte of mandatory field.
2074 // Check whether has Vector Instruction,We only treat instructions uses vector
2075 // register as vector instructions.
2076 bool HasVectorInst
= false;
2077 for (unsigned Reg
= PPC::V0
; Reg
<= PPC::V31
; ++Reg
)
2078 if (MRI
.isPhysRegUsed(Reg
, /* SkipRegMaskTest */ true)) {
2079 // Has VMX instruction.
2080 HasVectorInst
= true;
2084 if (FI
->hasVectorParms() || HasVectorInst
)
2085 SecondHalfOfMandatoryField
|= TracebackTable::HasVectorInfoMask
;
2087 uint16_t NumOfVRSaved
= getNumberOfVRSaved();
2088 bool ShouldEmitEHBlock
=
2089 TargetLoweringObjectFileXCOFF::ShouldEmitEHBlock(MF
) || NumOfVRSaved
> 0;
2091 if (ShouldEmitEHBlock
)
2092 SecondHalfOfMandatoryField
|= TracebackTable::HasExtensionTableMask
;
2094 uint32_t GPRSaved
= 0;
2096 // X13 is reserved under 64-bit environment.
2097 unsigned GPRBegin
= Subtarget
->isPPC64() ? PPC::X14
: PPC::R13
;
2098 unsigned GPREnd
= Subtarget
->isPPC64() ? PPC::X31
: PPC::R31
;
2100 for (unsigned Reg
= GPRBegin
; Reg
<= GPREnd
; ++Reg
) {
2101 if (MRI
.isPhysRegModified(Reg
)) {
2102 GPRSaved
= GPREnd
- Reg
+ 1;
2107 SecondHalfOfMandatoryField
|= (GPRSaved
<< TracebackTable::GPRSavedShift
) &
2108 TracebackTable::GPRSavedMask
;
2110 GENBOOLCOMMENT("", SecondHalfOfMandatoryField
, HasExtensionTable
);
2111 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField
, HasVectorInfo
);
2112 GENVALUECOMMENT(", NumOfGPRsSaved", SecondHalfOfMandatoryField
, GPRSaved
);
2114 OutStreamer
->emitIntValueInHexWithPadding(
2115 (SecondHalfOfMandatoryField
& 0x00ff0000) >> 16, 1);
2117 // Set the 7th byte of mandatory field.
2118 uint32_t NumberOfFixedParms
= FI
->getFixedParmsNum();
2119 SecondHalfOfMandatoryField
|=
2120 (NumberOfFixedParms
<< TracebackTable::NumberOfFixedParmsShift
) &
2121 TracebackTable::NumberOfFixedParmsMask
;
2122 GENVALUECOMMENT("NumberOfFixedParms", SecondHalfOfMandatoryField
,
2123 NumberOfFixedParms
);
2125 OutStreamer
->emitIntValueInHexWithPadding(
2126 (SecondHalfOfMandatoryField
& 0x0000ff00) >> 8, 1);
2128 // Set the 8th byte of mandatory field.
2130 // Always set parameter on stack.
2131 SecondHalfOfMandatoryField
|= TracebackTable::HasParmsOnStackMask
;
2133 uint32_t NumberOfFPParms
= FI
->getFloatingPointParmsNum();
2134 SecondHalfOfMandatoryField
|=
2135 (NumberOfFPParms
<< TracebackTable::NumberOfFloatingPointParmsShift
) &
2136 TracebackTable::NumberOfFloatingPointParmsMask
;
2138 GENVALUECOMMENT("NumberOfFPParms", SecondHalfOfMandatoryField
,
2139 NumberOfFloatingPointParms
);
2140 GENBOOLCOMMENT(", ", SecondHalfOfMandatoryField
, HasParmsOnStack
);
2142 OutStreamer
->emitIntValueInHexWithPadding(SecondHalfOfMandatoryField
& 0xff,
2145 // Generate the optional fields of traceback table.
2148 if (NumberOfFixedParms
|| NumberOfFPParms
) {
2149 uint32_t ParmsTypeValue
= FI
->getParmsType();
2151 Expected
<SmallString
<32>> ParmsType
=
2152 FI
->hasVectorParms()
2153 ? XCOFF::parseParmsTypeWithVecInfo(
2154 ParmsTypeValue
, NumberOfFixedParms
, NumberOfFPParms
,
2155 FI
->getVectorParmsNum())
2156 : XCOFF::parseParmsType(ParmsTypeValue
, NumberOfFixedParms
,
2159 assert(ParmsType
&& toString(ParmsType
.takeError()).c_str());
2161 CommentOS
<< "Parameter type = " << ParmsType
.get();
2164 OutStreamer
->emitIntValueInHexWithPadding(ParmsTypeValue
,
2165 sizeof(ParmsTypeValue
));
2167 // Traceback table offset.
2168 OutStreamer
->AddComment("Function size");
2169 if (FirstHalfOfMandatoryField
& TracebackTable::HasTraceBackTableOffsetMask
) {
2170 MCSymbol
*FuncSectSym
= getObjFileLowering().getFunctionEntryPointSymbol(
2171 &(MF
->getFunction()), TM
);
2172 OutStreamer
->emitAbsoluteSymbolDiff(FuncEnd
, FuncSectSym
, 4);
2175 // Since we unset the Int_Handler.
2176 if (FirstHalfOfMandatoryField
& TracebackTable::IsInterruptHandlerMask
)
2177 report_fatal_error("Hand_Mask not implement yet");
2179 if (FirstHalfOfMandatoryField
& TracebackTable::HasControlledStorageMask
)
2180 report_fatal_error("Ctl_Info not implement yet");
2182 if (FirstHalfOfMandatoryField
& TracebackTable::IsFunctionNamePresentMask
) {
2183 StringRef Name
= MF
->getName().substr(0, INT16_MAX
);
2184 int16_t NameLength
= Name
.size();
2185 CommentOS
<< "Function name len = "
2186 << static_cast<unsigned int>(NameLength
);
2187 EmitCommentAndValue(NameLength
, 2);
2188 OutStreamer
->AddComment("Function Name");
2189 OutStreamer
->emitBytes(Name
);
2192 if (FirstHalfOfMandatoryField
& TracebackTable::IsAllocaUsedMask
) {
2193 uint8_t AllocReg
= XCOFF::AllocRegNo
;
2194 OutStreamer
->AddComment("AllocaUsed");
2195 OutStreamer
->emitIntValueInHex(AllocReg
, sizeof(AllocReg
));
2198 if (SecondHalfOfMandatoryField
& TracebackTable::HasVectorInfoMask
) {
2199 uint16_t VRData
= 0;
2201 // Number of VRs saved.
2202 VRData
|= (NumOfVRSaved
<< TracebackTable::NumberOfVRSavedShift
) &
2203 TracebackTable::NumberOfVRSavedMask
;
2204 // This bit is supposed to set only when the special register
2205 // VRSAVE is saved on stack.
2206 // However, IBM XL compiler sets the bit when any vector registers
2207 // are saved on the stack. We will follow XL's behavior on AIX
2208 // so that we don't get surprise behavior change for C code.
2209 VRData
|= TracebackTable::IsVRSavedOnStackMask
;
2213 if (FI
->getVarArgsFrameIndex())
2214 VRData
|= TracebackTable::HasVarArgsMask
;
2216 // Vector parameters number.
2217 unsigned VectorParmsNum
= FI
->getVectorParmsNum();
2218 VRData
|= (VectorParmsNum
<< TracebackTable::NumberOfVectorParmsShift
) &
2219 TracebackTable::NumberOfVectorParmsMask
;
2222 VRData
|= TracebackTable::HasVMXInstructionMask
;
2224 GENVALUECOMMENT("NumOfVRsSaved", VRData
, NumberOfVRSaved
);
2225 GENBOOLCOMMENT(", ", VRData
, IsVRSavedOnStack
);
2226 GENBOOLCOMMENT(", ", VRData
, HasVarArgs
);
2228 OutStreamer
->emitIntValueInHexWithPadding((VRData
& 0xff00) >> 8, 1);
2230 GENVALUECOMMENT("NumOfVectorParams", VRData
, NumberOfVectorParms
);
2231 GENBOOLCOMMENT(", ", VRData
, HasVMXInstruction
);
2233 OutStreamer
->emitIntValueInHexWithPadding(VRData
& 0x00ff, 1);
2235 uint32_t VecParmTypeValue
= FI
->getVecExtParmsType();
2237 Expected
<SmallString
<32>> VecParmsType
=
2238 XCOFF::parseVectorParmsType(VecParmTypeValue
, VectorParmsNum
);
2239 assert(VecParmsType
&& toString(VecParmsType
.takeError()).c_str());
2241 CommentOS
<< "Vector Parameter type = " << VecParmsType
.get();
2244 OutStreamer
->emitIntValueInHexWithPadding(VecParmTypeValue
,
2245 sizeof(VecParmTypeValue
));
2247 CommentOS
<< "Padding";
2248 EmitCommentAndValue(0, 2);
2251 uint8_t ExtensionTableFlag
= 0;
2252 if (SecondHalfOfMandatoryField
& TracebackTable::HasExtensionTableMask
) {
2253 if (ShouldEmitEHBlock
)
2254 ExtensionTableFlag
|= ExtendedTBTableFlag::TB_EH_INFO
;
2255 if (EnableSSPCanaryBitInTB
&&
2256 TargetLoweringObjectFileXCOFF::ShouldSetSSPCanaryBitInTB(MF
))
2257 ExtensionTableFlag
|= ExtendedTBTableFlag::TB_SSP_CANARY
;
2259 CommentOS
<< "ExtensionTableFlag = "
2260 << getExtendedTBTableFlagString(ExtensionTableFlag
);
2261 EmitCommentAndValue(ExtensionTableFlag
, sizeof(ExtensionTableFlag
));
2264 if (ExtensionTableFlag
& ExtendedTBTableFlag::TB_EH_INFO
) {
2265 auto &Ctx
= OutStreamer
->getContext();
2266 MCSymbol
*EHInfoSym
=
2267 TargetLoweringObjectFileXCOFF::getEHInfoTableSymbol(MF
);
2268 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(EHInfoSym
);
2269 const MCSymbol
*TOCBaseSym
=
2270 cast
<MCSectionXCOFF
>(getObjFileLowering().getTOCBaseSection())
2271 ->getQualNameSymbol();
2273 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry
, Ctx
),
2274 MCSymbolRefExpr::create(TOCBaseSym
, Ctx
), Ctx
);
2276 const DataLayout
&DL
= getDataLayout();
2277 OutStreamer
->emitValueToAlignment(4);
2278 OutStreamer
->AddComment("EHInfo Table");
2279 OutStreamer
->emitValue(Exp
, DL
.getPointerSize());
2281 #undef GENBOOLCOMMENT
2282 #undef GENVALUECOMMENT
2285 static bool isSpecialLLVMGlobalArrayToSkip(const GlobalVariable
*GV
) {
2286 return GV
->hasAppendingLinkage() &&
2287 StringSwitch
<bool>(GV
->getName())
2288 // TODO: Linker could still eliminate the GV if we just skip
2289 // handling llvm.used array. Skipping them for now until we or the
2290 // AIX OS team come up with a good solution.
2291 .Case("llvm.used", true)
2292 // It's correct to just skip llvm.compiler.used array here.
2293 .Case("llvm.compiler.used", true)
2297 static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable
*GV
) {
2298 return StringSwitch
<bool>(GV
->getName())
2299 .Cases("llvm.global_ctors", "llvm.global_dtors", true)
2303 void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable
*GV
) {
2304 // Special LLVM global arrays have been handled at the initialization.
2305 if (isSpecialLLVMGlobalArrayToSkip(GV
) || isSpecialLLVMGlobalArrayForStaticInit(GV
))
2308 // If the Global Variable has the toc-data attribute, it needs to be emitted
2309 // when we emit the .toc section.
2310 if (GV
->hasAttribute("toc-data")) {
2311 TOCDataGlobalVars
.push_back(GV
);
2315 emitGlobalVariableHelper(GV
);
2318 void PPCAIXAsmPrinter::emitGlobalVariableHelper(const GlobalVariable
*GV
) {
2319 assert(!GV
->getName().startswith("llvm.") &&
2320 "Unhandled intrinsic global variable.");
2322 if (GV
->hasComdat())
2323 report_fatal_error("COMDAT not yet supported by AIX.");
2325 MCSymbolXCOFF
*GVSym
= cast
<MCSymbolXCOFF
>(getSymbol(GV
));
2327 if (GV
->isDeclarationForLinker()) {
2328 emitLinkage(GV
, GVSym
);
2332 SectionKind GVKind
= getObjFileLowering().getKindForGlobal(GV
, TM
);
2333 if (!GVKind
.isGlobalWriteableData() && !GVKind
.isReadOnly() &&
2334 !GVKind
.isThreadLocal()) // Checks for both ThreadData and ThreadBSS.
2335 report_fatal_error("Encountered a global variable kind that is "
2336 "not supported yet.");
2338 // Print GV in verbose mode
2340 if (GV
->hasInitializer()) {
2341 GV
->printAsOperand(OutStreamer
->GetCommentOS(),
2342 /*PrintType=*/false, GV
->getParent());
2343 OutStreamer
->GetCommentOS() << '\n';
2347 MCSectionXCOFF
*Csect
= cast
<MCSectionXCOFF
>(
2348 getObjFileLowering().SectionForGlobal(GV
, GVKind
, TM
));
2350 // Switch to the containing csect.
2351 OutStreamer
->SwitchSection(Csect
);
2353 const DataLayout
&DL
= GV
->getParent()->getDataLayout();
2355 // Handle common and zero-initialized local symbols.
2356 if (GV
->hasCommonLinkage() || GVKind
.isBSSLocal() ||
2357 GVKind
.isThreadBSSLocal()) {
2358 Align Alignment
= GV
->getAlign().getValueOr(DL
.getPreferredAlign(GV
));
2359 uint64_t Size
= DL
.getTypeAllocSize(GV
->getValueType());
2360 GVSym
->setStorageClass(
2361 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV
));
2363 if (GVKind
.isBSSLocal() || GVKind
.isThreadBSSLocal())
2364 OutStreamer
->emitXCOFFLocalCommonSymbol(
2365 OutContext
.getOrCreateSymbol(GVSym
->getSymbolTableName()), Size
,
2366 GVSym
, Alignment
.value());
2368 OutStreamer
->emitCommonSymbol(GVSym
, Size
, Alignment
.value());
2372 MCSymbol
*EmittedInitSym
= GVSym
;
2373 emitLinkage(GV
, EmittedInitSym
);
2374 emitAlignment(getGVAlignment(GV
, DL
), GV
);
2376 // When -fdata-sections is enabled, every GlobalVariable will
2377 // be put into its own csect; therefore, label is not necessary here.
2378 if (!TM
.getDataSections() || GV
->hasSection()) {
2379 OutStreamer
->emitLabel(EmittedInitSym
);
2382 // Emit aliasing label for global variable.
2383 llvm::for_each(GOAliasMap
[GV
], [this](const GlobalAlias
*Alias
) {
2384 OutStreamer
->emitLabel(getSymbol(Alias
));
2387 emitGlobalConstant(GV
->getParent()->getDataLayout(), GV
->getInitializer());
2390 void PPCAIXAsmPrinter::emitFunctionDescriptor() {
2391 const DataLayout
&DL
= getDataLayout();
2392 const unsigned PointerSize
= DL
.getPointerSizeInBits() == 64 ? 8 : 4;
2394 MCSectionSubPair Current
= OutStreamer
->getCurrentSection();
2395 // Emit function descriptor.
2396 OutStreamer
->SwitchSection(
2397 cast
<MCSymbolXCOFF
>(CurrentFnDescSym
)->getRepresentedCsect());
2399 // Emit aliasing label for function descriptor csect.
2400 llvm::for_each(GOAliasMap
[&MF
->getFunction()],
2401 [this](const GlobalAlias
*Alias
) {
2402 OutStreamer
->emitLabel(getSymbol(Alias
));
2405 // Emit function entry point address.
2406 OutStreamer
->emitValue(MCSymbolRefExpr::create(CurrentFnSym
, OutContext
),
2408 // Emit TOC base address.
2409 const MCSymbol
*TOCBaseSym
=
2410 cast
<MCSectionXCOFF
>(getObjFileLowering().getTOCBaseSection())
2411 ->getQualNameSymbol();
2412 OutStreamer
->emitValue(MCSymbolRefExpr::create(TOCBaseSym
, OutContext
),
2414 // Emit a null environment pointer.
2415 OutStreamer
->emitIntValue(0, PointerSize
);
2417 OutStreamer
->SwitchSection(Current
.first
, Current
.second
);
2420 void PPCAIXAsmPrinter::emitFunctionEntryLabel() {
2421 // It's not necessary to emit the label when we have individual
2422 // function in its own csect.
2423 if (!TM
.getFunctionSections())
2424 PPCAsmPrinter::emitFunctionEntryLabel();
2426 // Emit aliasing label for function entry point label.
2428 GOAliasMap
[&MF
->getFunction()], [this](const GlobalAlias
*Alias
) {
2429 OutStreamer
->emitLabel(
2430 getObjFileLowering().getFunctionEntryPointSymbol(Alias
, TM
));
2434 void PPCAIXAsmPrinter::emitEndOfAsmFile(Module
&M
) {
2435 // If there are no functions and there are no toc-data definitions in this
2436 // module, we will never need to reference the TOC base.
2437 if (M
.empty() && TOCDataGlobalVars
.empty())
2440 // Switch to section to emit TOC base.
2441 OutStreamer
->SwitchSection(getObjFileLowering().getTOCBaseSection());
2443 PPCTargetStreamer
*TS
=
2444 static_cast<PPCTargetStreamer
*>(OutStreamer
->getTargetStreamer());
2446 for (auto &I
: TOC
) {
2447 MCSectionXCOFF
*TCEntry
;
2448 // Setup the csect for the current TC entry. If the variant kind is
2449 // VK_PPC_AIX_TLSGDM the entry represents the region handle, we create a
2450 // new symbol to prefix the name with a dot.
2451 if (I
.first
.second
== MCSymbolRefExpr::VariantKind::VK_PPC_AIX_TLSGDM
) {
2452 SmallString
<128> Name
;
2453 StringRef Prefix
= ".";
2455 Name
+= I
.first
.first
->getName();
2456 MCSymbol
*S
= OutContext
.getOrCreateSymbol(Name
);
2457 TCEntry
= cast
<MCSectionXCOFF
>(
2458 getObjFileLowering().getSectionForTOCEntry(S
, TM
));
2460 TCEntry
= cast
<MCSectionXCOFF
>(
2461 getObjFileLowering().getSectionForTOCEntry(I
.first
.first
, TM
));
2463 OutStreamer
->SwitchSection(TCEntry
);
2465 OutStreamer
->emitLabel(I
.second
);
2467 TS
->emitTCEntry(*I
.first
.first
, I
.first
.second
);
2470 for (const auto *GV
: TOCDataGlobalVars
)
2471 emitGlobalVariableHelper(GV
);
2474 bool PPCAIXAsmPrinter::doInitialization(Module
&M
) {
2475 const bool Result
= PPCAsmPrinter::doInitialization(M
);
2477 auto setCsectAlignment
= [this](const GlobalObject
*GO
) {
2478 // Declarations have 0 alignment which is set by default.
2479 if (GO
->isDeclarationForLinker())
2482 SectionKind GOKind
= getObjFileLowering().getKindForGlobal(GO
, TM
);
2483 MCSectionXCOFF
*Csect
= cast
<MCSectionXCOFF
>(
2484 getObjFileLowering().SectionForGlobal(GO
, GOKind
, TM
));
2486 Align GOAlign
= getGVAlignment(GO
, GO
->getParent()->getDataLayout());
2487 if (GOAlign
> Csect
->getAlignment())
2488 Csect
->setAlignment(GOAlign
);
2491 // We need to know, up front, the alignment of csects for the assembly path,
2492 // because once a .csect directive gets emitted, we could not change the
2493 // alignment value on it.
2494 for (const auto &G
: M
.globals()) {
2495 if (isSpecialLLVMGlobalArrayToSkip(&G
))
2498 if (isSpecialLLVMGlobalArrayForStaticInit(&G
)) {
2499 // Generate a format indicator and a unique module id to be a part of
2500 // the sinit and sterm function names.
2501 if (FormatIndicatorAndUniqueModId
.empty()) {
2502 std::string UniqueModuleId
= getUniqueModuleId(&M
);
2503 if (UniqueModuleId
!= "")
2504 // TODO: Use source file full path to generate the unique module id
2505 // and add a format indicator as a part of function name in case we
2506 // will support more than one format.
2507 FormatIndicatorAndUniqueModId
= "clang_" + UniqueModuleId
.substr(1);
2509 // Use the Pid and current time as the unique module id when we cannot
2510 // generate one based on a module's strong external symbols.
2511 // FIXME: Adjust the comment accordingly after we use source file full
2513 FormatIndicatorAndUniqueModId
=
2514 "clangPidTime_" + llvm::itostr(sys::Process::getProcessId()) +
2515 "_" + llvm::itostr(time(nullptr));
2518 emitSpecialLLVMGlobal(&G
);
2522 setCsectAlignment(&G
);
2525 for (const auto &F
: M
)
2526 setCsectAlignment(&F
);
2528 // Construct an aliasing list for each GlobalObject.
2529 for (const auto &Alias
: M
.aliases()) {
2530 const GlobalObject
*Base
= Alias
.getBaseObject();
2533 "alias without a base object is not yet supported on AIX");
2534 GOAliasMap
[Base
].push_back(&Alias
);
2540 void PPCAIXAsmPrinter::emitInstruction(const MachineInstr
*MI
) {
2541 switch (MI
->getOpcode()) {
2544 case PPC::GETtlsADDR64AIX
:
2545 case PPC::GETtlsADDR32AIX
: {
2546 // The reference to .__tls_get_addr is unknown to the assembler
2547 // so we need to emit an external symbol reference.
2548 MCSymbol
*TlsGetAddr
= createMCSymbolForTlsGetAddr(OutContext
);
2549 ExtSymSDNodeSymbols
.insert(TlsGetAddr
);
2556 const MachineOperand
&MO
= MI
->getOperand(0);
2557 if (MO
.isSymbol()) {
2559 cast
<MCSymbolXCOFF
>(OutContext
.getOrCreateSymbol(MO
.getSymbolName()));
2560 ExtSymSDNodeSymbols
.insert(S
);
2566 case PPC::BL8_NOP_TLS
:
2567 report_fatal_error("TLS call not yet implemented");
2573 case PPC::TAILBCTR8
:
2574 if (MI
->getOperand(0).isSymbol())
2575 report_fatal_error("Tail call for extern symbol not yet supported.");
2587 MCInstBuilder(PPC::ORI
).addReg(PPC::R0
).addReg(PPC::R0
).addImm(0));
2590 return PPCAsmPrinter::emitInstruction(MI
);
2593 bool PPCAIXAsmPrinter::doFinalization(Module
&M
) {
2594 // Do streamer related finalization for DWARF.
2595 if (!MAI
->usesDwarfFileAndLocDirectives() && MMI
->hasDebugInfo())
2596 OutStreamer
->doFinalizationAtSectionEnd(
2597 OutStreamer
->getContext().getObjectFileInfo()->getTextSection());
2599 for (MCSymbol
*Sym
: ExtSymSDNodeSymbols
)
2600 OutStreamer
->emitSymbolAttribute(Sym
, MCSA_Extern
);
2601 return PPCAsmPrinter::doFinalization(M
);
2604 static unsigned mapToSinitPriority(int P
) {
2605 if (P
< 0 || P
> 65535)
2606 report_fatal_error("invalid init priority");
2612 return 20 + (P
- 20) * 16;
2615 return 1004 + (P
- 81);
2618 return 2047 + (P
- 1124) * 33878;
2620 return 2147482625u + (P
- 64512);
2623 static std::string
convertToSinitPriority(int Priority
) {
2624 // This helper function converts clang init priority to values used in sinit
2625 // and sterm functions.
2627 // The conversion strategies are:
2628 // We map the reserved clang/gnu priority range [0, 100] into the sinit/sterm
2629 // reserved priority range [0, 1023] by
2630 // - directly mapping the first 21 and the last 20 elements of the ranges
2631 // - linear interpolating the intermediate values with a step size of 16.
2633 // We map the non reserved clang/gnu priority range of [101, 65535] into the
2634 // sinit/sterm priority range [1024, 2147483648] by:
2635 // - directly mapping the first and the last 1024 elements of the ranges
2636 // - linear interpolating the intermediate values with a step size of 33878.
2637 unsigned int P
= mapToSinitPriority(Priority
);
2639 std::string PrioritySuffix
;
2640 llvm::raw_string_ostream
os(PrioritySuffix
);
2641 os
<< llvm::format_hex_no_prefix(P
, 8);
2643 return PrioritySuffix
;
2646 void PPCAIXAsmPrinter::emitXXStructorList(const DataLayout
&DL
,
2647 const Constant
*List
, bool IsCtor
) {
2648 SmallVector
<Structor
, 8> Structors
;
2649 preprocessXXStructorList(DL
, List
, Structors
);
2650 if (Structors
.empty())
2654 for (Structor
&S
: Structors
) {
2655 if (const ConstantExpr
*CE
= dyn_cast
<ConstantExpr
>(S
.Func
))
2656 S
.Func
= CE
->getOperand(0);
2658 llvm::GlobalAlias::create(
2659 GlobalValue::ExternalLinkage
,
2660 (IsCtor
? llvm::Twine("__sinit") : llvm::Twine("__sterm")) +
2661 llvm::Twine(convertToSinitPriority(S
.Priority
)) +
2662 llvm::Twine("_", FormatIndicatorAndUniqueModId
) +
2663 llvm::Twine("_", llvm::utostr(Index
++)),
2664 cast
<Function
>(S
.Func
));
2668 void PPCAIXAsmPrinter::emitTTypeReference(const GlobalValue
*GV
,
2669 unsigned Encoding
) {
2671 MCSymbol
*TypeInfoSym
= TM
.getSymbol(GV
);
2672 MCSymbol
*TOCEntry
= lookUpOrCreateTOCEntry(TypeInfoSym
);
2673 const MCSymbol
*TOCBaseSym
=
2674 cast
<MCSectionXCOFF
>(getObjFileLowering().getTOCBaseSection())
2675 ->getQualNameSymbol();
2676 auto &Ctx
= OutStreamer
->getContext();
2678 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCEntry
, Ctx
),
2679 MCSymbolRefExpr::create(TOCBaseSym
, Ctx
), Ctx
);
2680 OutStreamer
->emitValue(Exp
, GetSizeOfEncodedValue(Encoding
));
2682 OutStreamer
->emitIntValue(0, GetSizeOfEncodedValue(Encoding
));
2685 // Return a pass that prints the PPC assembly code for a MachineFunction to the
2686 // given output stream.
2688 createPPCAsmPrinterPass(TargetMachine
&tm
,
2689 std::unique_ptr
<MCStreamer
> &&Streamer
) {
2690 if (tm
.getTargetTriple().isOSAIX())
2691 return new PPCAIXAsmPrinter(tm
, std::move(Streamer
));
2693 return new PPCLinuxAsmPrinter(tm
, std::move(Streamer
));
2696 // Force static initialization.
2697 extern "C" LLVM_EXTERNAL_VISIBILITY
void LLVMInitializePowerPCAsmPrinter() {
2698 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
2699 createPPCAsmPrinterPass
);
2700 TargetRegistry::RegisterAsmPrinter(getThePPC32LETarget(),
2701 createPPCAsmPrinterPass
);
2702 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
2703 createPPCAsmPrinterPass
);
2704 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
2705 createPPCAsmPrinterPass
);