Bug Summary

File:llvm/include/llvm/MC/SectionKind.h
Warning:line 159, column 33
The left operand of '==' is a garbage value

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name PPCAsmPrinter.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-11/lib/clang/11.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/Target/PowerPC -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/include -I /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-11/lib/clang/11.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++14 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/build-llvm/lib/Target/PowerPC -fdebug-prefix-map=/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347=. -ferror-limit 19 -fmessage-length 0 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -o /tmp/scan-build-2020-03-09-184146-41876-1 -x c++ /build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp

1//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file 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'.
12//
13// Documentation at http://developer.apple.com/documentation/DeveloperTools/
14// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
15//
16//===----------------------------------------------------------------------===//
17
18#include "MCTargetDesc/PPCInstPrinter.h"
19#include "MCTargetDesc/PPCMCExpr.h"
20#include "MCTargetDesc/PPCMCTargetDesc.h"
21#include "MCTargetDesc/PPCPredicates.h"
22#include "PPC.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/StringRef.h"
31#include "llvm/ADT/Triple.h"
32#include "llvm/ADT/Twine.h"
33#include "llvm/BinaryFormat/ELF.h"
34#include "llvm/BinaryFormat/MachO.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/MCExpr.h"
51#include "llvm/MC/MCInst.h"
52#include "llvm/MC/MCInstBuilder.h"
53#include "llvm/MC/MCSectionELF.h"
54#include "llvm/MC/MCSectionMachO.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/ErrorHandling.h"
65#include "llvm/Support/TargetRegistry.h"
66#include "llvm/Support/raw_ostream.h"
67#include "llvm/Target/TargetMachine.h"
68#include <algorithm>
69#include <cassert>
70#include <cstdint>
71#include <memory>
72#include <new>
73
74using namespace llvm;
75
76#define DEBUG_TYPE"asmprinter" "asmprinter"
77
78namespace {
79
80class PPCAsmPrinter : public AsmPrinter {
81protected:
82 MapVector<const MCSymbol *, MCSymbol *> TOC;
83 const PPCSubtarget *Subtarget = nullptr;
84 StackMaps SM;
85
86 virtual MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO);
87
88public:
89 explicit PPCAsmPrinter(TargetMachine &TM,
90 std::unique_ptr<MCStreamer> Streamer)
91 : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
92
93 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
94
95 MCSymbol *lookUpOrCreateTOCEntry(const MCSymbol *Sym);
96
97 bool doInitialization(Module &M) override {
98 if (!TOC.empty())
99 TOC.clear();
100 return AsmPrinter::doInitialization(M);
101 }
102
103 void emitInstruction(const MachineInstr *MI) override;
104
105 /// This function is for PrintAsmOperand and PrintAsmMemoryOperand,
106 /// invoked by EmitMSInlineAsmStr and EmitGCCInlineAsmStr only.
107 /// The \p MI would be INLINEASM ONLY.
108 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
109
110 void PrintSymbolOperand(const MachineOperand &MO, raw_ostream &O) override;
111 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
112 const char *ExtraCode, raw_ostream &O) override;
113 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
114 const char *ExtraCode, raw_ostream &O) override;
115
116 void emitEndOfAsmFile(Module &M) override;
117
118 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
119 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
120 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
121 bool runOnMachineFunction(MachineFunction &MF) override {
122 Subtarget = &MF.getSubtarget<PPCSubtarget>();
123 bool Changed = AsmPrinter::runOnMachineFunction(MF);
124 emitXRayTable();
125 return Changed;
126 }
127};
128
129/// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
130class PPCLinuxAsmPrinter : public PPCAsmPrinter {
131public:
132 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
133 std::unique_ptr<MCStreamer> Streamer)
134 : PPCAsmPrinter(TM, std::move(Streamer)) {}
135
136 StringRef getPassName() const override {
137 return "Linux PPC Assembly Printer";
138 }
139
140 void emitStartOfAsmFile(Module &M) override;
141 void emitEndOfAsmFile(Module &) override;
142
143 void emitFunctionEntryLabel() override;
144
145 void emitFunctionBodyStart() override;
146 void emitFunctionBodyEnd() override;
147 void emitInstruction(const MachineInstr *MI) override;
148};
149
150class PPCAIXAsmPrinter : public PPCAsmPrinter {
151private:
152 static void ValidateGV(const GlobalVariable *GV);
153protected:
154 MCSymbol *getMCSymbolForTOCPseudoMO(const MachineOperand &MO) override;
155
156public:
157 PPCAIXAsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
158 : PPCAsmPrinter(TM, std::move(Streamer)) {}
159
160 StringRef getPassName() const override { return "AIX PPC Assembly Printer"; }
161
162 void SetupMachineFunction(MachineFunction &MF) override;
163
164 const MCExpr *lowerConstant(const Constant *CV) override;
165
166 void emitGlobalVariable(const GlobalVariable *GV) override;
167
168 void emitFunctionDescriptor() override;
169
170 void emitEndOfAsmFile(Module &) override;
171};
172
173} // end anonymous namespace
174
175void PPCAsmPrinter::PrintSymbolOperand(const MachineOperand &MO,
176 raw_ostream &O) {
177 // Computing the address of a global symbol, not calling it.
178 const GlobalValue *GV = MO.getGlobal();
179 getSymbol(GV)->print(O, MAI);
180 printOffset(MO.getOffset(), O);
181}
182
183void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
184 raw_ostream &O) {
185 const DataLayout &DL = getDataLayout();
186 const MachineOperand &MO = MI->getOperand(OpNo);
187
188 switch (MO.getType()) {
189 case MachineOperand::MO_Register: {
190 // The MI is INLINEASM ONLY and UseVSXReg is always false.
191 const char *RegName = PPCInstPrinter::getRegisterName(MO.getReg());
192
193 // Linux assembler (Others?) does not take register mnemonics.
194 // FIXME - What about special registers used in mfspr/mtspr?
195 O << PPCRegisterInfo::stripRegisterPrefix(RegName);
196 return;
197 }
198 case MachineOperand::MO_Immediate:
199 O << MO.getImm();
200 return;
201
202 case MachineOperand::MO_MachineBasicBlock:
203 MO.getMBB()->getSymbol()->print(O, MAI);
204 return;
205 case MachineOperand::MO_ConstantPoolIndex:
206 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
207 << MO.getIndex();
208 return;
209 case MachineOperand::MO_BlockAddress:
210 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
211 return;
212 case MachineOperand::MO_GlobalAddress: {
213 PrintSymbolOperand(MO, O);
214 return;
215 }
216
217 default:
218 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
219 return;
220 }
221}
222
223/// PrintAsmOperand - Print out an operand for an inline asm expression.
224///
225bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
226 const char *ExtraCode, raw_ostream &O) {
227 // Does this asm operand have a single letter operand modifier?
228 if (ExtraCode && ExtraCode[0]) {
229 if (ExtraCode[1] != 0) return true; // Unknown modifier.
230
231 switch (ExtraCode[0]) {
232 default:
233 // See if this is a generic print operand
234 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
235 case 'L': // Write second word of DImode reference.
236 // Verify that this operand has two consecutive registers.
237 if (!MI->getOperand(OpNo).isReg() ||
238 OpNo+1 == MI->getNumOperands() ||
239 !MI->getOperand(OpNo+1).isReg())
240 return true;
241 ++OpNo; // Return the high-part.
242 break;
243 case 'I':
244 // Write 'i' if an integer constant, otherwise nothing. Used to print
245 // addi vs add, etc.
246 if (MI->getOperand(OpNo).isImm())
247 O << "i";
248 return false;
249 case 'x':
250 if(!MI->getOperand(OpNo).isReg())
251 return true;
252 // This operand uses VSX numbering.
253 // If the operand is a VMX register, convert it to a VSX register.
254 Register Reg = MI->getOperand(OpNo).getReg();
255 if (PPCInstrInfo::isVRRegister(Reg))
256 Reg = PPC::VSX32 + (Reg - PPC::V0);
257 else if (PPCInstrInfo::isVFRegister(Reg))
258 Reg = PPC::VSX32 + (Reg - PPC::VF0);
259 const char *RegName;
260 RegName = PPCInstPrinter::getRegisterName(Reg);
261 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
262 O << RegName;
263 return false;
264 }
265 }
266
267 printOperand(MI, OpNo, O);
268 return false;
269}
270
271// At the moment, all inline asm memory operands are a single register.
272// In any case, the output of this routine should always be just one
273// assembler operand.
274
275bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
276 const char *ExtraCode,
277 raw_ostream &O) {
278 if (ExtraCode && ExtraCode[0]) {
279 if (ExtraCode[1] != 0) return true; // Unknown modifier.
280
281 switch (ExtraCode[0]) {
282 default: return true; // Unknown modifier.
283 case 'y': { // A memory reference for an X-form instruction
284 O << "0, ";
285 printOperand(MI, OpNo, O);
286 return false;
287 }
288 case 'U': // Print 'u' for update form.
289 case 'X': // Print 'x' for indexed form.
290 {
291 // FIXME: Currently for PowerPC memory operands are always loaded
292 // into a register, so we never get an update or indexed form.
293 // This is bad even for offset forms, since even if we know we
294 // have a value in -16(r1), we will generate a load into r<n>
295 // and then load from 0(r<n>). Until that issue is fixed,
296 // tolerate 'U' and 'X' but don't output anything.
297 assert(MI->getOperand(OpNo).isReg())((MI->getOperand(OpNo).isReg()) ? static_cast<void> (
0) : __assert_fail ("MI->getOperand(OpNo).isReg()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 297, __PRETTY_FUNCTION__))
;
298 return false;
299 }
300 }
301 }
302
303 assert(MI->getOperand(OpNo).isReg())((MI->getOperand(OpNo).isReg()) ? static_cast<void> (
0) : __assert_fail ("MI->getOperand(OpNo).isReg()", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 303, __PRETTY_FUNCTION__))
;
304 O << "0(";
305 printOperand(MI, OpNo, O);
306 O << ")";
307 return false;
308}
309
310/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
311/// exists for it. If not, create one. Then return a symbol that references
312/// the TOC entry.
313MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(const MCSymbol *Sym) {
314 MCSymbol *&TOCEntry = TOC[Sym];
315 if (!TOCEntry)
316 TOCEntry = createTempSymbol("C");
317 return TOCEntry;
318}
319
320void PPCAsmPrinter::emitEndOfAsmFile(Module &M) {
321 emitStackMaps(SM);
322}
323
324void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
325 unsigned NumNOPBytes = MI.getOperand(1).getImm();
326
327 auto &Ctx = OutStreamer->getContext();
328 MCSymbol *MILabel = Ctx.createTempSymbol();
329 OutStreamer->emitLabel(MILabel);
330
331 SM.recordStackMap(*MILabel, MI);
332 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!")((NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!"
) ? static_cast<void> (0) : __assert_fail ("NumNOPBytes % 4 == 0 && \"Invalid number of NOP bytes requested!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 332, __PRETTY_FUNCTION__))
;
333
334 // Scan ahead to trim the shadow.
335 const MachineBasicBlock &MBB = *MI.getParent();
336 MachineBasicBlock::const_iterator MII(MI);
337 ++MII;
338 while (NumNOPBytes > 0) {
339 if (MII == MBB.end() || MII->isCall() ||
340 MII->getOpcode() == PPC::DBG_VALUE ||
341 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
342 MII->getOpcode() == TargetOpcode::STACKMAP)
343 break;
344 ++MII;
345 NumNOPBytes -= 4;
346 }
347
348 // Emit nops.
349 for (unsigned i = 0; i < NumNOPBytes; i += 4)
350 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
351}
352
353// Lower a patchpoint of the form:
354// [<def>], <id>, <numBytes>, <target>, <numArgs>
355void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
356 auto &Ctx = OutStreamer->getContext();
357 MCSymbol *MILabel = Ctx.createTempSymbol();
358 OutStreamer->emitLabel(MILabel);
359
360 SM.recordPatchPoint(*MILabel, MI);
361 PatchPointOpers Opers(&MI);
362
363 unsigned EncodedBytes = 0;
364 const MachineOperand &CalleeMO = Opers.getCallTarget();
365
366 if (CalleeMO.isImm()) {
367 int64_t CallTarget = CalleeMO.getImm();
368 if (CallTarget) {
369 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&(((CallTarget & 0xFFFFFFFFFFFF) == CallTarget && "High 16 bits of call target should be zero."
) ? static_cast<void> (0) : __assert_fail ("(CallTarget & 0xFFFFFFFFFFFF) == CallTarget && \"High 16 bits of call target should be zero.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 370, __PRETTY_FUNCTION__))
370 "High 16 bits of call target should be zero.")(((CallTarget & 0xFFFFFFFFFFFF) == CallTarget && "High 16 bits of call target should be zero."
) ? static_cast<void> (0) : __assert_fail ("(CallTarget & 0xFFFFFFFFFFFF) == CallTarget && \"High 16 bits of call target should be zero.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 370, __PRETTY_FUNCTION__))
;
371 Register ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
372 EncodedBytes = 0;
373 // Materialize the jump address:
374 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
375 .addReg(ScratchReg)
376 .addImm((CallTarget >> 32) & 0xFFFF));
377 ++EncodedBytes;
378 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
379 .addReg(ScratchReg)
380 .addReg(ScratchReg)
381 .addImm(32).addImm(16));
382 ++EncodedBytes;
383 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
384 .addReg(ScratchReg)
385 .addReg(ScratchReg)
386 .addImm((CallTarget >> 16) & 0xFFFF));
387 ++EncodedBytes;
388 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
389 .addReg(ScratchReg)
390 .addReg(ScratchReg)
391 .addImm(CallTarget & 0xFFFF));
392
393 // Save the current TOC pointer before the remote call.
394 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
395 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
396 .addReg(PPC::X2)
397 .addImm(TOCSaveOffset)
398 .addReg(PPC::X1));
399 ++EncodedBytes;
400
401 // If we're on ELFv1, then we need to load the actual function pointer
402 // from the function descriptor.
403 if (!Subtarget->isELFv2ABI()) {
404 // Load the new TOC pointer and the function address, but not r11
405 // (needing this is rare, and loading it here would prevent passing it
406 // via a 'nest' parameter.
407 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
408 .addReg(PPC::X2)
409 .addImm(8)
410 .addReg(ScratchReg));
411 ++EncodedBytes;
412 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
413 .addReg(ScratchReg)
414 .addImm(0)
415 .addReg(ScratchReg));
416 ++EncodedBytes;
417 }
418
419 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
420 .addReg(ScratchReg));
421 ++EncodedBytes;
422 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
423 ++EncodedBytes;
424
425 // Restore the TOC pointer after the call.
426 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
427 .addReg(PPC::X2)
428 .addImm(TOCSaveOffset)
429 .addReg(PPC::X1));
430 ++EncodedBytes;
431 }
432 } else if (CalleeMO.isGlobal()) {
433 const GlobalValue *GValue = CalleeMO.getGlobal();
434 MCSymbol *MOSymbol = getSymbol(GValue);
435 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
436
437 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
438 .addExpr(SymVar));
439 EncodedBytes += 2;
440 }
441
442 // Each instruction is 4 bytes.
443 EncodedBytes *= 4;
444
445 // Emit padding.
446 unsigned NumBytes = Opers.getNumPatchBytes();
447 assert(NumBytes >= EncodedBytes &&((NumBytes >= EncodedBytes && "Patchpoint can't request size less than the length of a call."
) ? static_cast<void> (0) : __assert_fail ("NumBytes >= EncodedBytes && \"Patchpoint can't request size less than the length of a call.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 448, __PRETTY_FUNCTION__))
448 "Patchpoint can't request size less than the length of a call.")((NumBytes >= EncodedBytes && "Patchpoint can't request size less than the length of a call."
) ? static_cast<void> (0) : __assert_fail ("NumBytes >= EncodedBytes && \"Patchpoint can't request size less than the length of a call.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 448, __PRETTY_FUNCTION__))
;
449 assert((NumBytes - EncodedBytes) % 4 == 0 &&(((NumBytes - EncodedBytes) % 4 == 0 && "Invalid number of NOP bytes requested!"
) ? static_cast<void> (0) : __assert_fail ("(NumBytes - EncodedBytes) % 4 == 0 && \"Invalid number of NOP bytes requested!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 450, __PRETTY_FUNCTION__))
450 "Invalid number of NOP bytes requested!")(((NumBytes - EncodedBytes) % 4 == 0 && "Invalid number of NOP bytes requested!"
) ? static_cast<void> (0) : __assert_fail ("(NumBytes - EncodedBytes) % 4 == 0 && \"Invalid number of NOP bytes requested!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 450, __PRETTY_FUNCTION__))
;
451 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
452 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
453}
454
455/// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
456/// call to __tls_get_addr to the current output stream.
457void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
458 MCSymbolRefExpr::VariantKind VK) {
459 StringRef Name = "__tls_get_addr";
460 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
461 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
462 const Module *M = MF->getFunction().getParent();
463
464 assert(MI->getOperand(0).isReg() &&((MI->getOperand(0).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(0).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(0).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must define GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(0).isReg() && ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must define GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 467, __PRETTY_FUNCTION__))
465 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||((MI->getOperand(0).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(0).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(0).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must define GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(0).isReg() && ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must define GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 467, __PRETTY_FUNCTION__))
466 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&((MI->getOperand(0).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(0).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(0).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must define GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(0).isReg() && ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must define GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 467, __PRETTY_FUNCTION__))
467 "GETtls[ld]ADDR[32] must define GPR3")((MI->getOperand(0).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(0).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(0).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must define GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(0).isReg() && ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must define GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 467, __PRETTY_FUNCTION__))
;
468 assert(MI->getOperand(1).isReg() &&((MI->getOperand(1).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(1).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(1).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must read GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(1).isReg() && ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must read GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 471, __PRETTY_FUNCTION__))
469 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||((MI->getOperand(1).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(1).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(1).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must read GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(1).isReg() && ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must read GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 471, __PRETTY_FUNCTION__))
470 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&((MI->getOperand(1).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(1).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(1).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must read GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(1).isReg() && ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must read GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 471, __PRETTY_FUNCTION__))
471 "GETtls[ld]ADDR[32] must read GPR3")((MI->getOperand(1).isReg() && ((Subtarget->isPPC64
() && MI->getOperand(1).getReg() == PPC::X3) || (!
Subtarget->isPPC64() && MI->getOperand(1).getReg
() == PPC::R3)) && "GETtls[ld]ADDR[32] must read GPR3"
) ? static_cast<void> (0) : __assert_fail ("MI->getOperand(1).isReg() && ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) || (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) && \"GETtls[ld]ADDR[32] must read GPR3\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 471, __PRETTY_FUNCTION__))
;
472
473 if (Subtarget->is32BitELFABI() && isPositionIndependent())
474 Kind = MCSymbolRefExpr::VK_PLT;
475
476 const MCExpr *TlsRef =
477 MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
478
479 // Add 32768 offset to the symbol so we follow up the latest GOT/PLT ABI.
480 if (Kind == MCSymbolRefExpr::VK_PLT && Subtarget->isSecurePlt() &&
481 M->getPICLevel() == PICLevel::BigPIC)
482 TlsRef = MCBinaryExpr::createAdd(
483 TlsRef, MCConstantExpr::create(32768, OutContext), OutContext);
484 const MachineOperand &MO = MI->getOperand(2);
485 const GlobalValue *GValue = MO.getGlobal();
486 MCSymbol *MOSymbol = getSymbol(GValue);
487 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
488 EmitToStreamer(*OutStreamer,
489 MCInstBuilder(Subtarget->isPPC64() ?
490 PPC::BL8_NOP_TLS : PPC::BL_TLS)
491 .addExpr(TlsRef)
492 .addExpr(SymVar));
493}
494
495/// Map a machine operand for a TOC pseudo-machine instruction to its
496/// corresponding MCSymbol.
497MCSymbol *PPCAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
498 switch (MO.getType()) {
499 case MachineOperand::MO_GlobalAddress:
500 return getSymbol(MO.getGlobal());
501 case MachineOperand::MO_ConstantPoolIndex:
502 return GetCPISymbol(MO.getIndex());
503 case MachineOperand::MO_JumpTableIndex:
504 return GetJTISymbol(MO.getIndex());
505 case MachineOperand::MO_BlockAddress:
506 return GetBlockAddressSymbol(MO.getBlockAddress());
507 default:
508 llvm_unreachable("Unexpected operand type to get symbol.")::llvm::llvm_unreachable_internal("Unexpected operand type to get symbol."
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 508)
;
509 }
510}
511
512/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
513/// the current output stream.
514///
515void PPCAsmPrinter::emitInstruction(const MachineInstr *MI) {
516 MCInst TmpInst;
517 const bool IsPPC64 = Subtarget->isPPC64();
518 const bool IsAIX = Subtarget->isAIXABI();
519 const Module *M = MF->getFunction().getParent();
520 PICLevel::Level PL = M->getPICLevel();
521
522#ifndef NDEBUG
523 // Validate that SPE and FPU are mutually exclusive in codegen
524 if (!MI->isInlineAsm()) {
525 for (const MachineOperand &MO: MI->operands()) {
526 if (MO.isReg()) {
527 Register Reg = MO.getReg();
528 if (Subtarget->hasSPE()) {
529 if (PPC::F4RCRegClass.contains(Reg) ||
530 PPC::F8RCRegClass.contains(Reg) ||
531 PPC::QBRCRegClass.contains(Reg) ||
532 PPC::QFRCRegClass.contains(Reg) ||
533 PPC::QSRCRegClass.contains(Reg) ||
534 PPC::VFRCRegClass.contains(Reg) ||
535 PPC::VRRCRegClass.contains(Reg) ||
536 PPC::VSFRCRegClass.contains(Reg) ||
537 PPC::VSSRCRegClass.contains(Reg)
538 )
539 llvm_unreachable("SPE targets cannot have FPRegs!")::llvm::llvm_unreachable_internal("SPE targets cannot have FPRegs!"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 539)
;
540 } else {
541 if (PPC::SPERCRegClass.contains(Reg))
542 llvm_unreachable("SPE register found in FPU-targeted code!")::llvm::llvm_unreachable_internal("SPE register found in FPU-targeted code!"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 542)
;
543 }
544 }
545 }
546 }
547#endif
548 // Lower multi-instruction pseudo operations.
549 switch (MI->getOpcode()) {
550 default: break;
551 case TargetOpcode::DBG_VALUE:
552 llvm_unreachable("Should be handled target independently")::llvm::llvm_unreachable_internal("Should be handled target independently"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 552)
;
553 case TargetOpcode::STACKMAP:
554 return LowerSTACKMAP(SM, *MI);
555 case TargetOpcode::PATCHPOINT:
556 return LowerPATCHPOINT(SM, *MI);
557
558 case PPC::MoveGOTtoLR: {
559 // Transform %lr = MoveGOTtoLR
560 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
561 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
562 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
563 // blrl
564 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
565 MCSymbol *GOTSymbol =
566 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
567 const MCExpr *OffsExpr =
568 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol,
569 MCSymbolRefExpr::VK_PPC_LOCAL,
570 OutContext),
571 MCConstantExpr::create(4, OutContext),
572 OutContext);
573
574 // Emit the 'bl'.
575 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
576 return;
577 }
578 case PPC::MovePCtoLR:
579 case PPC::MovePCtoLR8: {
580 // Transform %lr = MovePCtoLR
581 // Into this, where the label is the PIC base:
582 // bl L1$pb
583 // L1$pb:
584 MCSymbol *PICBase = MF->getPICBaseSymbol();
585
586 // Emit the 'bl'.
587 EmitToStreamer(*OutStreamer,
588 MCInstBuilder(PPC::BL)
589 // FIXME: We would like an efficient form for this, so we
590 // don't have to do a lot of extra uniquing.
591 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
592
593 // Emit the label.
594 OutStreamer->emitLabel(PICBase);
595 return;
596 }
597 case PPC::UpdateGBR: {
598 // Transform %rd = UpdateGBR(%rt, %ri)
599 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
600 // add %rd, %rt, %ri
601 // or into (if secure plt mode is on):
602 // addis r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@ha
603 // addi r30, r30, {.LTOC,_GLOBAL_OFFSET_TABLE} - .L0$pb@l
604 // Get the offset from the GOT Base Register to the GOT
605 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
606 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
607 unsigned PICR = TmpInst.getOperand(0).getReg();
608 MCSymbol *BaseSymbol = OutContext.getOrCreateSymbol(
609 M->getPICLevel() == PICLevel::SmallPIC ? "_GLOBAL_OFFSET_TABLE_"
610 : ".LTOC");
611 const MCExpr *PB =
612 MCSymbolRefExpr::create(MF->getPICBaseSymbol(), OutContext);
613
614 const MCExpr *DeltaExpr = MCBinaryExpr::createSub(
615 MCSymbolRefExpr::create(BaseSymbol, OutContext), PB, OutContext);
616
617 const MCExpr *DeltaHi = PPCMCExpr::createHa(DeltaExpr, OutContext);
618 EmitToStreamer(
619 *OutStreamer,
620 MCInstBuilder(PPC::ADDIS).addReg(PICR).addReg(PICR).addExpr(DeltaHi));
621
622 const MCExpr *DeltaLo = PPCMCExpr::createLo(DeltaExpr, OutContext);
623 EmitToStreamer(
624 *OutStreamer,
625 MCInstBuilder(PPC::ADDI).addReg(PICR).addReg(PICR).addExpr(DeltaLo));
626 return;
627 } else {
628 MCSymbol *PICOffset =
629 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
630 TmpInst.setOpcode(PPC::LWZ);
631 const MCExpr *Exp =
632 MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
633 const MCExpr *PB =
634 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
635 MCSymbolRefExpr::VK_None,
636 OutContext);
637 const MCOperand TR = TmpInst.getOperand(1);
638 const MCOperand PICR = TmpInst.getOperand(0);
639
640 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
641 TmpInst.getOperand(1) =
642 MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
643 TmpInst.getOperand(0) = TR;
644 TmpInst.getOperand(2) = PICR;
645 EmitToStreamer(*OutStreamer, TmpInst);
646
647 TmpInst.setOpcode(PPC::ADD4);
648 TmpInst.getOperand(0) = PICR;
649 TmpInst.getOperand(1) = TR;
650 TmpInst.getOperand(2) = PICR;
651 EmitToStreamer(*OutStreamer, TmpInst);
652 return;
653 }
654 }
655 case PPC::LWZtoc: {
656 // Transform %rN = LWZtoc @op1, %r2
657 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
658
659 // Change the opcode to LWZ.
660 TmpInst.setOpcode(PPC::LWZ);
661
662 const MachineOperand &MO = MI->getOperand(1);
663 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for LWZtoc.") ? static_cast<
void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for LWZtoc.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 664, __PRETTY_FUNCTION__))
664 "Invalid operand for LWZtoc.")(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for LWZtoc.") ? static_cast<
void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for LWZtoc.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 664, __PRETTY_FUNCTION__))
;
665
666 // Map the operand to its corresponding MCSymbol.
667 const MCSymbol *const MOSymbol = getMCSymbolForTOCPseudoMO(MO);
668
669 // Create a reference to the GOT entry for the symbol. The GOT entry will be
670 // synthesized later.
671 if (PL == PICLevel::SmallPIC && !IsAIX) {
672 const MCExpr *Exp =
673 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,
674 OutContext);
675 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
676 EmitToStreamer(*OutStreamer, TmpInst);
677 return;
678 }
679
680 // Otherwise, use the TOC. 'TOCEntry' is a label used to reference the
681 // storage allocated in the TOC which contains the address of
682 // 'MOSymbol'. Said TOC entry will be synthesized later.
683 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
684 const MCExpr *Exp =
685 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None, OutContext);
686
687 // AIX uses the label directly as the lwz displacement operand for
688 // references into the toc section. The displacement value will be generated
689 // relative to the toc-base.
690 if (IsAIX) {
691 assert(((TM.getCodeModel() == CodeModel::Small && "This pseudo should only be selected for 32-bit small code model."
) ? static_cast<void> (0) : __assert_fail ("TM.getCodeModel() == CodeModel::Small && \"This pseudo should only be selected for 32-bit small code model.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 693, __PRETTY_FUNCTION__))
692 TM.getCodeModel() == CodeModel::Small &&((TM.getCodeModel() == CodeModel::Small && "This pseudo should only be selected for 32-bit small code model."
) ? static_cast<void> (0) : __assert_fail ("TM.getCodeModel() == CodeModel::Small && \"This pseudo should only be selected for 32-bit small code model.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 693, __PRETTY_FUNCTION__))
693 "This pseudo should only be selected for 32-bit small code model.")((TM.getCodeModel() == CodeModel::Small && "This pseudo should only be selected for 32-bit small code model."
) ? static_cast<void> (0) : __assert_fail ("TM.getCodeModel() == CodeModel::Small && \"This pseudo should only be selected for 32-bit small code model.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 693, __PRETTY_FUNCTION__))
;
694 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
695 EmitToStreamer(*OutStreamer, TmpInst);
696 return;
697 }
698
699 // Create an explicit subtract expression between the local symbol and
700 // '.LTOC' to manifest the toc-relative offset.
701 const MCExpr *PB = MCSymbolRefExpr::create(
702 OutContext.getOrCreateSymbol(Twine(".LTOC")), OutContext);
703 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
704 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
705 EmitToStreamer(*OutStreamer, TmpInst);
706 return;
707 }
708 case PPC::LDtocJTI:
709 case PPC::LDtocCPT:
710 case PPC::LDtocBA:
711 case PPC::LDtoc: {
712 // Transform %x3 = LDtoc @min1, %x2
713 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
714
715 // Change the opcode to LD.
716 TmpInst.setOpcode(PPC::LD);
717
718 const MachineOperand &MO = MI->getOperand(1);
719 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand!") ? static_cast<void> (
0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 720, __PRETTY_FUNCTION__))
720 "Invalid operand!")(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand!") ? static_cast<void> (
0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 720, __PRETTY_FUNCTION__))
;
721
722 // Map the machine operand to its corresponding MCSymbol, then map the
723 // global address operand to be a reference to the TOC entry we will
724 // synthesize later.
725 MCSymbol *TOCEntry =
726 lookUpOrCreateTOCEntry(getMCSymbolForTOCPseudoMO(MO));
727
728 const MCSymbolRefExpr::VariantKind VK =
729 IsAIX ? MCSymbolRefExpr::VK_None : MCSymbolRefExpr::VK_PPC_TOC;
730 const MCExpr *Exp =
731 MCSymbolRefExpr::create(TOCEntry, VK, OutContext);
732 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
733 EmitToStreamer(*OutStreamer, TmpInst);
734 return;
735 }
736 case PPC::ADDIStocHA: {
737 assert((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) &&(((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel
::Large) && "This pseudo should only be selected for 32-bit large code model on"
" AIX.") ? static_cast<void> (0) : __assert_fail ("(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) && \"This pseudo should only be selected for 32-bit large code model on\" \" AIX.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 739, __PRETTY_FUNCTION__))
738 "This pseudo should only be selected for 32-bit large code model on"(((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel
::Large) && "This pseudo should only be selected for 32-bit large code model on"
" AIX.") ? static_cast<void> (0) : __assert_fail ("(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) && \"This pseudo should only be selected for 32-bit large code model on\" \" AIX.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 739, __PRETTY_FUNCTION__))
739 " AIX.")(((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel
::Large) && "This pseudo should only be selected for 32-bit large code model on"
" AIX.") ? static_cast<void> (0) : __assert_fail ("(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large) && \"This pseudo should only be selected for 32-bit large code model on\" \" AIX.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 739, __PRETTY_FUNCTION__))
;
740
741 // Transform %rd = ADDIStocHA %rA, @sym(%r2)
742 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
743
744 // Change the opcode to ADDIS.
745 TmpInst.setOpcode(PPC::ADDIS);
746
747 const MachineOperand &MO = MI->getOperand(2);
748 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for ADDIStocHA.") ? static_cast
<void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for ADDIStocHA.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 749, __PRETTY_FUNCTION__))
749 "Invalid operand for ADDIStocHA.")(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for ADDIStocHA.") ? static_cast
<void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for ADDIStocHA.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 749, __PRETTY_FUNCTION__))
;
750
751 // Map the machine operand to its corresponding MCSymbol.
752 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
753
754 // Always use TOC on AIX. Map the global address operand to be a reference
755 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
756 // reference the storage allocated in the TOC which contains the address of
757 // 'MOSymbol'.
758 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
759 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
760 MCSymbolRefExpr::VK_PPC_U,
761 OutContext);
762 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
763 EmitToStreamer(*OutStreamer, TmpInst);
764 return;
765 }
766 case PPC::LWZtocL: {
767 assert(IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large &&((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel
::Large && "This pseudo should only be selected for 32-bit large code model on"
" AIX.") ? static_cast<void> (0) : __assert_fail ("IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large && \"This pseudo should only be selected for 32-bit large code model on\" \" AIX.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 769, __PRETTY_FUNCTION__))
768 "This pseudo should only be selected for 32-bit large code model on"((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel
::Large && "This pseudo should only be selected for 32-bit large code model on"
" AIX.") ? static_cast<void> (0) : __assert_fail ("IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large && \"This pseudo should only be selected for 32-bit large code model on\" \" AIX.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 769, __PRETTY_FUNCTION__))
769 " AIX.")((IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel
::Large && "This pseudo should only be selected for 32-bit large code model on"
" AIX.") ? static_cast<void> (0) : __assert_fail ("IsAIX && !IsPPC64 && TM.getCodeModel() == CodeModel::Large && \"This pseudo should only be selected for 32-bit large code model on\" \" AIX.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 769, __PRETTY_FUNCTION__))
;
770
771 // Transform %rd = LWZtocL @sym, %rs.
772 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
773
774 // Change the opcode to lwz.
775 TmpInst.setOpcode(PPC::LWZ);
776
777 const MachineOperand &MO = MI->getOperand(1);
778 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for LWZtocL.") ? static_cast<
void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for LWZtocL.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 779, __PRETTY_FUNCTION__))
779 "Invalid operand for LWZtocL.")(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for LWZtocL.") ? static_cast<
void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for LWZtocL.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 779, __PRETTY_FUNCTION__))
;
780
781 // Map the machine operand to its corresponding MCSymbol.
782 MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
783
784 // Always use TOC on AIX. Map the global address operand to be a reference
785 // to the TOC entry we will synthesize later. 'TOCEntry' is a label used to
786 // reference the storage allocated in the TOC which contains the address of
787 // 'MOSymbol'.
788 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
789 const MCExpr *Exp = MCSymbolRefExpr::create(TOCEntry,
790 MCSymbolRefExpr::VK_PPC_L,
791 OutContext);
792 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
793 EmitToStreamer(*OutStreamer, TmpInst);
794 return;
795 }
796 case PPC::ADDIStocHA8: {
797 // Transform %xd = ADDIStocHA8 %x2, @sym
798 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
799
800 // Change the opcode to ADDIS8. If the global address is the address of
801 // an external symbol, is a jump table address, is a block address, or is a
802 // constant pool index with large code model enabled, then generate a TOC
803 // entry and reference that. Otherwise, reference the symbol directly.
804 TmpInst.setOpcode(PPC::ADDIS8);
805
806 const MachineOperand &MO = MI->getOperand(2);
807 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) &&(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for ADDIStocHA8!") ? static_cast
<void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for ADDIStocHA8!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 808, __PRETTY_FUNCTION__))
808 "Invalid operand for ADDIStocHA8!")(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for ADDIStocHA8!") ? static_cast
<void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for ADDIStocHA8!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 808, __PRETTY_FUNCTION__))
;
809
810 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
811
812 const bool GlobalToc =
813 MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal());
814 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
815 (MO.isCPI() && TM.getCodeModel() == CodeModel::Large))
816 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
817
818 const MCSymbolRefExpr::VariantKind VK =
819 IsAIX ? MCSymbolRefExpr::VK_PPC_U : MCSymbolRefExpr::VK_PPC_TOC_HA;
820
821 const MCExpr *Exp =
822 MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
823
824 if (!MO.isJTI() && MO.getOffset())
825 Exp = MCBinaryExpr::createAdd(Exp,
826 MCConstantExpr::create(MO.getOffset(),
827 OutContext),
828 OutContext);
829
830 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
831 EmitToStreamer(*OutStreamer, TmpInst);
832 return;
833 }
834 case PPC::LDtocL: {
835 // Transform %xd = LDtocL @sym, %xs
836 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
837
838 // Change the opcode to LD. If the global address is the address of
839 // an external symbol, is a jump table address, is a block address, or is
840 // a constant pool index with large code model enabled, then generate a
841 // TOC entry and reference that. Otherwise, reference the symbol directly.
842 TmpInst.setOpcode(PPC::LD);
843
844 const MachineOperand &MO = MI->getOperand(1);
845 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for LDtocL!") ? static_cast<
void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for LDtocL!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 847, __PRETTY_FUNCTION__))
846 MO.isBlockAddress()) &&(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for LDtocL!") ? static_cast<
void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for LDtocL!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 847, __PRETTY_FUNCTION__))
847 "Invalid operand for LDtocL!")(((MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress
()) && "Invalid operand for LDtocL!") ? static_cast<
void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress()) && \"Invalid operand for LDtocL!\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 847, __PRETTY_FUNCTION__))
;
848
849 LLVM_DEBUG(assert(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asmprinter")) { (((!MO.isGlobal() || Subtarget->isGVIndirectSymbol
(MO.getGlobal())) && "LDtocL used on symbol that could be accessed directly is "
"invalid. Must match ADDIStocHA8.") ? static_cast<void>
(0) : __assert_fail ("(!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) && \"LDtocL used on symbol that could be accessed directly is \" \"invalid. Must match ADDIStocHA8.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 852, __PRETTY_FUNCTION__)); } } while (false)
850 (!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asmprinter")) { (((!MO.isGlobal() || Subtarget->isGVIndirectSymbol
(MO.getGlobal())) && "LDtocL used on symbol that could be accessed directly is "
"invalid. Must match ADDIStocHA8.") ? static_cast<void>
(0) : __assert_fail ("(!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) && \"LDtocL used on symbol that could be accessed directly is \" \"invalid. Must match ADDIStocHA8.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 852, __PRETTY_FUNCTION__)); } } while (false)
851 "LDtocL used on symbol that could be accessed directly is "do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asmprinter")) { (((!MO.isGlobal() || Subtarget->isGVIndirectSymbol
(MO.getGlobal())) && "LDtocL used on symbol that could be accessed directly is "
"invalid. Must match ADDIStocHA8.") ? static_cast<void>
(0) : __assert_fail ("(!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) && \"LDtocL used on symbol that could be accessed directly is \" \"invalid. Must match ADDIStocHA8.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 852, __PRETTY_FUNCTION__)); } } while (false)
852 "invalid. Must match ADDIStocHA8."))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asmprinter")) { (((!MO.isGlobal() || Subtarget->isGVIndirectSymbol
(MO.getGlobal())) && "LDtocL used on symbol that could be accessed directly is "
"invalid. Must match ADDIStocHA8.") ? static_cast<void>
(0) : __assert_fail ("(!MO.isGlobal() || Subtarget->isGVIndirectSymbol(MO.getGlobal())) && \"LDtocL used on symbol that could be accessed directly is \" \"invalid. Must match ADDIStocHA8.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 852, __PRETTY_FUNCTION__)); } } while (false)
;
853
854 const MCSymbol *MOSymbol = getMCSymbolForTOCPseudoMO(MO);
855
856 if (!MO.isCPI() || TM.getCodeModel() == CodeModel::Large)
857 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
858
859 const MCSymbolRefExpr::VariantKind VK =
860 IsAIX ? MCSymbolRefExpr::VK_PPC_L : MCSymbolRefExpr::VK_PPC_TOC_LO;
861 const MCExpr *Exp =
862 MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
863 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
864 EmitToStreamer(*OutStreamer, TmpInst);
865 return;
866 }
867 case PPC::ADDItocL: {
868 // Transform %xd = ADDItocL %xs, @sym
869 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
870
871 // Change the opcode to ADDI8. If the global address is external, then
872 // generate a TOC entry and reference that. Otherwise, reference the
873 // symbol directly.
874 TmpInst.setOpcode(PPC::ADDI8);
875
876 const MachineOperand &MO = MI->getOperand(2);
877 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL.")(((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL."
) ? static_cast<void> (0) : __assert_fail ("(MO.isGlobal() || MO.isCPI()) && \"Invalid operand for ADDItocL.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 877, __PRETTY_FUNCTION__))
;
878
879 LLVM_DEBUG(assert(do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asmprinter")) { ((!(MO.isGlobal() && Subtarget->
isGVIndirectSymbol(MO.getGlobal())) && "Interposable definitions must use indirect access."
) ? static_cast<void> (0) : __assert_fail ("!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) && \"Interposable definitions must use indirect access.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 881, __PRETTY_FUNCTION__)); } } while (false)
880 !(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) &&do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asmprinter")) { ((!(MO.isGlobal() && Subtarget->
isGVIndirectSymbol(MO.getGlobal())) && "Interposable definitions must use indirect access."
) ? static_cast<void> (0) : __assert_fail ("!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) && \"Interposable definitions must use indirect access.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 881, __PRETTY_FUNCTION__)); } } while (false)
881 "Interposable definitions must use indirect access."))do { if (::llvm::DebugFlag && ::llvm::isCurrentDebugType
("asmprinter")) { ((!(MO.isGlobal() && Subtarget->
isGVIndirectSymbol(MO.getGlobal())) && "Interposable definitions must use indirect access."
) ? static_cast<void> (0) : __assert_fail ("!(MO.isGlobal() && Subtarget->isGVIndirectSymbol(MO.getGlobal())) && \"Interposable definitions must use indirect access.\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 881, __PRETTY_FUNCTION__)); } } while (false)
;
882
883 const MCExpr *Exp =
884 MCSymbolRefExpr::create(getMCSymbolForTOCPseudoMO(MO),
885 MCSymbolRefExpr::VK_PPC_TOC_LO, OutContext);
886 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
887 EmitToStreamer(*OutStreamer, TmpInst);
888 return;
889 }
890 case PPC::ADDISgotTprelHA: {
891 // Transform: %xd = ADDISgotTprelHA %x2, @sym
892 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
893 assert(IsPPC64 && "Not supported for 32-bit PowerPC")((IsPPC64 && "Not supported for 32-bit PowerPC") ? static_cast
<void> (0) : __assert_fail ("IsPPC64 && \"Not supported for 32-bit PowerPC\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 893, __PRETTY_FUNCTION__))
;
894 const MachineOperand &MO = MI->getOperand(2);
895 const GlobalValue *GValue = MO.getGlobal();
896 MCSymbol *MOSymbol = getSymbol(GValue);
897 const MCExpr *SymGotTprel =
898 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
899 OutContext);
900 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
901 .addReg(MI->getOperand(0).getReg())
902 .addReg(MI->getOperand(1).getReg())
903 .addExpr(SymGotTprel));
904 return;
905 }
906 case PPC::LDgotTprelL:
907 case PPC::LDgotTprelL32: {
908 // Transform %xd = LDgotTprelL @sym, %xs
909 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
910
911 // Change the opcode to LD.
912 TmpInst.setOpcode(IsPPC64 ? PPC::LD : PPC::LWZ);
913 const MachineOperand &MO = MI->getOperand(1);
914 const GlobalValue *GValue = MO.getGlobal();
915 MCSymbol *MOSymbol = getSymbol(GValue);
916 const MCExpr *Exp = MCSymbolRefExpr::create(
917 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO
918 : MCSymbolRefExpr::VK_PPC_GOT_TPREL,
919 OutContext);
920 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
921 EmitToStreamer(*OutStreamer, TmpInst);
922 return;
923 }
924
925 case PPC::PPC32PICGOT: {
926 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
927 MCSymbol *GOTRef = OutContext.createTempSymbol();
928 MCSymbol *NextInstr = OutContext.createTempSymbol();
929
930 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
931 // FIXME: We would like an efficient form for this, so we don't have to do
932 // a lot of extra uniquing.
933 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
934 const MCExpr *OffsExpr =
935 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
936 MCSymbolRefExpr::create(GOTRef, OutContext),
937 OutContext);
938 OutStreamer->emitLabel(GOTRef);
939 OutStreamer->emitValue(OffsExpr, 4);
940 OutStreamer->emitLabel(NextInstr);
941 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
942 .addReg(MI->getOperand(0).getReg()));
943 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
944 .addReg(MI->getOperand(1).getReg())
945 .addImm(0)
946 .addReg(MI->getOperand(0).getReg()));
947 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
948 .addReg(MI->getOperand(0).getReg())
949 .addReg(MI->getOperand(1).getReg())
950 .addReg(MI->getOperand(0).getReg()));
951 return;
952 }
953 case PPC::PPC32GOT: {
954 MCSymbol *GOTSymbol =
955 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
956 const MCExpr *SymGotTlsL = MCSymbolRefExpr::create(
957 GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext);
958 const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create(
959 GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext);
960 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
961 .addReg(MI->getOperand(0).getReg())
962 .addExpr(SymGotTlsL));
963 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
964 .addReg(MI->getOperand(0).getReg())
965 .addReg(MI->getOperand(0).getReg())
966 .addExpr(SymGotTlsHA));
967 return;
968 }
969 case PPC::ADDIStlsgdHA: {
970 // Transform: %xd = ADDIStlsgdHA %x2, @sym
971 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
972 assert(IsPPC64 && "Not supported for 32-bit PowerPC")((IsPPC64 && "Not supported for 32-bit PowerPC") ? static_cast
<void> (0) : __assert_fail ("IsPPC64 && \"Not supported for 32-bit PowerPC\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 972, __PRETTY_FUNCTION__))
;
973 const MachineOperand &MO = MI->getOperand(2);
974 const GlobalValue *GValue = MO.getGlobal();
975 MCSymbol *MOSymbol = getSymbol(GValue);
976 const MCExpr *SymGotTlsGD =
977 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
978 OutContext);
979 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
980 .addReg(MI->getOperand(0).getReg())
981 .addReg(MI->getOperand(1).getReg())
982 .addExpr(SymGotTlsGD));
983 return;
984 }
985 case PPC::ADDItlsgdL:
986 // Transform: %xd = ADDItlsgdL %xs, @sym
987 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
988 case PPC::ADDItlsgdL32: {
989 // Transform: %rd = ADDItlsgdL32 %rs, @sym
990 // Into: %rd = ADDI %rs, sym@got@tlsgd
991 const MachineOperand &MO = MI->getOperand(2);
992 const GlobalValue *GValue = MO.getGlobal();
993 MCSymbol *MOSymbol = getSymbol(GValue);
994 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create(
995 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
996 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
997 OutContext);
998 EmitToStreamer(*OutStreamer,
999 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1000 .addReg(MI->getOperand(0).getReg())
1001 .addReg(MI->getOperand(1).getReg())
1002 .addExpr(SymGotTlsGD));
1003 return;
1004 }
1005 case PPC::GETtlsADDR:
1006 // Transform: %x3 = GETtlsADDR %x3, @sym
1007 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
1008 case PPC::GETtlsADDR32: {
1009 // Transform: %r3 = GETtlsADDR32 %r3, @sym
1010 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
1011 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
1012 return;
1013 }
1014 case PPC::ADDIStlsldHA: {
1015 // Transform: %xd = ADDIStlsldHA %x2, @sym
1016 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
1017 assert(IsPPC64 && "Not supported for 32-bit PowerPC")((IsPPC64 && "Not supported for 32-bit PowerPC") ? static_cast
<void> (0) : __assert_fail ("IsPPC64 && \"Not supported for 32-bit PowerPC\""
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 1017, __PRETTY_FUNCTION__))
;
1018 const MachineOperand &MO = MI->getOperand(2);
1019 const GlobalValue *GValue = MO.getGlobal();
1020 MCSymbol *MOSymbol = getSymbol(GValue);
1021 const MCExpr *SymGotTlsLD =
1022 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
1023 OutContext);
1024 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
1025 .addReg(MI->getOperand(0).getReg())
1026 .addReg(MI->getOperand(1).getReg())
1027 .addExpr(SymGotTlsLD));
1028 return;
1029 }
1030 case PPC::ADDItlsldL:
1031 // Transform: %xd = ADDItlsldL %xs, @sym
1032 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
1033 case PPC::ADDItlsldL32: {
1034 // Transform: %rd = ADDItlsldL32 %rs, @sym
1035 // Into: %rd = ADDI %rs, sym@got@tlsld
1036 const MachineOperand &MO = MI->getOperand(2);
1037 const GlobalValue *GValue = MO.getGlobal();
1038 MCSymbol *MOSymbol = getSymbol(GValue);
1039 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create(
1040 MOSymbol, IsPPC64 ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
1041 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
1042 OutContext);
1043 EmitToStreamer(*OutStreamer,
1044 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1045 .addReg(MI->getOperand(0).getReg())
1046 .addReg(MI->getOperand(1).getReg())
1047 .addExpr(SymGotTlsLD));
1048 return;
1049 }
1050 case PPC::GETtlsldADDR:
1051 // Transform: %x3 = GETtlsldADDR %x3, @sym
1052 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
1053 case PPC::GETtlsldADDR32: {
1054 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
1055 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
1056 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
1057 return;
1058 }
1059 case PPC::ADDISdtprelHA:
1060 // Transform: %xd = ADDISdtprelHA %xs, @sym
1061 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
1062 case PPC::ADDISdtprelHA32: {
1063 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
1064 // Into: %rd = ADDIS %rs, sym@dtprel@ha
1065 const MachineOperand &MO = MI->getOperand(2);
1066 const GlobalValue *GValue = MO.getGlobal();
1067 MCSymbol *MOSymbol = getSymbol(GValue);
1068 const MCExpr *SymDtprel =
1069 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
1070 OutContext);
1071 EmitToStreamer(
1072 *OutStreamer,
1073 MCInstBuilder(IsPPC64 ? PPC::ADDIS8 : PPC::ADDIS)
1074 .addReg(MI->getOperand(0).getReg())
1075 .addReg(MI->getOperand(1).getReg())
1076 .addExpr(SymDtprel));
1077 return;
1078 }
1079 case PPC::ADDIdtprelL:
1080 // Transform: %xd = ADDIdtprelL %xs, @sym
1081 // Into: %xd = ADDI8 %xs, sym@dtprel@l
1082 case PPC::ADDIdtprelL32: {
1083 // Transform: %rd = ADDIdtprelL32 %rs, @sym
1084 // Into: %rd = ADDI %rs, sym@dtprel@l
1085 const MachineOperand &MO = MI->getOperand(2);
1086 const GlobalValue *GValue = MO.getGlobal();
1087 MCSymbol *MOSymbol = getSymbol(GValue);
1088 const MCExpr *SymDtprel =
1089 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
1090 OutContext);
1091 EmitToStreamer(*OutStreamer,
1092 MCInstBuilder(IsPPC64 ? PPC::ADDI8 : PPC::ADDI)
1093 .addReg(MI->getOperand(0).getReg())
1094 .addReg(MI->getOperand(1).getReg())
1095 .addExpr(SymDtprel));
1096 return;
1097 }
1098 case PPC::MFOCRF:
1099 case PPC::MFOCRF8:
1100 if (!Subtarget->hasMFOCRF()) {
1101 // Transform: %r3 = MFOCRF %cr7
1102 // Into: %r3 = MFCR ;; cr7
1103 unsigned NewOpcode =
1104 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
1105 OutStreamer->AddComment(PPCInstPrinter::
1106 getRegisterName(MI->getOperand(1).getReg()));
1107 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1108 .addReg(MI->getOperand(0).getReg()));
1109 return;
1110 }
1111 break;
1112 case PPC::MTOCRF:
1113 case PPC::MTOCRF8:
1114 if (!Subtarget->hasMFOCRF()) {
1115 // Transform: %cr7 = MTOCRF %r3
1116 // Into: MTCRF mask, %r3 ;; cr7
1117 unsigned NewOpcode =
1118 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1119 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1120 ->getEncodingValue(MI->getOperand(0).getReg());
1121 OutStreamer->AddComment(PPCInstPrinter::
1122 getRegisterName(MI->getOperand(0).getReg()));
1123 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1124 .addImm(Mask)
1125 .addReg(MI->getOperand(1).getReg()));
1126 return;
1127 }
1128 break;
1129 case PPC::LD:
1130 case PPC::STD:
1131 case PPC::LWA_32:
1132 case PPC::LWA: {
1133 // Verify alignment is legal, so we don't create relocations
1134 // that can't be supported.
1135 // FIXME: This test is currently disabled for Darwin. The test
1136 // suite shows a handful of test cases that fail this check for
1137 // Darwin. Those need to be investigated before this sanity test
1138 // can be enabled for those subtargets.
1139 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1140 const MachineOperand &MO = MI->getOperand(OpNum);
1141 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
1142 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!")::llvm::llvm_unreachable_internal("Global must be word-aligned for LD, STD, LWA!"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 1142)
;
1143 // Now process the instruction normally.
1144 break;
1145 }
1146 }
1147
1148 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this);
1149 EmitToStreamer(*OutStreamer, TmpInst);
1150}
1151
1152void PPCLinuxAsmPrinter::emitInstruction(const MachineInstr *MI) {
1153 if (!Subtarget->isPPC64())
1154 return PPCAsmPrinter::emitInstruction(MI);
1155
1156 switch (MI->getOpcode()) {
1157 default:
1158 return PPCAsmPrinter::emitInstruction(MI);
1159 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1160 // .begin:
1161 // b .end # lis 0, FuncId[16..32]
1162 // nop # li 0, FuncId[0..15]
1163 // std 0, -8(1)
1164 // mflr 0
1165 // bl __xray_FunctionEntry
1166 // mtlr 0
1167 // .end:
1168 //
1169 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1170 // of instructions change.
1171 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1172 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1173 OutStreamer->emitLabel(BeginOfSled);
1174 EmitToStreamer(*OutStreamer,
1175 MCInstBuilder(PPC::B).addExpr(
1176 MCSymbolRefExpr::create(EndOfSled, OutContext)));
1177 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1178 EmitToStreamer(
1179 *OutStreamer,
1180 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1181 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1182 EmitToStreamer(*OutStreamer,
1183 MCInstBuilder(PPC::BL8_NOP)
1184 .addExpr(MCSymbolRefExpr::create(
1185 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
1186 OutContext)));
1187 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1188 OutStreamer->emitLabel(EndOfSled);
1189 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
1190 break;
1191 }
1192 case TargetOpcode::PATCHABLE_RET: {
1193 unsigned RetOpcode = MI->getOperand(0).getImm();
1194 MCInst RetInst;
1195 RetInst.setOpcode(RetOpcode);
1196 for (const auto &MO :
1197 make_range(std::next(MI->operands_begin()), MI->operands_end())) {
1198 MCOperand MCOp;
1199 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this))
1200 RetInst.addOperand(MCOp);
1201 }
1202
1203 bool IsConditional;
1204 if (RetOpcode == PPC::BCCLR) {
1205 IsConditional = true;
1206 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1207 RetOpcode == PPC::TCRETURNai8) {
1208 break;
1209 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1210 IsConditional = false;
1211 } else {
1212 EmitToStreamer(*OutStreamer, RetInst);
1213 break;
1214 }
1215
1216 MCSymbol *FallthroughLabel;
1217 if (IsConditional) {
1218 // Before:
1219 // bgtlr cr0
1220 //
1221 // After:
1222 // ble cr0, .end
1223 // .p2align 3
1224 // .begin:
1225 // blr # lis 0, FuncId[16..32]
1226 // nop # li 0, FuncId[0..15]
1227 // std 0, -8(1)
1228 // mflr 0
1229 // bl __xray_FunctionExit
1230 // mtlr 0
1231 // blr
1232 // .end:
1233 //
1234 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1235 // of instructions change.
1236 FallthroughLabel = OutContext.createTempSymbol();
1237 EmitToStreamer(
1238 *OutStreamer,
1239 MCInstBuilder(PPC::BCC)
1240 .addImm(PPC::InvertPredicate(
1241 static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
1242 .addReg(MI->getOperand(2).getReg())
1243 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
1244 RetInst = MCInst();
1245 RetInst.setOpcode(PPC::BLR8);
1246 }
1247 // .p2align 3
1248 // .begin:
1249 // b(lr)? # lis 0, FuncId[16..32]
1250 // nop # li 0, FuncId[0..15]
1251 // std 0, -8(1)
1252 // mflr 0
1253 // bl __xray_FunctionExit
1254 // mtlr 0
1255 // b(lr)?
1256 //
1257 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1258 // of instructions change.
1259 OutStreamer->emitCodeAlignment(8);
1260 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1261 OutStreamer->emitLabel(BeginOfSled);
1262 EmitToStreamer(*OutStreamer, RetInst);
1263 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1264 EmitToStreamer(
1265 *OutStreamer,
1266 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1267 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1268 EmitToStreamer(*OutStreamer,
1269 MCInstBuilder(PPC::BL8_NOP)
1270 .addExpr(MCSymbolRefExpr::create(
1271 OutContext.getOrCreateSymbol("__xray_FunctionExit"),
1272 OutContext)));
1273 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1274 EmitToStreamer(*OutStreamer, RetInst);
1275 if (IsConditional)
1276 OutStreamer->emitLabel(FallthroughLabel);
1277 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
1278 break;
1279 }
1280 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1281 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted")::llvm::llvm_unreachable_internal("PATCHABLE_FUNCTION_EXIT should never be emitted"
, "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 1281)
;
1282 case TargetOpcode::PATCHABLE_TAIL_CALL:
1283 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1284 // normal function exit from a tail exit.
1285 llvm_unreachable("Tail call is handled in the normal case. See comments "::llvm::llvm_unreachable_internal("Tail call is handled in the normal case. See comments "
"around this assert.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 1286)
1286 "around this assert.")::llvm::llvm_unreachable_internal("Tail call is handled in the normal case. See comments "
"around this assert.", "/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/lib/Target/PowerPC/PPCAsmPrinter.cpp"
, 1286)
;
1287 }
1288}
1289
1290void PPCLinuxAsmPrinter::emitStartOfAsmFile(Module &M) {
1291 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
1292 PPCTargetStreamer *TS =
1293 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1294
1295 if (TS)
1296 TS->emitAbiVersion(2);
1297 }
1298
1299 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
1300 !isPositionIndependent())
1301 return AsmPrinter::emitStartOfAsmFile(M);
1302
1303 if (M.getPICLevel() == PICLevel::SmallPIC)
1304 return AsmPrinter::emitStartOfAsmFile(M);
1305
1306 OutStreamer->SwitchSection(OutContext.getELFSection(
1307 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC));
1308
1309 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1310 MCSymbol *CurrentPos = OutContext.createTempSymbol();
1311
1312 OutStreamer->emitLabel(CurrentPos);
1313
1314 // The GOT pointer points to the middle of the GOT, in order to reference the
1315 // entire 64kB range. 0x8000 is the midpoint.
1316 const MCExpr *tocExpr =
1317 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1318 MCConstantExpr::create(0x8000, OutContext),
1319 OutContext);
1320
1321 OutStreamer->emitAssignment(TOCSym, tocExpr);
1322
1323 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
1324}
1325
1326void PPCLinuxAsmPrinter::emitFunctionEntryLabel() {
1327 // linux/ppc32 - Normal entry label.
1328 if (!Subtarget->isPPC64() &&
1329 (!isPositionIndependent() ||
1330 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
1331 return AsmPrinter::emitFunctionEntryLabel();
1332
1333 if (!Subtarget->isPPC64()) {
1334 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1335 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
1336 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
1337 MCSymbol *PICBase = MF->getPICBaseSymbol();
1338 OutStreamer->emitLabel(RelocSymbol);
1339
1340 const MCExpr *OffsExpr =
1341 MCBinaryExpr::createSub(
1342 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
1343 OutContext),
1344 MCSymbolRefExpr::create(PICBase, OutContext),
1345 OutContext);
1346 OutStreamer->emitValue(OffsExpr, 4);
1347 OutStreamer->emitLabel(CurrentFnSym);
1348 return;
1349 } else
1350 return AsmPrinter::emitFunctionEntryLabel();
1351 }
1352
1353 // ELFv2 ABI - Normal entry label.
1354 if (Subtarget->isELFv2ABI()) {
1355 // In the Large code model, we allow arbitrary displacements between
1356 // the text section and its associated TOC section. We place the
1357 // full 8-byte offset to the TOC in memory immediately preceding
1358 // the function global entry point.
1359 if (TM.getCodeModel() == CodeModel::Large
1360 && !MF->getRegInfo().use_empty(PPC::X2)) {
1361 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1362
1363 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1364 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol();
1365 const MCExpr *TOCDeltaExpr =
1366 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1367 MCSymbolRefExpr::create(GlobalEPSymbol,
1368 OutContext),
1369 OutContext);
1370
1371 OutStreamer->emitLabel(PPCFI->getTOCOffsetSymbol());
1372 OutStreamer->emitValue(TOCDeltaExpr, 8);
1373 }
1374 return AsmPrinter::emitFunctionEntryLabel();
1375 }
1376
1377 // Emit an official procedure descriptor.
1378 MCSectionSubPair Current = OutStreamer->getCurrentSection();
1379 MCSectionELF *Section = OutStreamer->getContext().getELFSection(
1380 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1381 OutStreamer->SwitchSection(Section);
1382 OutStreamer->emitLabel(CurrentFnSym);
1383 OutStreamer->emitValueToAlignment(8);
1384 MCSymbol *Symbol1 = CurrentFnSymForSize;
1385 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1386 // entry point.
1387 OutStreamer->emitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
1388 8 /*size*/);
1389 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1390 // Generates a R_PPC64_TOC relocation for TOC base insertion.
1391 OutStreamer->emitValue(
1392 MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
1393 8/*size*/);
1394 // Emit a null environment pointer.
1395 OutStreamer->emitIntValue(0, 8 /* size */);
1396 OutStreamer->SwitchSection(Current.first, Current.second);
1397}
1398
1399void PPCLinuxAsmPrinter::emitEndOfAsmFile(Module &M) {
1400 const DataLayout &DL = getDataLayout();
1401
1402 bool isPPC64 = DL.getPointerSizeInBits() == 64;
1403
1404 PPCTargetStreamer &TS =
1405 static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
1406
1407 if (!TOC.empty()) {
1408 const char *Name = isPPC64 ? ".toc" : ".got2";
1409 MCSectionELF *Section = OutContext.getELFSection(
1410 Name, ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1411 OutStreamer->SwitchSection(Section);
1412 if (!isPPC64)
1413 OutStreamer->emitValueToAlignment(4);
1414
1415 for (const auto &TOCMapPair : TOC) {
1416 const MCSymbol *const TOCEntryTarget = TOCMapPair.first;
1417 MCSymbol *const TOCEntryLabel = TOCMapPair.second;
1418
1419 OutStreamer->emitLabel(TOCEntryLabel);
1420 if (isPPC64)
1421 TS.emitTCEntry(*TOCEntryTarget);
1422 else
1423 OutStreamer->emitSymbolValue(TOCEntryTarget, 4);
1424 }
1425 }
1426
1427 PPCAsmPrinter::emitEndOfAsmFile(M);
1428}
1429
1430/// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
1431void PPCLinuxAsmPrinter::emitFunctionBodyStart() {
1432 // In the ELFv2 ABI, in functions that use the TOC register, we need to
1433 // provide two entry points. The ABI guarantees that when calling the
1434 // local entry point, r2 is set up by the caller to contain the TOC base
1435 // for this function, and when calling the global entry point, r12 is set
1436 // up by the caller to hold the address of the global entry point. We
1437 // thus emit a prefix sequence along the following lines:
1438 //
1439 // func:
1440 // .Lfunc_gepNN:
1441 // # global entry point
1442 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1443 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
1444 // .Lfunc_lepNN:
1445 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1446 // # local entry point, followed by function body
1447 //
1448 // For the Large code model, we create
1449 //
1450 // .Lfunc_tocNN:
1451 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
1452 // func:
1453 // .Lfunc_gepNN:
1454 // # global entry point
1455 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1456 // add r2,r2,r12
1457 // .Lfunc_lepNN:
1458 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1459 // # local entry point, followed by function body
1460 //
1461 // This ensures we have r2 set up correctly while executing the function
1462 // body, no matter which entry point is called.
1463 if (Subtarget->isELFv2ABI()
1464 // Only do all that if the function uses r2 in the first place.
1465 && !MF->getRegInfo().use_empty(PPC::X2)) {
1466 // Note: The logic here must be synchronized with the code in the
1467 // branch-selection pass which sets the offset of the first block in the
1468 // function. This matters because it affects the alignment.
1469 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1470
1471 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol();
1472 OutStreamer->emitLabel(GlobalEntryLabel);
1473 const MCSymbolRefExpr *GlobalEntryLabelExp =
1474 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
1475
1476 if (TM.getCodeModel() != CodeModel::Large) {
1477 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1478 const MCExpr *TOCDeltaExpr =
1479 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1480 GlobalEntryLabelExp, OutContext);
1481
1482 const MCExpr *TOCDeltaHi = PPCMCExpr::createHa(TOCDeltaExpr, OutContext);
1483 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1484 .addReg(PPC::X2)
1485 .addReg(PPC::X12)
1486 .addExpr(TOCDeltaHi));
1487
1488 const MCExpr *TOCDeltaLo = PPCMCExpr::createLo(TOCDeltaExpr, OutContext);
1489 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
1490 .addReg(PPC::X2)
1491 .addReg(PPC::X2)
1492 .addExpr(TOCDeltaLo));
1493 } else {
1494 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol();
1495 const MCExpr *TOCOffsetDeltaExpr =
1496 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
1497 GlobalEntryLabelExp, OutContext);
1498
1499 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
1500 .addReg(PPC::X2)
1501 .addExpr(TOCOffsetDeltaExpr)
1502 .addReg(PPC::X12));
1503 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
1504 .addReg(PPC::X2)
1505 .addReg(PPC::X2)
1506 .addReg(PPC::X12));
1507 }
1508
1509 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol();
1510 OutStreamer->emitLabel(LocalEntryLabel);
1511 const MCSymbolRefExpr *LocalEntryLabelExp =
1512 MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
1513 const MCExpr *LocalOffsetExp =
1514 MCBinaryExpr::createSub(LocalEntryLabelExp,
1515 GlobalEntryLabelExp, OutContext);
1516
1517 PPCTargetStreamer *TS =
1518 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
1519
1520 if (TS)
1521 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
1522 }
1523}
1524
1525/// EmitFunctionBodyEnd - Print the traceback table before the .size
1526/// directive.
1527///
1528void PPCLinuxAsmPrinter::emitFunctionBodyEnd() {
1529 // Only the 64-bit target requires a traceback table. For now,
1530 // we only emit the word of zeroes that GDB requires to find
1531 // the end of the function, and zeroes for the eight-byte
1532 // mandatory fields.
1533 // FIXME: We should fill in the eight-byte mandatory fields as described in
1534 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1535 // currently make use of these fields).
1536 if (Subtarget->isPPC64()) {
1537 OutStreamer->emitIntValue(0, 4/*size*/);
1538 OutStreamer->emitIntValue(0, 8/*size*/);
1539 }
1540}
1541
1542void PPCAIXAsmPrinter::SetupMachineFunction(MachineFunction &MF) {
1543 // Get the function descriptor symbol.
1544 CurrentFnDescSym = getSymbol(&MF.getFunction());
1545 // Set the alignment and the containing csect.
1546 MCSectionXCOFF *FnDescSec = cast<MCSectionXCOFF>(
1547 getObjFileLowering().getSectionForFunctionDescriptor(CurrentFnDescSym));
1548 FnDescSec->setAlignment(Align(Subtarget->isPPC64() ? 8 : 4));
1549 cast<MCSymbolXCOFF>(CurrentFnDescSym)->setContainingCsect(FnDescSec);
1550
1551 return AsmPrinter::SetupMachineFunction(MF);
1552}
1553
1554void PPCAIXAsmPrinter::ValidateGV(const GlobalVariable *GV) {
1555 // Early error checking limiting what is supported.
1556 if (GV->isThreadLocal())
1557 report_fatal_error("Thread local not yet supported on AIX.");
1558
1559 if (GV->hasSection())
1560 report_fatal_error("Custom section for Data not yet supported.");
1561
1562 if (GV->hasComdat())
1563 report_fatal_error("COMDAT not yet supported by AIX.");
1564}
1565
1566const MCExpr *PPCAIXAsmPrinter::lowerConstant(const Constant *CV) {
1567 if (const Function *F = dyn_cast<Function>(CV)) {
1568 MCSymbolXCOFF *FSym = cast<MCSymbolXCOFF>(getSymbol(F));
1569 if (!FSym->hasContainingCsect()) {
1570 MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
1571 F->isDeclaration()
1572 ? getObjFileLowering().getSectionForExternalReference(F, TM)
1573 : getObjFileLowering().getSectionForFunctionDescriptor(FSym));
1574 FSym->setContainingCsect(Csect);
1575 }
1576 return MCSymbolRefExpr::create(
1577 FSym->getContainingCsect()->getQualNameSymbol(), OutContext);
1578 }
1579 return PPCAsmPrinter::lowerConstant(CV);
1580}
1581
1582static bool isSpecialLLVMGlobalArrayForStaticInit(const GlobalVariable *GV) {
1583 return StringSwitch<bool>(GV->getName())
1584 .Cases("llvm.global_ctors", "llvm.global_dtors", true)
1585 .Default(false);
1586}
1587
1588void PPCAIXAsmPrinter::emitGlobalVariable(const GlobalVariable *GV) {
1589 ValidateGV(GV);
1590
1591 // TODO: Update the handling of global arrays for static init when we support
1592 // the ".ref" directive.
1593 // Otherwise, we can skip these arrays, because the AIX linker collects
1594 // static init functions simply based on their name.
1595 if (isSpecialLLVMGlobalArrayForStaticInit(GV))
1
Taking false branch
1596 return;
1597
1598 // Create the symbol, set its storage class.
1599 MCSymbolXCOFF *GVSym = cast<MCSymbolXCOFF>(getSymbol(GV));
2
The object is a 'MCSymbolXCOFF'
1600 GVSym->setStorageClass(
1601 TargetLoweringObjectFileXCOFF::getStorageClassForGlobal(GV));
1602
1603 SectionKind GVKind;
1604
1605 // Create the containing csect and set it. We set it for externals as well,
1606 // since this may not have been set elsewhere depending on how they are used.
1607 MCSectionXCOFF *Csect = cast<MCSectionXCOFF>(
5
The object is a 'MCSectionXCOFF'
1608 GV->isDeclaration()
3
Assuming the condition is true
4
'?' condition is true
1609 ? getObjFileLowering().getSectionForExternalReference(GV, TM)
1610 : getObjFileLowering().SectionForGlobal(
1611 GV, GVKind = getObjFileLowering().getKindForGlobal(GV, TM),
1612 TM));
1613 GVSym->setContainingCsect(Csect);
1614
1615 // External global variables are already handled.
1616 if (GV->isDeclaration())
6
Assuming the condition is false
7
Taking false branch
1617 return;
1618
1619 if (!GVKind.isGlobalWriteableData() && !GVKind.isReadOnly())
8
Calling 'SectionKind::isGlobalWriteableData'
1620 report_fatal_error("Encountered a global variable kind that is "
1621 "not supported yet.");
1622
1623 // Switch to the containing csect.
1624 OutStreamer->SwitchSection(Csect);
1625
1626 const DataLayout &DL = GV->getParent()->getDataLayout();
1627
1628 // Handle common symbols.
1629 if (GVKind.isCommon() || GVKind.isBSSLocal()) {
1630 unsigned Align =
1631 GV->getAlignment() ? GV->getAlignment() : DL.getPreferredAlignment(GV);
1632 uint64_t Size = DL.getTypeAllocSize(GV->getType()->getElementType());
1633
1634 if (GVKind.isBSSLocal())
1635 OutStreamer->emitXCOFFLocalCommonSymbol(
1636 GVSym, Size, Csect->getQualNameSymbol(), Align);
1637 else
1638 OutStreamer->emitCommonSymbol(Csect->getQualNameSymbol(), Size, Align);
1639 return;
1640 }
1641
1642 MCSymbol *EmittedInitSym = GVSym;
1643 emitLinkage(GV, EmittedInitSym);
1644 emitAlignment(getGVAlignment(GV, DL), GV);
1645 OutStreamer->emitLabel(EmittedInitSym);
1646 emitGlobalConstant(GV->getParent()->getDataLayout(), GV->getInitializer());
1647}
1648
1649void PPCAIXAsmPrinter::emitFunctionDescriptor() {
1650 const DataLayout &DL = getDataLayout();
1651 const unsigned PointerSize = DL.getPointerSizeInBits() == 64 ? 8 : 4;
1652
1653 MCSectionSubPair Current = OutStreamer->getCurrentSection();
1654 // Emit function descriptor.
1655 OutStreamer->SwitchSection(
1656 cast<MCSymbolXCOFF>(CurrentFnDescSym)->getContainingCsect());
1657 OutStreamer->emitLabel(CurrentFnDescSym);
1658 // Emit function entry point address.
1659 OutStreamer->emitValue(MCSymbolRefExpr::create(CurrentFnSym, OutContext),
1660 PointerSize);
1661 // Emit TOC base address.
1662 const MCSymbol *TOCBaseSym =
1663 cast<MCSectionXCOFF>(getObjFileLowering().getTOCBaseSection())
1664 ->getQualNameSymbol();
1665 OutStreamer->emitValue(MCSymbolRefExpr::create(TOCBaseSym, OutContext),
1666 PointerSize);
1667 // Emit a null environment pointer.
1668 OutStreamer->emitIntValue(0, PointerSize);
1669
1670 OutStreamer->SwitchSection(Current.first, Current.second);
1671}
1672
1673void PPCAIXAsmPrinter::emitEndOfAsmFile(Module &M) {
1674 // If there are no functions in this module, we will never need to reference
1675 // the TOC base.
1676 if (M.empty())
1677 return;
1678
1679 // Switch to section to emit TOC base.
1680 OutStreamer->SwitchSection(getObjFileLowering().getTOCBaseSection());
1681
1682 PPCTargetStreamer &TS =
1683 static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
1684
1685 const unsigned EntryByteSize = Subtarget->isPPC64() ? 8 : 4;
1686 const unsigned TOCEntriesByteSize = TOC.size() * EntryByteSize;
1687 // TODO: If TOC entries' size is larger than 32768, then we run out of
1688 // positive displacement to reach the TOC entry. We need to decide how to
1689 // handle entries' size larger than that later.
1690 if (TOCEntriesByteSize > 32767) {
1691 report_fatal_error("Handling of TOC entry displacement larger than 32767 "
1692 "is not yet implemented.");
1693 }
1694
1695 for (auto &I : TOC) {
1696 // Setup the csect for the current TC entry.
1697 MCSectionXCOFF *TCEntry = cast<MCSectionXCOFF>(
1698 getObjFileLowering().getSectionForTOCEntry(I.first));
1699 cast<MCSymbolXCOFF>(I.second)->setContainingCsect(TCEntry);
1700 OutStreamer->SwitchSection(TCEntry);
1701
1702 OutStreamer->emitLabel(I.second);
1703 TS.emitTCEntry(*I.first);
1704 }
1705}
1706
1707MCSymbol *
1708PPCAIXAsmPrinter::getMCSymbolForTOCPseudoMO(const MachineOperand &MO) {
1709 const GlobalObject *GO = nullptr;
1710
1711 // If the MO is a function or certain kind of globals, we want to make sure to
1712 // refer to the csect symbol, otherwise we can just do the default handling.
1713 if (MO.getType() != MachineOperand::MO_GlobalAddress ||
1714 !(GO = dyn_cast<const GlobalObject>(MO.getGlobal())))
1715 return PPCAsmPrinter::getMCSymbolForTOCPseudoMO(MO);
1716
1717 // Do an early error check for globals we don't support. This will go away
1718 // eventually.
1719 const auto *GV = dyn_cast<const GlobalVariable>(GO);
1720 if (GV) {
1721 ValidateGV(GV);
1722 }
1723
1724 MCSymbolXCOFF *XSym = cast<MCSymbolXCOFF>(getSymbol(GO));
1725
1726 // If the global object is a global variable without initializer or is a
1727 // declaration of a function, then XSym is an external referenced symbol.
1728 // Hence we may need to explictly create a MCSectionXCOFF for it so that we
1729 // can return its symbol later.
1730 if (GO->isDeclaration()) {
1731 return cast<MCSectionXCOFF>(
1732 getObjFileLowering().getSectionForExternalReference(GO, TM))
1733 ->getQualNameSymbol();
1734 }
1735
1736 // Handle initialized global variables and defined functions.
1737 SectionKind GOKind = getObjFileLowering().getKindForGlobal(GO, TM);
1738
1739 if (GOKind.isText()) {
1740 // If the MO is a function, we want to make sure to refer to the function
1741 // descriptor csect.
1742 return cast<MCSectionXCOFF>(
1743 getObjFileLowering().getSectionForFunctionDescriptor(XSym))
1744 ->getQualNameSymbol();
1745 } else if (GOKind.isCommon() || GOKind.isBSSLocal()) {
1746 // If the operand is a common then we should refer to the csect symbol.
1747 return cast<MCSectionXCOFF>(
1748 getObjFileLowering().SectionForGlobal(GO, GOKind, TM))
1749 ->getQualNameSymbol();
1750 }
1751
1752 // Other global variables are refered to by labels inside of a single csect,
1753 // so refer to the label directly.
1754 return getSymbol(GV);
1755}
1756
1757/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1758/// for a MachineFunction to the given output stream, in a format that the
1759/// Darwin assembler can deal with.
1760///
1761static AsmPrinter *
1762createPPCAsmPrinterPass(TargetMachine &tm,
1763 std::unique_ptr<MCStreamer> &&Streamer) {
1764 if (tm.getTargetTriple().isOSAIX())
1765 return new PPCAIXAsmPrinter(tm, std::move(Streamer));
1766
1767 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
1768}
1769
1770// Force static initialization.
1771extern "C" LLVM_EXTERNAL_VISIBILITY__attribute__ ((visibility("default"))) void LLVMInitializePowerPCAsmPrinter() {
1772 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
1773 createPPCAsmPrinterPass);
1774 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
1775 createPPCAsmPrinterPass);
1776 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
1777 createPPCAsmPrinterPass);
1778}

/build/llvm-toolchain-snapshot-11~++20200309111110+2c36c23f347/llvm/include/llvm/MC/SectionKind.h

1//===-- llvm/MC/SectionKind.h - Classification of sections ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_MC_SECTIONKIND_H
10#define LLVM_MC_SECTIONKIND_H
11
12namespace llvm {
13
14/// SectionKind - This is a simple POD value that classifies the properties of
15/// a section. A section is classified into the deepest possible
16/// classification, and then the target maps them onto their sections based on
17/// what capabilities they have.
18///
19/// The comments below describe these as if they were an inheritance hierarchy
20/// in order to explain the predicates below.
21///
22class SectionKind {
23 enum Kind {
24 /// Metadata - Debug info sections or other metadata.
25 Metadata,
26
27 /// Text - Text section, used for functions and other executable code.
28 Text,
29
30 /// ExecuteOnly, Text section that is not readable.
31 ExecuteOnly,
32
33 /// ReadOnly - Data that is never written to at program runtime by the
34 /// program or the dynamic linker. Things in the top-level readonly
35 /// SectionKind are not mergeable.
36 ReadOnly,
37
38 /// MergableCString - Any null-terminated string which allows merging.
39 /// These values are known to end in a nul value of the specified size,
40 /// not otherwise contain a nul value, and be mergable. This allows the
41 /// linker to unique the strings if it so desires.
42
43 /// Mergeable1ByteCString - 1 byte mergable, null terminated, string.
44 Mergeable1ByteCString,
45
46 /// Mergeable2ByteCString - 2 byte mergable, null terminated, string.
47 Mergeable2ByteCString,
48
49 /// Mergeable4ByteCString - 4 byte mergable, null terminated, string.
50 Mergeable4ByteCString,
51
52 /// MergeableConst - These are sections for merging fixed-length
53 /// constants together. For example, this can be used to unique
54 /// constant pool entries etc.
55
56 /// MergeableConst4 - This is a section used by 4-byte constants,
57 /// for example, floats.
58 MergeableConst4,
59
60 /// MergeableConst8 - This is a section used by 8-byte constants,
61 /// for example, doubles.
62 MergeableConst8,
63
64 /// MergeableConst16 - This is a section used by 16-byte constants,
65 /// for example, vectors.
66 MergeableConst16,
67
68 /// MergeableConst32 - This is a section used by 32-byte constants,
69 /// for example, vectors.
70 MergeableConst32,
71
72 /// Writeable - This is the base of all segments that need to be written
73 /// to during program runtime.
74
75 /// ThreadLocal - This is the base of all TLS segments. All TLS
76 /// objects must be writeable, otherwise there is no reason for them to
77 /// be thread local!
78
79 /// ThreadBSS - Zero-initialized TLS data objects.
80 ThreadBSS,
81
82 /// ThreadData - Initialized TLS data objects.
83 ThreadData,
84
85 /// GlobalWriteableData - Writeable data that is global (not thread
86 /// local).
87
88 /// BSS - Zero initialized writeable data.
89 BSS,
90
91 /// BSSLocal - This is BSS (zero initialized and writable) data
92 /// which has local linkage.
93 BSSLocal,
94
95 /// BSSExtern - This is BSS data with normal external linkage.
96 BSSExtern,
97
98 /// Common - Data with common linkage. These represent tentative
99 /// definitions, which always have a zero initializer and are never
100 /// marked 'constant'.
101 Common,
102
103 /// This is writeable data that has a non-zero initializer.
104 Data,
105
106 /// ReadOnlyWithRel - These are global variables that are never
107 /// written to by the program, but that have relocations, so they
108 /// must be stuck in a writeable section so that the dynamic linker
109 /// can write to them. If it chooses to, the dynamic linker can
110 /// mark the pages these globals end up on as read-only after it is
111 /// done with its relocation phase.
112 ReadOnlyWithRel
113 } K : 8;
114public:
115
116 bool isMetadata() const { return K == Metadata; }
117
118 bool isText() const { return K == Text || K == ExecuteOnly; }
119
120 bool isExecuteOnly() const { return K == ExecuteOnly; }
121
122 bool isReadOnly() const {
123 return K == ReadOnly || isMergeableCString() ||
124 isMergeableConst();
125 }
126
127 bool isMergeableCString() const {
128 return K == Mergeable1ByteCString || K == Mergeable2ByteCString ||
129 K == Mergeable4ByteCString;
130 }
131 bool isMergeable1ByteCString() const { return K == Mergeable1ByteCString; }
132 bool isMergeable2ByteCString() const { return K == Mergeable2ByteCString; }
133 bool isMergeable4ByteCString() const { return K == Mergeable4ByteCString; }
134
135 bool isMergeableConst() const {
136 return K == MergeableConst4 || K == MergeableConst8 ||
137 K == MergeableConst16 || K == MergeableConst32;
138 }
139 bool isMergeableConst4() const { return K == MergeableConst4; }
140 bool isMergeableConst8() const { return K == MergeableConst8; }
141 bool isMergeableConst16() const { return K == MergeableConst16; }
142 bool isMergeableConst32() const { return K == MergeableConst32; }
143
144 bool isWriteable() const {
145 return isThreadLocal() || isGlobalWriteableData();
146 }
147
148 bool isThreadLocal() const {
149 return K == ThreadData || K == ThreadBSS;
150 }
151
152 bool isThreadBSS() const { return K == ThreadBSS; }
153 bool isThreadData() const { return K == ThreadData; }
154
155 bool isGlobalWriteableData() const {
156 return isBSS() || isCommon() || isData() || isReadOnlyWithRel();
9
Calling 'SectionKind::isBSS'
157 }
158
159 bool isBSS() const { return K == BSS || K == BSSLocal || K == BSSExtern; }
10
The left operand of '==' is a garbage value
160 bool isBSSLocal() const { return K == BSSLocal; }
161 bool isBSSExtern() const { return K == BSSExtern; }
162
163 bool isCommon() const { return K == Common; }
164
165 bool isData() const { return K == Data; }
166
167 bool isReadOnlyWithRel() const {
168 return K == ReadOnlyWithRel;
169 }
170private:
171 static SectionKind get(Kind K) {
172 SectionKind Res;
173 Res.K = K;
174 return Res;
175 }
176public:
177
178 static SectionKind getMetadata() { return get(Metadata); }
179 static SectionKind getText() { return get(Text); }
180 static SectionKind getExecuteOnly() { return get(ExecuteOnly); }
181 static SectionKind getReadOnly() { return get(ReadOnly); }
182 static SectionKind getMergeable1ByteCString() {
183 return get(Mergeable1ByteCString);
184 }
185 static SectionKind getMergeable2ByteCString() {
186 return get(Mergeable2ByteCString);
187 }
188 static SectionKind getMergeable4ByteCString() {
189 return get(Mergeable4ByteCString);
190 }
191 static SectionKind getMergeableConst4() { return get(MergeableConst4); }
192 static SectionKind getMergeableConst8() { return get(MergeableConst8); }
193 static SectionKind getMergeableConst16() { return get(MergeableConst16); }
194 static SectionKind getMergeableConst32() { return get(MergeableConst32); }
195 static SectionKind getThreadBSS() { return get(ThreadBSS); }
196 static SectionKind getThreadData() { return get(ThreadData); }
197 static SectionKind getBSS() { return get(BSS); }
198 static SectionKind getBSSLocal() { return get(BSSLocal); }
199 static SectionKind getBSSExtern() { return get(BSSExtern); }
200 static SectionKind getCommon() { return get(Common); }
201 static SectionKind getData() { return get(Data); }
202 static SectionKind getReadOnlyWithRel() { return get(ReadOnlyWithRel); }
203};
204
205} // end namespace llvm
206
207#endif