blob: 04aa3c9b1e22cd2d32cc8d4ac7f4d331bb2d2e15 [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- PPCAsmPrinter.cpp - Print machine instrs to PowerPC assembly ------===//
Misha Brukmanb4402432005-04-21 23:30:14 +00002//
Misha Brukmane05203f2004-06-21 16:55:25 +00003// The LLVM Compiler Infrastructure
4//
Chris Lattnerf3ebc3f2007-12-29 20:36:04 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Misha Brukmanb4402432005-04-21 23:30:14 +00007//
Misha Brukmane05203f2004-06-21 16:55:25 +00008//===----------------------------------------------------------------------===//
9//
Misha Brukmanb604b4d2004-07-08 17:58:04 +000010// This file contains a printer that converts from our internal representation
11// of machine-dependent LLVM code to PowerPC assembly language. This printer is
Chris Lattner07fad1c2004-07-28 20:18:53 +000012// the output mechanism used by `llc'.
Misha Brukmane05203f2004-06-21 16:55:25 +000013//
Misha Brukmanb604b4d2004-07-08 17:58:04 +000014// Documentation at http://developer.apple.com/documentation/DeveloperTools/
15// Reference/Assembler/ASMIntroduction/chapter_1_section_1.html
Misha Brukman811f5c22004-06-29 17:13:26 +000016//
Misha Brukmane05203f2004-06-21 16:55:25 +000017//===----------------------------------------------------------------------===//
18
Craig Topperb25fda92012-03-17 18:46:09 +000019#include "InstPrinter/PPCInstPrinter.h"
Ulrich Weigand41789de2013-05-23 22:26:41 +000020#include "MCTargetDesc/PPCMCExpr.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000021#include "MCTargetDesc/PPCMCTargetDesc.h"
Tim Shencee75362017-09-22 18:30:02 +000022#include "MCTargetDesc/PPCPredicates.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000023#include "PPC.h"
24#include "PPCInstrInfo.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000025#include "PPCMachineFunctionInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000026#include "PPCSubtarget.h"
27#include "PPCTargetMachine.h"
Rafael Espindolaa17151a2013-10-08 13:08:17 +000028#include "PPCTargetStreamer.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000029#include "llvm/ADT/MapVector.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000030#include "llvm/ADT/StringRef.h"
31#include "llvm/ADT/Triple.h"
32#include "llvm/ADT/Twine.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000033#include "llvm/BinaryFormat/ELF.h"
34#include "llvm/BinaryFormat/MachO.h"
Chris Lattner0ced9052004-08-16 23:25:21 +000035#include "llvm/CodeGen/AsmPrinter.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000036#include "llvm/CodeGen/MachineBasicBlock.h"
37#include "llvm/CodeGen/MachineFunction.h"
Misha Brukmane05203f2004-06-21 16:55:25 +000038#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner1ff47942010-01-20 21:16:14 +000039#include "llvm/CodeGen/MachineModuleInfoImpls.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000040#include "llvm/CodeGen/MachineOperand.h"
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +000041#include "llvm/CodeGen/MachineRegisterInfo.h"
Hal Finkel934361a2015-01-14 01:07:51 +000042#include "llvm/CodeGen/StackMaps.h"
Anton Korobeynikovab663a02010-02-15 22:37:53 +000043#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000044#include "llvm/IR/DataLayout.h"
45#include "llvm/IR/GlobalValue.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000046#include "llvm/IR/Module.h"
Chris Lattner4cd44982009-09-13 17:14:04 +000047#include "llvm/MC/MCAsmInfo.h"
Chris Lattner9148f362010-01-13 19:00:57 +000048#include "llvm/MC/MCContext.h"
Bill Wendlingfaec0812010-03-11 23:39:44 +000049#include "llvm/MC/MCExpr.h"
Chris Lattner686a0952010-11-14 19:53:02 +000050#include "llvm/MC/MCInst.h"
Benjamin Kramer4e629f72012-11-26 13:34:22 +000051#include "llvm/MC/MCInstBuilder.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000052#include "llvm/MC/MCSectionELF.h"
Chris Lattner6c203912009-08-10 18:15:01 +000053#include "llvm/MC/MCSectionMachO.h"
Chris Lattner4b7dadb2009-08-19 05:49:37 +000054#include "llvm/MC/MCStreamer.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000055#include "llvm/MC/MCSymbol.h"
Rafael Espindola95fb9b92015-06-02 20:38:46 +000056#include "llvm/MC/MCSymbolELF.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000057#include "llvm/MC/SectionKind.h"
58#include "llvm/Support/Casting.h"
59#include "llvm/Support/CodeGen.h"
Devang Patel6e9a9792010-08-04 22:07:50 +000060#include "llvm/Support/Debug.h"
Torok Edwinfb8d6d52009-07-08 20:53:28 +000061#include "llvm/Support/ErrorHandling.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000062#include "llvm/Support/TargetRegistry.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000063#include "llvm/Support/raw_ostream.h"
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000064#include "llvm/Target/TargetMachine.h"
65#include <algorithm>
66#include <cassert>
67#include <cstdint>
68#include <memory>
69#include <new>
70
Chris Lattner0ced9052004-08-16 23:25:21 +000071using namespace llvm;
Misha Brukmane05203f2004-06-21 16:55:25 +000072
Chandler Carruth84e68b22014-04-22 02:41:26 +000073#define DEBUG_TYPE "asmprinter"
74
Chris Lattner1ef9cd42006-12-19 22:59:26 +000075namespace {
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000076
NAKAMURA Takumi70ad98a2015-09-22 11:13:55 +000077class PPCAsmPrinter : public AsmPrinter {
78protected:
79 MapVector<MCSymbol *, MCSymbol *> TOC;
80 const PPCSubtarget *Subtarget;
81 StackMaps SM;
Misha Brukmanb4402432005-04-21 23:30:14 +000082
NAKAMURA Takumi70ad98a2015-09-22 11:13:55 +000083public:
84 explicit PPCAsmPrinter(TargetMachine &TM,
85 std::unique_ptr<MCStreamer> Streamer)
86 : AsmPrinter(TM, std::move(Streamer)), SM(*this) {}
87
Mehdi Amini117296c2016-10-01 02:56:57 +000088 StringRef getPassName() const override { return "PowerPC Assembly Printer"; }
Misha Brukmane05203f2004-06-21 16:55:25 +000089
Mehdi Amini117296c2016-10-01 02:56:57 +000090 MCSymbol *lookUpOrCreateTOCEntry(MCSymbol *Sym);
Nate Begeman0ad7f812004-08-14 22:09:10 +000091
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000092 bool doInitialization(Module &M) override {
Mehdi Amini117296c2016-10-01 02:56:57 +000093 if (!TOC.empty())
94 TOC.clear();
95 return AsmPrinter::doInitialization(M);
Eugene Zelenko6a9226d2016-12-12 22:23:53 +000096 }
Nemanja Ivanovicbd56e4e2016-03-12 10:23:07 +000097
Craig Topper0d3fa922014-04-29 07:57:37 +000098 void EmitInstruction(const MachineInstr *MI) override;
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +000099
Chris Lattner510c66f2010-11-15 03:39:06 +0000100 void printOperand(const MachineInstr *MI, unsigned OpNo, raw_ostream &O);
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000101
Chris Lattnerf7f05672006-02-01 22:38:46 +0000102 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
Chris Lattner3bb09762010-04-04 05:29:35 +0000103 unsigned AsmVariant, const char *ExtraCode,
Craig Topper0d3fa922014-04-29 07:57:37 +0000104 raw_ostream &O) override;
Chris Lattner7674d902006-02-24 20:27:40 +0000105 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
Chris Lattner3bb09762010-04-04 05:29:35 +0000106 unsigned AsmVariant, const char *ExtraCode,
Craig Topper0d3fa922014-04-29 07:57:37 +0000107 raw_ostream &O) override;
Hal Finkel934361a2015-01-14 01:07:51 +0000108
109 void EmitEndOfAsmFile(Module &M) override;
110
Hal Finkel98347d32015-12-12 01:47:08 +0000111 void LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI);
112 void LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI);
Bill Schmidt82f1c772015-02-10 19:09:05 +0000113 void EmitTlsCall(const MachineInstr *MI, MCSymbolRefExpr::VariantKind VK);
Eric Christopher5c0e0092015-02-17 07:21:21 +0000114 bool runOnMachineFunction(MachineFunction &MF) override {
115 Subtarget = &MF.getSubtarget<PPCSubtarget>();
Tim Shen918ed872017-02-10 21:03:24 +0000116 bool Changed = AsmPrinter::runOnMachineFunction(MF);
117 emitXRayTable();
118 return Changed;
Eric Christopher5c0e0092015-02-17 07:21:21 +0000119 }
Nate Begeman4bfceb12004-09-04 05:00:00 +0000120 };
Misha Brukmanb4402432005-04-21 23:30:14 +0000121
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000122 /// PPCLinuxAsmPrinter - PowerPC assembly printer, customized for Linux
Nick Lewycky02d5f772009-10-25 06:33:48 +0000123 class PPCLinuxAsmPrinter : public PPCAsmPrinter {
Bill Wendlingc5437ea2009-02-24 08:30:20 +0000124 public:
David Blaikie94598322015-01-18 20:29:04 +0000125 explicit PPCLinuxAsmPrinter(TargetMachine &TM,
126 std::unique_ptr<MCStreamer> Streamer)
127 : PPCAsmPrinter(TM, std::move(Streamer)) {}
Jim Laskey28663c72006-12-21 20:26:09 +0000128
Mehdi Amini117296c2016-10-01 02:56:57 +0000129 StringRef getPassName() const override {
Jim Laskey28663c72006-12-21 20:26:09 +0000130 return "Linux PPC Assembly Printer";
131 }
132
Craig Topper0d3fa922014-04-29 07:57:37 +0000133 bool doFinalization(Module &M) override;
Hal Finkel3ee2af72014-07-18 23:29:49 +0000134 void EmitStartOfAsmFile(Module &M) override;
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000135
Craig Topper0d3fa922014-04-29 07:57:37 +0000136 void EmitFunctionEntryLabel() override;
Roman Divacky8c4b6a32012-08-28 19:06:55 +0000137
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +0000138 void EmitFunctionBodyStart() override;
Craig Topper0d3fa922014-04-29 07:57:37 +0000139 void EmitFunctionBodyEnd() override;
Tim Shen918ed872017-02-10 21:03:24 +0000140 void EmitInstruction(const MachineInstr *MI) override;
Jim Laskey28663c72006-12-21 20:26:09 +0000141 };
142
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000143 /// PPCDarwinAsmPrinter - PowerPC assembly printer, customized for Darwin/Mac
144 /// OS X
Nick Lewycky02d5f772009-10-25 06:33:48 +0000145 class PPCDarwinAsmPrinter : public PPCAsmPrinter {
Bill Wendlingc5437ea2009-02-24 08:30:20 +0000146 public:
David Blaikie94598322015-01-18 20:29:04 +0000147 explicit PPCDarwinAsmPrinter(TargetMachine &TM,
148 std::unique_ptr<MCStreamer> Streamer)
149 : PPCAsmPrinter(TM, std::move(Streamer)) {}
Nate Begeman4bfceb12004-09-04 05:00:00 +0000150
Mehdi Amini117296c2016-10-01 02:56:57 +0000151 StringRef getPassName() const override {
Nate Begeman4bfceb12004-09-04 05:00:00 +0000152 return "Darwin PPC Assembly Printer";
153 }
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000154
Craig Topper0d3fa922014-04-29 07:57:37 +0000155 bool doFinalization(Module &M) override;
156 void EmitStartOfAsmFile(Module &M) override;
Misha Brukmane05203f2004-06-21 16:55:25 +0000157 };
Eugene Zelenko6a9226d2016-12-12 22:23:53 +0000158
159} // end anonymous namespace
Misha Brukmane05203f2004-06-21 16:55:25 +0000160
Chris Lattner510c66f2010-11-15 03:39:06 +0000161void PPCAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
162 raw_ostream &O) {
Mehdi Aminibd7287e2015-07-16 06:11:10 +0000163 const DataLayout &DL = getDataLayout();
Chris Lattner510c66f2010-11-15 03:39:06 +0000164 const MachineOperand &MO = MI->getOperand(OpNo);
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +0000165
Misha Brukmane05203f2004-06-21 16:55:25 +0000166 switch (MO.getType()) {
Chris Lattner510c66f2010-11-15 03:39:06 +0000167 case MachineOperand::MO_Register: {
Nemanja Ivanovica5909672018-09-27 11:49:47 +0000168 unsigned Reg = PPCInstrInfo::getRegNumForOperand(MI->getDesc(),
169 MO.getReg(), OpNo);
Nemanja Ivanovic11049f82016-10-04 06:59:23 +0000170
Nemanja Ivanovic11049f82016-10-04 06:59:23 +0000171 const char *RegName = PPCInstPrinter::getRegisterName(Reg);
172
Chris Lattner510c66f2010-11-15 03:39:06 +0000173 // Linux assembler (Others?) does not take register mnemonics.
174 // FIXME - What about special registers used in mfspr/mtspr?
Eric Christopherd4986802015-02-10 00:44:17 +0000175 if (!Subtarget->isDarwin())
Nemanja Ivanovica5909672018-09-27 11:49:47 +0000176 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
Chris Lattner510c66f2010-11-15 03:39:06 +0000177 O << RegName;
178 return;
179 }
Chris Lattnerfef7a2d2006-05-04 17:21:20 +0000180 case MachineOperand::MO_Immediate:
Chris Lattner510c66f2010-11-15 03:39:06 +0000181 O << MO.getImm();
182 return;
Misha Brukman8d75aa42004-07-21 20:11:11 +0000183
Nate Begeman4ca2ea52006-04-22 18:53:45 +0000184 case MachineOperand::MO_MachineBasicBlock:
Matt Arsenault8b643552015-06-09 00:31:39 +0000185 MO.getMBB()->getSymbol()->print(O, MAI);
Misha Brukmane05203f2004-06-21 16:55:25 +0000186 return;
Misha Brukmanb604b4d2004-07-08 17:58:04 +0000187 case MachineOperand::MO_ConstantPoolIndex:
Mehdi Aminibd7287e2015-07-16 06:11:10 +0000188 O << DL.getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_'
189 << MO.getIndex();
Misha Brukmane05203f2004-06-21 16:55:25 +0000190 return;
Bob Wilsonf84f7102009-11-04 21:31:18 +0000191 case MachineOperand::MO_BlockAddress:
Matt Arsenault8b643552015-06-09 00:31:39 +0000192 GetBlockAddressSymbol(MO.getBlockAddress())->print(O, MAI);
Bob Wilsonf84f7102009-11-04 21:31:18 +0000193 return;
Nate Begeman5bf9bfe2004-08-13 09:32:01 +0000194 case MachineOperand::MO_GlobalAddress: {
Chris Lattner57575112005-12-16 00:22:14 +0000195 // Computing the address of a global symbol, not calling it.
Dan Gohmanbcaf6812010-04-15 01:51:59 +0000196 const GlobalValue *GV = MO.getGlobal();
Chris Lattner1e26ec32010-01-16 02:00:23 +0000197 MCSymbol *SymToPrint;
Misha Brukman7dba17d2004-07-23 16:08:20 +0000198
Nate Begeman844186b2004-10-17 23:01:34 +0000199 // External or weakly linked global variables need non-lazily-resolved stubs
Rafael Espindolaf092cc82016-06-24 13:28:26 +0000200 if (Subtarget->hasLazyResolverStub(GV)) {
Rafael Espindola01cdf312016-06-24 13:08:06 +0000201 SymToPrint = getSymbolWithGlobalValueBase(GV, "$non_lazy_ptr");
202 MachineModuleInfoImpl::StubValueTy &StubSym =
203 MMI->getObjFileInfo<MachineModuleInfoMachO>().getGVStubEntry(
204 SymToPrint);
205 if (!StubSym.getPointer())
206 StubSym = MachineModuleInfoImpl::StubValueTy(getSymbol(GV),
207 !GV->hasInternalLinkage());
Chris Lattner9ffa4e22009-07-15 01:14:44 +0000208 } else {
Rafael Espindola79858aa2013-10-29 17:07:16 +0000209 SymToPrint = getSymbol(GV);
Nate Begeman5bf9bfe2004-08-13 09:32:01 +0000210 }
Matt Arsenault8b643552015-06-09 00:31:39 +0000211
212 SymToPrint->print(O, MAI);
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000213
Chris Lattnerf33c7fc2010-04-03 22:28:33 +0000214 printOffset(MO.getOffset(), O);
Misha Brukmane05203f2004-06-21 16:55:25 +0000215 return;
Nate Begeman5bf9bfe2004-08-13 09:32:01 +0000216 }
Misha Brukmanb4402432005-04-21 23:30:14 +0000217
Misha Brukmane05203f2004-06-21 16:55:25 +0000218 default:
Pete Cooper0d4ea972014-05-16 23:28:17 +0000219 O << "<unknown operand type: " << (unsigned)MO.getType() << ">";
Misha Brukmana2737582004-06-25 15:11:34 +0000220 return;
Misha Brukmane05203f2004-06-21 16:55:25 +0000221 }
222}
223
Chris Lattner1bad2542006-02-23 19:31:10 +0000224/// PrintAsmOperand - Print out an operand for an inline asm expression.
225///
226bool PPCAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000227 unsigned AsmVariant,
Chris Lattner3bb09762010-04-04 05:29:35 +0000228 const char *ExtraCode, raw_ostream &O) {
Chris Lattner1bad2542006-02-23 19:31:10 +0000229 // Does this asm operand have a single letter operand modifier?
230 if (ExtraCode && ExtraCode[0]) {
231 if (ExtraCode[1] != 0) return true; // Unknown modifier.
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000232
Chris Lattner1bad2542006-02-23 19:31:10 +0000233 switch (ExtraCode[0]) {
Jack Carter5e69cff2012-06-26 13:49:27 +0000234 default:
235 // See if this is a generic print operand
236 return AsmPrinter::PrintAsmOperand(MI, OpNo, AsmVariant, ExtraCode, O);
Chris Lattner48518542007-01-25 02:52:50 +0000237 case 'c': // Don't print "$" before a global var name or constant.
Chris Lattner510c66f2010-11-15 03:39:06 +0000238 break; // PPC never has a prefix.
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000239 case 'L': // Write second word of DImode reference.
Chris Lattner1bad2542006-02-23 19:31:10 +0000240 // Verify that this operand has two consecutive registers.
Dan Gohman0d1e9a82008-10-03 15:45:36 +0000241 if (!MI->getOperand(OpNo).isReg() ||
Chris Lattner1bad2542006-02-23 19:31:10 +0000242 OpNo+1 == MI->getNumOperands() ||
Dan Gohman0d1e9a82008-10-03 15:45:36 +0000243 !MI->getOperand(OpNo+1).isReg())
Chris Lattner1bad2542006-02-23 19:31:10 +0000244 return true;
245 ++OpNo; // Return the high-part.
246 break;
Chris Lattnercb35c612007-04-24 22:51:03 +0000247 case 'I':
248 // Write 'i' if an integer constant, otherwise nothing. Used to print
249 // addi vs add, etc.
Dan Gohman0d1e9a82008-10-03 15:45:36 +0000250 if (MI->getOperand(OpNo).isImm())
Chris Lattnercb35c612007-04-24 22:51:03 +0000251 O << "i";
252 return false;
Zaara Syedaedefda42018-09-24 14:01:16 +0000253 case 'x':
254 if(!MI->getOperand(OpNo).isReg())
255 return true;
256 // This operand uses VSX numbering.
257 // If the operand is a VMX register, convert it to a VSX register.
258 unsigned Reg = MI->getOperand(OpNo).getReg();
259 if (PPCInstrInfo::isVRRegister(Reg))
260 Reg = PPC::VSX32 + (Reg - PPC::V0);
261 else if (PPCInstrInfo::isVFRegister(Reg))
262 Reg = PPC::VSX32 + (Reg - PPC::VF0);
263 const char *RegName;
264 RegName = PPCInstPrinter::getRegisterName(Reg);
Nemanja Ivanovica5909672018-09-27 11:49:47 +0000265 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
Zaara Syedaedefda42018-09-24 14:01:16 +0000266 O << RegName;
267 return false;
Chris Lattner1bad2542006-02-23 19:31:10 +0000268 }
269 }
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000270
Chris Lattner76c564b2010-04-04 04:47:45 +0000271 printOperand(MI, OpNo, O);
Chris Lattner1bad2542006-02-23 19:31:10 +0000272 return false;
273}
274
Dale Johannesen4a50e682009-08-18 00:18:39 +0000275// At the moment, all inline asm memory operands are a single register.
276// In any case, the output of this routine should always be just one
277// assembler operand.
278
Chris Lattner7674d902006-02-24 20:27:40 +0000279bool PPCAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +0000280 unsigned AsmVariant,
Chris Lattner3bb09762010-04-04 05:29:35 +0000281 const char *ExtraCode,
282 raw_ostream &O) {
Hal Finkel4f24c622012-11-05 18:18:42 +0000283 if (ExtraCode && ExtraCode[0]) {
284 if (ExtraCode[1] != 0) return true; // Unknown modifier.
285
286 switch (ExtraCode[0]) {
287 default: return true; // Unknown modifier.
288 case 'y': // A memory reference for an X-form instruction
289 {
290 const char *RegName = "r0";
Eric Christopherd4986802015-02-10 00:44:17 +0000291 if (!Subtarget->isDarwin())
Nemanja Ivanovica5909672018-09-27 11:49:47 +0000292 RegName = PPCRegisterInfo::stripRegisterPrefix(RegName);
Hal Finkel4f24c622012-11-05 18:18:42 +0000293 O << RegName << ", ";
294 printOperand(MI, OpNo, O);
295 return false;
296 }
Bill Schmidtbe95fd52014-09-11 20:10:03 +0000297 case 'U': // Print 'u' for update form.
298 case 'X': // Print 'x' for indexed form.
NAKAMURA Takumi0a7d0ad2015-09-22 11:15:07 +0000299 {
300 // FIXME: Currently for PowerPC memory operands are always loaded
301 // into a register, so we never get an update or indexed form.
302 // This is bad even for offset forms, since even if we know we
303 // have a value in -16(r1), we will generate a load into r<n>
304 // and then load from 0(r<n>). Until that issue is fixed,
305 // tolerate 'U' and 'X' but don't output anything.
306 assert(MI->getOperand(OpNo).isReg());
307 return false;
308 }
Hal Finkel4f24c622012-11-05 18:18:42 +0000309 }
310 }
311
Chris Lattner510c66f2010-11-15 03:39:06 +0000312 assert(MI->getOperand(OpNo).isReg());
Dale Johannesenf582ac72009-08-26 18:10:32 +0000313 O << "0(";
Chris Lattner76c564b2010-04-04 04:47:45 +0000314 printOperand(MI, OpNo, O);
Dale Johannesenf582ac72009-08-26 18:10:32 +0000315 O << ")";
Chris Lattner7674d902006-02-24 20:27:40 +0000316 return false;
317}
Chris Lattner1bad2542006-02-23 19:31:10 +0000318
Bill Schmidt34627e32012-11-27 17:35:46 +0000319/// lookUpOrCreateTOCEntry -- Given a symbol, look up whether a TOC entry
320/// exists for it. If not, create one. Then return a symbol that references
321/// the TOC entry.
322MCSymbol *PPCAsmPrinter::lookUpOrCreateTOCEntry(MCSymbol *Sym) {
Bill Schmidt34627e32012-11-27 17:35:46 +0000323 MCSymbol *&TOCEntry = TOC[Sym];
Rafael Espindolaccfbbd52015-03-17 14:50:32 +0000324 if (!TOCEntry)
Rafael Espindola9ab09232015-03-17 20:07:06 +0000325 TOCEntry = createTempSymbol("C");
Bill Schmidt34627e32012-11-27 17:35:46 +0000326 return TOCEntry;
327}
328
Hal Finkel934361a2015-01-14 01:07:51 +0000329void PPCAsmPrinter::EmitEndOfAsmFile(Module &M) {
Than McIntosh30c804b2018-11-26 18:43:48 +0000330 emitStackMaps(SM);
Hal Finkel934361a2015-01-14 01:07:51 +0000331}
332
Hal Finkel98347d32015-12-12 01:47:08 +0000333void PPCAsmPrinter::LowerSTACKMAP(StackMaps &SM, const MachineInstr &MI) {
Hal Finkel934361a2015-01-14 01:07:51 +0000334 unsigned NumNOPBytes = MI.getOperand(1).getImm();
335
336 SM.recordStackMap(MI);
337 assert(NumNOPBytes % 4 == 0 && "Invalid number of NOP bytes requested!");
338
339 // Scan ahead to trim the shadow.
340 const MachineBasicBlock &MBB = *MI.getParent();
341 MachineBasicBlock::const_iterator MII(MI);
342 ++MII;
343 while (NumNOPBytes > 0) {
344 if (MII == MBB.end() || MII->isCall() ||
345 MII->getOpcode() == PPC::DBG_VALUE ||
346 MII->getOpcode() == TargetOpcode::PATCHPOINT ||
347 MII->getOpcode() == TargetOpcode::STACKMAP)
348 break;
349 ++MII;
350 NumNOPBytes -= 4;
351 }
352
353 // Emit nops.
354 for (unsigned i = 0; i < NumNOPBytes; i += 4)
Hal Finkel98347d32015-12-12 01:47:08 +0000355 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
Hal Finkel934361a2015-01-14 01:07:51 +0000356}
357
358// Lower a patchpoint of the form:
359// [<def>], <id>, <numBytes>, <target>, <numArgs>
Hal Finkel98347d32015-12-12 01:47:08 +0000360void PPCAsmPrinter::LowerPATCHPOINT(StackMaps &SM, const MachineInstr &MI) {
Hal Finkel934361a2015-01-14 01:07:51 +0000361 SM.recordPatchPoint(MI);
362 PatchPointOpers Opers(&MI);
363
Hal Finkel934361a2015-01-14 01:07:51 +0000364 unsigned EncodedBytes = 0;
Philip Reamese83c4b32016-08-23 23:33:29 +0000365 const MachineOperand &CalleeMO = Opers.getCallTarget();
Hal Finkel934361a2015-01-14 01:07:51 +0000366
Hal Finkel40120242015-07-14 22:53:11 +0000367 if (CalleeMO.isImm()) {
Philip Reamese83c4b32016-08-23 23:33:29 +0000368 int64_t CallTarget = CalleeMO.getImm();
Hal Finkel40120242015-07-14 22:53:11 +0000369 if (CallTarget) {
370 assert((CallTarget & 0xFFFFFFFFFFFF) == CallTarget &&
371 "High 16 bits of call target should be zero.");
372 unsigned ScratchReg = MI.getOperand(Opers.getNextScratchIdx()).getReg();
373 EncodedBytes = 0;
374 // Materialize the jump address:
Hal Finkel98347d32015-12-12 01:47:08 +0000375 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI8)
Hal Finkel40120242015-07-14 22:53:11 +0000376 .addReg(ScratchReg)
377 .addImm((CallTarget >> 32) & 0xFFFF));
378 ++EncodedBytes;
Hal Finkel98347d32015-12-12 01:47:08 +0000379 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::RLDIC)
Hal Finkel40120242015-07-14 22:53:11 +0000380 .addReg(ScratchReg)
381 .addReg(ScratchReg)
382 .addImm(32).addImm(16));
383 ++EncodedBytes;
Hal Finkel98347d32015-12-12 01:47:08 +0000384 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORIS8)
Hal Finkel40120242015-07-14 22:53:11 +0000385 .addReg(ScratchReg)
386 .addReg(ScratchReg)
387 .addImm((CallTarget >> 16) & 0xFFFF));
388 ++EncodedBytes;
Hal Finkel98347d32015-12-12 01:47:08 +0000389 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ORI8)
Hal Finkel40120242015-07-14 22:53:11 +0000390 .addReg(ScratchReg)
391 .addReg(ScratchReg)
392 .addImm(CallTarget & 0xFFFF));
393
394 // Save the current TOC pointer before the remote call.
Eric Christopherd78bd572017-04-10 22:22:11 +0000395 int TOCSaveOffset = Subtarget->getFrameLowering()->getTOCSaveOffset();
Hal Finkel98347d32015-12-12 01:47:08 +0000396 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::STD)
Hal Finkel40120242015-07-14 22:53:11 +0000397 .addReg(PPC::X2)
398 .addImm(TOCSaveOffset)
399 .addReg(PPC::X1));
400 ++EncodedBytes;
Hal Finkel9bbad032015-07-14 22:26:06 +0000401
Hal Finkel40120242015-07-14 22:53:11 +0000402 // If we're on ELFv1, then we need to load the actual function pointer
403 // from the function descriptor.
404 if (!Subtarget->isELFv2ABI()) {
NAKAMURA Takumi84965032015-09-22 11:14:12 +0000405 // Load the new TOC pointer and the function address, but not r11
406 // (needing this is rare, and loading it here would prevent passing it
407 // via a 'nest' parameter.
Hal Finkel98347d32015-12-12 01:47:08 +0000408 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
Hal Finkel40120242015-07-14 22:53:11 +0000409 .addReg(PPC::X2)
410 .addImm(8)
411 .addReg(ScratchReg));
412 ++EncodedBytes;
Hal Finkel98347d32015-12-12 01:47:08 +0000413 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
Hal Finkel40120242015-07-14 22:53:11 +0000414 .addReg(ScratchReg)
415 .addImm(0)
416 .addReg(ScratchReg));
417 ++EncodedBytes;
418 }
419
Hal Finkel98347d32015-12-12 01:47:08 +0000420 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTCTR8)
Hal Finkel40120242015-07-14 22:53:11 +0000421 .addReg(ScratchReg));
422 ++EncodedBytes;
Hal Finkel98347d32015-12-12 01:47:08 +0000423 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BCTRL8));
Hal Finkel40120242015-07-14 22:53:11 +0000424 ++EncodedBytes;
425
426 // Restore the TOC pointer after the call.
Hal Finkel98347d32015-12-12 01:47:08 +0000427 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
Hal Finkel9bbad032015-07-14 22:26:06 +0000428 .addReg(PPC::X2)
Hal Finkel40120242015-07-14 22:53:11 +0000429 .addImm(TOCSaveOffset)
430 .addReg(PPC::X1));
Hal Finkel9bbad032015-07-14 22:26:06 +0000431 ++EncodedBytes;
432 }
Hal Finkel40120242015-07-14 22:53:11 +0000433 } else if (CalleeMO.isGlobal()) {
434 const GlobalValue *GValue = CalleeMO.getGlobal();
435 MCSymbol *MOSymbol = getSymbol(GValue);
436 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, OutContext);
Hal Finkel9bbad032015-07-14 22:26:06 +0000437
Hal Finkel98347d32015-12-12 01:47:08 +0000438 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL8_NOP)
Hal Finkel40120242015-07-14 22:53:11 +0000439 .addExpr(SymVar));
440 EncodedBytes += 2;
Hal Finkel934361a2015-01-14 01:07:51 +0000441 }
442
Hal Finkel9bbad032015-07-14 22:26:06 +0000443 // Each instruction is 4 bytes.
444 EncodedBytes *= 4;
445
Hal Finkel934361a2015-01-14 01:07:51 +0000446 // Emit padding.
Philip Reamese83c4b32016-08-23 23:33:29 +0000447 unsigned NumBytes = Opers.getNumPatchBytes();
Hal Finkel934361a2015-01-14 01:07:51 +0000448 assert(NumBytes >= EncodedBytes &&
449 "Patchpoint can't request size less than the length of a call.");
450 assert((NumBytes - EncodedBytes) % 4 == 0 &&
451 "Invalid number of NOP bytes requested!");
452 for (unsigned i = EncodedBytes; i < NumBytes; i += 4)
Hal Finkel98347d32015-12-12 01:47:08 +0000453 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
Hal Finkel934361a2015-01-14 01:07:51 +0000454}
Bill Schmidt34627e32012-11-27 17:35:46 +0000455
Bill Schmidt82f1c772015-02-10 19:09:05 +0000456/// EmitTlsCall -- Given a GETtls[ld]ADDR[32] instruction, print a
457/// call to __tls_get_addr to the current output stream.
458void PPCAsmPrinter::EmitTlsCall(const MachineInstr *MI,
459 MCSymbolRefExpr::VariantKind VK) {
460 StringRef Name = "__tls_get_addr";
Jim Grosbach6f482002015-05-18 18:43:14 +0000461 MCSymbol *TlsGetAddr = OutContext.getOrCreateSymbol(Name);
Bill Schmidt82f1c772015-02-10 19:09:05 +0000462 MCSymbolRefExpr::VariantKind Kind = MCSymbolRefExpr::VK_None;
463
464 assert(MI->getOperand(0).isReg() &&
Bill Schmidt67f36bd2015-02-10 19:31:55 +0000465 ((Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::X3) ||
466 (!Subtarget->isPPC64() && MI->getOperand(0).getReg() == PPC::R3)) &&
Bill Schmidt82f1c772015-02-10 19:09:05 +0000467 "GETtls[ld]ADDR[32] must define GPR3");
468 assert(MI->getOperand(1).isReg() &&
Bill Schmidt67f36bd2015-02-10 19:31:55 +0000469 ((Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::X3) ||
470 (!Subtarget->isPPC64() && MI->getOperand(1).getReg() == PPC::R3)) &&
Bill Schmidt82f1c772015-02-10 19:09:05 +0000471 "GETtls[ld]ADDR[32] must read GPR3");
472
Bill Schmidt67f36bd2015-02-10 19:31:55 +0000473 if (!Subtarget->isPPC64() && !Subtarget->isDarwin() &&
Rafael Espindola0db11db2016-06-27 14:19:45 +0000474 isPositionIndependent())
Bill Schmidt82f1c772015-02-10 19:09:05 +0000475 Kind = MCSymbolRefExpr::VK_PLT;
476 const MCSymbolRefExpr *TlsRef =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000477 MCSymbolRefExpr::create(TlsGetAddr, Kind, OutContext);
Bill Schmidt82f1c772015-02-10 19:09:05 +0000478 const MachineOperand &MO = MI->getOperand(2);
479 const GlobalValue *GValue = MO.getGlobal();
480 MCSymbol *MOSymbol = getSymbol(GValue);
Jim Grosbach13760bd2015-05-30 01:25:56 +0000481 const MCExpr *SymVar = MCSymbolRefExpr::create(MOSymbol, VK, OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000482 EmitToStreamer(*OutStreamer,
Bill Schmidt67f36bd2015-02-10 19:31:55 +0000483 MCInstBuilder(Subtarget->isPPC64() ?
Bill Schmidt82f1c772015-02-10 19:09:05 +0000484 PPC::BL8_NOP_TLS : PPC::BL_TLS)
485 .addExpr(TlsRef)
486 .addExpr(SymVar));
487}
488
Chris Lattner73de5fb2010-01-28 01:28:58 +0000489/// EmitInstruction -- Print out a single PowerPC MI in Darwin syntax to
Nate Begeman0ad7f812004-08-14 22:09:10 +0000490/// the current output stream.
Misha Brukmane05203f2004-06-21 16:55:25 +0000491///
Chris Lattner73de5fb2010-01-28 01:28:58 +0000492void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
Chris Lattner510c66f2010-11-15 03:39:06 +0000493 MCInst TmpInst;
Eric Christopherd4986802015-02-10 00:44:17 +0000494 bool isPPC64 = Subtarget->isPPC64();
Daniel Sandersc81f4502015-06-16 15:44:21 +0000495 bool isDarwin = TM.getTargetTriple().isOSDarwin();
Matthias Braunf1caa282017-12-15 22:22:58 +0000496 const Module *M = MF->getFunction().getParent();
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000497 PICLevel::Level PL = M->getPICLevel();
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +0000498
Justin Hibbitsd52990c2018-07-18 04:25:10 +0000499#ifndef NDEBUG
500 // Validate that SPE and FPU are mutually exclusive in codegen
501 if (!MI->isInlineAsm()) {
502 for (const MachineOperand &MO: MI->operands()) {
503 if (MO.isReg()) {
504 unsigned Reg = MO.getReg();
505 if (Subtarget->hasSPE()) {
506 if (PPC::F4RCRegClass.contains(Reg) ||
507 PPC::F8RCRegClass.contains(Reg) ||
508 PPC::QBRCRegClass.contains(Reg) ||
509 PPC::QFRCRegClass.contains(Reg) ||
510 PPC::QSRCRegClass.contains(Reg) ||
511 PPC::VFRCRegClass.contains(Reg) ||
512 PPC::VRRCRegClass.contains(Reg) ||
513 PPC::VSFRCRegClass.contains(Reg) ||
514 PPC::VSSRCRegClass.contains(Reg)
515 )
516 llvm_unreachable("SPE targets cannot have FPRegs!");
517 } else {
518 if (PPC::SPERCRegClass.contains(Reg))
519 llvm_unreachable("SPE register found in FPU-targeted code!");
520 }
521 }
522 }
523 }
524#endif
Chris Lattner510c66f2010-11-15 03:39:06 +0000525 // Lower multi-instruction pseudo operations.
526 switch (MI->getOpcode()) {
527 default: break;
David Blaikieb735b4d2013-06-16 20:34:27 +0000528 case TargetOpcode::DBG_VALUE:
529 llvm_unreachable("Should be handled target independently");
Hal Finkel934361a2015-01-14 01:07:51 +0000530 case TargetOpcode::STACKMAP:
Hal Finkel98347d32015-12-12 01:47:08 +0000531 return LowerSTACKMAP(SM, *MI);
Hal Finkel934361a2015-01-14 01:07:51 +0000532 case TargetOpcode::PATCHPOINT:
Hal Finkel98347d32015-12-12 01:47:08 +0000533 return LowerPATCHPOINT(SM, *MI);
Hal Finkel934361a2015-01-14 01:07:51 +0000534
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000535 case PPC::MoveGOTtoLR: {
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000536 // Transform %lr = MoveGOTtoLR
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000537 // Into this: bl _GLOBAL_OFFSET_TABLE_@local-4
538 // _GLOBAL_OFFSET_TABLE_@local-4 (instruction preceding
539 // _GLOBAL_OFFSET_TABLE_) has exactly one instruction:
540 // blrl
541 // This will return the pointer to _GLOBAL_OFFSET_TABLE_@local
542 MCSymbol *GOTSymbol =
Jim Grosbach6f482002015-05-18 18:43:14 +0000543 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000544 const MCExpr *OffsExpr =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000545 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol,
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000546 MCSymbolRefExpr::VK_PPC_LOCAL,
547 OutContext),
Jim Grosbach13760bd2015-05-30 01:25:56 +0000548 MCConstantExpr::create(4, OutContext),
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000549 OutContext);
550
551 // Emit the 'bl'.
Lang Hames9ff69c82015-04-24 19:11:51 +0000552 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL).addExpr(OffsExpr));
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000553 return;
554 }
Chris Lattner510c66f2010-11-15 03:39:06 +0000555 case PPC::MovePCtoLR:
556 case PPC::MovePCtoLR8: {
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000557 // Transform %lr = MovePCtoLR
NAKAMURA Takumi84965032015-09-22 11:14:12 +0000558 // Into this, where the label is the PIC base:
Chris Lattner510c66f2010-11-15 03:39:06 +0000559 // bl L1$pb
560 // L1$pb:
561 MCSymbol *PICBase = MF->getPICBaseSymbol();
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +0000562
Chris Lattner510c66f2010-11-15 03:39:06 +0000563 // Emit the 'bl'.
NAKAMURA Takumi70ad98a2015-09-22 11:13:55 +0000564 EmitToStreamer(*OutStreamer,
565 MCInstBuilder(PPC::BL)
566 // FIXME: We would like an efficient form for this, so we
567 // don't have to do a lot of extra uniquing.
568 .addExpr(MCSymbolRefExpr::create(PICBase, OutContext)));
569
Chris Lattner510c66f2010-11-15 03:39:06 +0000570 // Emit the label.
Lang Hames9ff69c82015-04-24 19:11:51 +0000571 OutStreamer->EmitLabel(PICBase);
Chris Lattner510c66f2010-11-15 03:39:06 +0000572 return;
573 }
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000574 case PPC::UpdateGBR: {
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000575 // Transform %rd = UpdateGBR(%rt, %ri)
576 // Into: lwz %rt, .L0$poff - .L0$pb(%ri)
577 // add %rd, %rt, %ri
Strahinja Petrovic06cf6a62018-03-27 11:23:53 +0000578 // or into (if secure plt mode is on):
579 // addis r30, r30, .LTOC - .L0$pb@ha
580 // addi r30, r30, .LTOC - .L0$pb@l
Hal Finkel3ee2af72014-07-18 23:29:49 +0000581 // Get the offset from the GOT Base Register to the GOT
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000582 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Strahinja Petrovic06cf6a62018-03-27 11:23:53 +0000583 if (Subtarget->isSecurePlt() && isPositionIndependent() ) {
584 unsigned PICR = TmpInst.getOperand(0).getReg();
585 MCSymbol *LTOCSymbol = OutContext.getOrCreateSymbol(StringRef(".LTOC"));
586 const MCExpr *PB =
587 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
588 OutContext);
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000589
Strahinja Petrovic06cf6a62018-03-27 11:23:53 +0000590 const MCExpr *LTOCDeltaExpr =
591 MCBinaryExpr::createSub(MCSymbolRefExpr::create(LTOCSymbol, OutContext),
592 PB, OutContext);
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000593
Strahinja Petrovic06cf6a62018-03-27 11:23:53 +0000594 const MCExpr *LTOCDeltaHi =
595 PPCMCExpr::createHa(LTOCDeltaExpr, false, OutContext);
596 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
597 .addReg(PICR)
598 .addReg(PICR)
599 .addExpr(LTOCDeltaHi));
600
601 const MCExpr *LTOCDeltaLo =
602 PPCMCExpr::createLo(LTOCDeltaExpr, false, OutContext);
603 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
604 .addReg(PICR)
605 .addReg(PICR)
606 .addExpr(LTOCDeltaLo));
607 return;
608 } else {
609 MCSymbol *PICOffset =
610 MF->getInfo<PPCFunctionInfo>()->getPICOffsetSymbol();
611 TmpInst.setOpcode(PPC::LWZ);
612 const MCExpr *Exp =
613 MCSymbolRefExpr::create(PICOffset, MCSymbolRefExpr::VK_None, OutContext);
614 const MCExpr *PB =
615 MCSymbolRefExpr::create(MF->getPICBaseSymbol(),
616 MCSymbolRefExpr::VK_None,
617 OutContext);
618 const MCOperand TR = TmpInst.getOperand(1);
619 const MCOperand PICR = TmpInst.getOperand(0);
620
621 // Step 1: lwz %rt, .L$poff - .L$pb(%ri)
622 TmpInst.getOperand(1) =
623 MCOperand::createExpr(MCBinaryExpr::createSub(Exp, PB, OutContext));
624 TmpInst.getOperand(0) = TR;
625 TmpInst.getOperand(2) = PICR;
626 EmitToStreamer(*OutStreamer, TmpInst);
627
628 TmpInst.setOpcode(PPC::ADD4);
629 TmpInst.getOperand(0) = PICR;
630 TmpInst.getOperand(1) = TR;
631 TmpInst.getOperand(2) = PICR;
632 EmitToStreamer(*OutStreamer, TmpInst);
633 return;
634 }
Hal Finkel3ee2af72014-07-18 23:29:49 +0000635 }
636 case PPC::LWZtoc: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000637 // Transform %r3 = LWZtoc @min1, %r2
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000638 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Hal Finkel3ee2af72014-07-18 23:29:49 +0000639
640 // Change the opcode to LWZ, and the global address operand to be a
641 // reference to the GOT entry we will synthesize later.
642 TmpInst.setOpcode(PPC::LWZ);
643 const MachineOperand &MO = MI->getOperand(1);
644
645 // Map symbol -> label of TOC entry
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000646 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
Hal Finkel3ee2af72014-07-18 23:29:49 +0000647 MCSymbol *MOSymbol = nullptr;
648 if (MO.isGlobal())
649 MOSymbol = getSymbol(MO.getGlobal());
650 else if (MO.isCPI())
651 MOSymbol = GetCPISymbol(MO.getIndex());
652 else if (MO.isJTI())
653 MOSymbol = GetJTISymbol(MO.getIndex());
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000654 else if (MO.isBlockAddress())
655 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
Hal Finkel3ee2af72014-07-18 23:29:49 +0000656
Davide Italiano4cccc482016-06-17 18:07:14 +0000657 if (PL == PICLevel::SmallPIC) {
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000658 const MCExpr *Exp =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000659 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_GOT,
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000660 OutContext);
Jim Grosbache9119e42015-05-13 18:37:00 +0000661 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000662 } else {
663 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
Hal Finkel3ee2af72014-07-18 23:29:49 +0000664
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000665 const MCExpr *Exp =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000666 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_None,
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000667 OutContext);
668 const MCExpr *PB =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000669 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000670 OutContext);
Jim Grosbach13760bd2015-05-30 01:25:56 +0000671 Exp = MCBinaryExpr::createSub(Exp, PB, OutContext);
Jim Grosbache9119e42015-05-13 18:37:00 +0000672 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000673 }
Lang Hames9ff69c82015-04-24 19:11:51 +0000674 EmitToStreamer(*OutStreamer, TmpInst);
Hal Finkel3ee2af72014-07-18 23:29:49 +0000675 return;
676 }
Roman Divackyace47072012-08-24 16:26:02 +0000677 case PPC::LDtocJTI:
678 case PPC::LDtocCPT:
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000679 case PPC::LDtocBA:
Chris Lattner510c66f2010-11-15 03:39:06 +0000680 case PPC::LDtoc: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000681 // Transform %x3 = LDtoc @min1, %x2
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000682 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Roman Divackyace47072012-08-24 16:26:02 +0000683
Chris Lattner510c66f2010-11-15 03:39:06 +0000684 // Change the opcode to LD, and the global address operand to be a
685 // reference to the TOC entry we will synthesize later.
686 TmpInst.setOpcode(PPC::LD);
687 const MachineOperand &MO = MI->getOperand(1);
Roman Divackyace47072012-08-24 16:26:02 +0000688
689 // Map symbol -> label of TOC entry
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000690 assert(MO.isGlobal() || MO.isCPI() || MO.isJTI() || MO.isBlockAddress());
Craig Topper062a2ba2014-04-25 05:30:21 +0000691 MCSymbol *MOSymbol = nullptr;
Roman Divackyace47072012-08-24 16:26:02 +0000692 if (MO.isGlobal())
Rafael Espindola79858aa2013-10-29 17:07:16 +0000693 MOSymbol = getSymbol(MO.getGlobal());
Roman Divackyace47072012-08-24 16:26:02 +0000694 else if (MO.isCPI())
695 MOSymbol = GetCPISymbol(MO.getIndex());
696 else if (MO.isJTI())
697 MOSymbol = GetJTISymbol(MO.getIndex());
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000698 else if (MO.isBlockAddress())
699 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
Bill Schmidt34627e32012-11-27 17:35:46 +0000700
701 MCSymbol *TOCEntry = lookUpOrCreateTOCEntry(MOSymbol);
Roman Divacky0be33592012-09-18 17:10:37 +0000702
Chris Lattner510c66f2010-11-15 03:39:06 +0000703 const MCExpr *Exp =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000704 MCSymbolRefExpr::create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
Chris Lattner510c66f2010-11-15 03:39:06 +0000705 OutContext);
Jim Grosbache9119e42015-05-13 18:37:00 +0000706 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
Lang Hames9ff69c82015-04-24 19:11:51 +0000707 EmitToStreamer(*OutStreamer, TmpInst);
Chris Lattner686a0952010-11-14 19:53:02 +0000708 return;
709 }
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +0000710
Bill Schmidt34627e32012-11-27 17:35:46 +0000711 case PPC::ADDIStocHA: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000712 // Transform %xd = ADDIStocHA %x2, @sym
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000713 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Bill Schmidt34627e32012-11-27 17:35:46 +0000714
Bill Schmidt5d82f092014-06-16 21:36:02 +0000715 // Change the opcode to ADDIS8. If the global address is external, has
716 // common linkage, is a non-local function address, or is a jump table
Bill Schmidt34627e32012-11-27 17:35:46 +0000717 // address, then generate a TOC entry and reference that. Otherwise
718 // reference the symbol directly.
719 TmpInst.setOpcode(PPC::ADDIS8);
720 const MachineOperand &MO = MI->getOperand(2);
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000721 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
722 MO.isBlockAddress()) &&
Bill Schmidt34627e32012-11-27 17:35:46 +0000723 "Invalid operand for ADDIStocHA!");
Craig Topper062a2ba2014-04-25 05:30:21 +0000724 MCSymbol *MOSymbol = nullptr;
Eric Christopherc1808362015-11-20 20:51:31 +0000725 bool GlobalToc = false;
Bill Schmidt34627e32012-11-27 17:35:46 +0000726
727 if (MO.isGlobal()) {
Rafael Espindola04902862014-05-29 15:41:38 +0000728 const GlobalValue *GV = MO.getGlobal();
729 MOSymbol = getSymbol(GV);
Eric Christopherc1808362015-11-20 20:51:31 +0000730 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
731 GlobalToc = (GVFlags & PPCII::MO_NLP_FLAG);
732 } else if (MO.isCPI()) {
Bill Schmidt34627e32012-11-27 17:35:46 +0000733 MOSymbol = GetCPISymbol(MO.getIndex());
Eric Christopherc1808362015-11-20 20:51:31 +0000734 } else if (MO.isJTI()) {
Bill Schmidt34627e32012-11-27 17:35:46 +0000735 MOSymbol = GetJTISymbol(MO.getIndex());
Eric Christopherc1808362015-11-20 20:51:31 +0000736 } else if (MO.isBlockAddress()) {
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000737 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
Eric Christopherc1808362015-11-20 20:51:31 +0000738 }
Bill Schmidt34627e32012-11-27 17:35:46 +0000739
Eric Christopherc1808362015-11-20 20:51:31 +0000740 if (GlobalToc || MO.isJTI() || MO.isBlockAddress() ||
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000741 TM.getCodeModel() == CodeModel::Large)
Bill Schmidt34627e32012-11-27 17:35:46 +0000742 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
743
744 const MCExpr *Exp =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000745 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_HA,
Bill Schmidt34627e32012-11-27 17:35:46 +0000746 OutContext);
Hal Finkel7b104d42016-09-02 21:37:07 +0000747
748 if (!MO.isJTI() && MO.getOffset())
749 Exp = MCBinaryExpr::createAdd(Exp,
750 MCConstantExpr::create(MO.getOffset(),
751 OutContext),
752 OutContext);
753
Jim Grosbache9119e42015-05-13 18:37:00 +0000754 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
Lang Hames9ff69c82015-04-24 19:11:51 +0000755 EmitToStreamer(*OutStreamer, TmpInst);
Bill Schmidt34627e32012-11-27 17:35:46 +0000756 return;
757 }
758 case PPC::LDtocL: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000759 // Transform %xd = LDtocL @sym, %xs
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000760 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Bill Schmidt34627e32012-11-27 17:35:46 +0000761
Ulrich Weigand4a083882013-03-26 10:55:45 +0000762 // Change the opcode to LD. If the global address is external, has
Bill Schmidt34627e32012-11-27 17:35:46 +0000763 // common linkage, or is a jump table address, then reference the
764 // associated TOC entry. Otherwise reference the symbol directly.
Ulrich Weigand4a083882013-03-26 10:55:45 +0000765 TmpInst.setOpcode(PPC::LD);
Bill Schmidt34627e32012-11-27 17:35:46 +0000766 const MachineOperand &MO = MI->getOperand(1);
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000767 assert((MO.isGlobal() || MO.isCPI() || MO.isJTI() ||
768 MO.isBlockAddress()) &&
Bill Schmidt27917782013-02-21 17:12:27 +0000769 "Invalid operand for LDtocL!");
Craig Topper062a2ba2014-04-25 05:30:21 +0000770 MCSymbol *MOSymbol = nullptr;
Bill Schmidt34627e32012-11-27 17:35:46 +0000771
772 if (MO.isJTI())
773 MOSymbol = lookUpOrCreateTOCEntry(GetJTISymbol(MO.getIndex()));
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +0000774 else if (MO.isBlockAddress()) {
775 MOSymbol = GetBlockAddressSymbol(MO.getBlockAddress());
776 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
777 }
Bill Schmidtbb381d72013-09-17 20:03:25 +0000778 else if (MO.isCPI()) {
Bill Schmidt27917782013-02-21 17:12:27 +0000779 MOSymbol = GetCPISymbol(MO.getIndex());
Bill Schmidtbb381d72013-09-17 20:03:25 +0000780 if (TM.getCodeModel() == CodeModel::Large)
781 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
782 }
Bill Schmidt27917782013-02-21 17:12:27 +0000783 else if (MO.isGlobal()) {
Eric Christopherc1808362015-11-20 20:51:31 +0000784 const GlobalValue *GV = MO.getGlobal();
785 MOSymbol = getSymbol(GV);
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000786 LLVM_DEBUG(
787 unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
788 assert((GVFlags & PPCII::MO_NLP_FLAG) &&
789 "LDtocL used on symbol that could be accessed directly is "
790 "invalid. Must match ADDIStocHA."));
Eric Christopherc1808362015-11-20 20:51:31 +0000791 MOSymbol = lookUpOrCreateTOCEntry(MOSymbol);
Bill Schmidt34627e32012-11-27 17:35:46 +0000792 }
793
794 const MCExpr *Exp =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000795 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
Bill Schmidt34627e32012-11-27 17:35:46 +0000796 OutContext);
Jim Grosbache9119e42015-05-13 18:37:00 +0000797 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
Lang Hames9ff69c82015-04-24 19:11:51 +0000798 EmitToStreamer(*OutStreamer, TmpInst);
Bill Schmidt34627e32012-11-27 17:35:46 +0000799 return;
800 }
801 case PPC::ADDItocL: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000802 // Transform %xd = ADDItocL %xs, @sym
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000803 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Bill Schmidt34627e32012-11-27 17:35:46 +0000804
Ulrich Weigand35f9fdf2013-03-26 10:55:20 +0000805 // Change the opcode to ADDI8. If the global address is external, then
Bill Schmidt34627e32012-11-27 17:35:46 +0000806 // generate a TOC entry and reference that. Otherwise reference the
807 // symbol directly.
Ulrich Weigand35f9fdf2013-03-26 10:55:20 +0000808 TmpInst.setOpcode(PPC::ADDI8);
Bill Schmidt34627e32012-11-27 17:35:46 +0000809 const MachineOperand &MO = MI->getOperand(2);
810 assert((MO.isGlobal() || MO.isCPI()) && "Invalid operand for ADDItocL");
Craig Topper062a2ba2014-04-25 05:30:21 +0000811 MCSymbol *MOSymbol = nullptr;
Bill Schmidt34627e32012-11-27 17:35:46 +0000812
813 if (MO.isGlobal()) {
Rafael Espindola04902862014-05-29 15:41:38 +0000814 const GlobalValue *GV = MO.getGlobal();
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000815 LLVM_DEBUG(unsigned char GVFlags = Subtarget->classifyGlobalReference(GV);
816 assert(!(GVFlags & PPCII::MO_NLP_FLAG) &&
817 "Interposable definitions must use indirect access."));
Rafael Espindola04902862014-05-29 15:41:38 +0000818 MOSymbol = getSymbol(GV);
Eric Christopherc1808362015-11-20 20:51:31 +0000819 } else if (MO.isCPI()) {
Bill Schmidt34627e32012-11-27 17:35:46 +0000820 MOSymbol = GetCPISymbol(MO.getIndex());
Eric Christopherc1808362015-11-20 20:51:31 +0000821 }
Bill Schmidt34627e32012-11-27 17:35:46 +0000822
823 const MCExpr *Exp =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000824 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_TOC_LO,
Bill Schmidt34627e32012-11-27 17:35:46 +0000825 OutContext);
Jim Grosbache9119e42015-05-13 18:37:00 +0000826 TmpInst.getOperand(2) = MCOperand::createExpr(Exp);
Lang Hames9ff69c82015-04-24 19:11:51 +0000827 EmitToStreamer(*OutStreamer, TmpInst);
Bill Schmidt34627e32012-11-27 17:35:46 +0000828 return;
829 }
Bill Schmidt9f0b4ec2012-12-14 17:02:38 +0000830 case PPC::ADDISgotTprelHA: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000831 // Transform: %xd = ADDISgotTprelHA %x2, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000832 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
Eric Christopherd4986802015-02-10 00:44:17 +0000833 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
Bill Schmidt9f0b4ec2012-12-14 17:02:38 +0000834 const MachineOperand &MO = MI->getOperand(2);
835 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +0000836 MCSymbol *MOSymbol = getSymbol(GValue);
Bill Schmidt9f0b4ec2012-12-14 17:02:38 +0000837 const MCExpr *SymGotTprel =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000838 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA,
Bill Schmidt9f0b4ec2012-12-14 17:02:38 +0000839 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000840 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
841 .addReg(MI->getOperand(0).getReg())
842 .addReg(MI->getOperand(1).getReg())
843 .addExpr(SymGotTprel));
Bill Schmidt9f0b4ec2012-12-14 17:02:38 +0000844 return;
845 }
Roman Divacky32143e22013-12-20 18:08:54 +0000846 case PPC::LDgotTprelL:
847 case PPC::LDgotTprelL32: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000848 // Transform %xd = LDgotTprelL @sym, %xs
Justin Hibbitsa88b6052014-11-12 15:16:30 +0000849 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Bill Schmidtca4a0c92012-12-04 16:18:08 +0000850
Ulrich Weigand4a083882013-03-26 10:55:45 +0000851 // Change the opcode to LD.
Roman Divacky32143e22013-12-20 18:08:54 +0000852 TmpInst.setOpcode(isPPC64 ? PPC::LD : PPC::LWZ);
Bill Schmidtca4a0c92012-12-04 16:18:08 +0000853 const MachineOperand &MO = MI->getOperand(1);
854 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +0000855 MCSymbol *MOSymbol = getSymbol(GValue);
Bill Schmidtca4a0c92012-12-04 16:18:08 +0000856 const MCExpr *Exp =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000857 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO,
Bill Schmidtca4a0c92012-12-04 16:18:08 +0000858 OutContext);
Jim Grosbache9119e42015-05-13 18:37:00 +0000859 TmpInst.getOperand(1) = MCOperand::createExpr(Exp);
Lang Hames9ff69c82015-04-24 19:11:51 +0000860 EmitToStreamer(*OutStreamer, TmpInst);
Bill Schmidtca4a0c92012-12-04 16:18:08 +0000861 return;
862 }
Roman Divacky32143e22013-12-20 18:08:54 +0000863
Hal Finkel7c8ae532014-07-25 17:47:22 +0000864 case PPC::PPC32PICGOT: {
Jim Grosbach6f482002015-05-18 18:43:14 +0000865 MCSymbol *GOTSymbol = OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
866 MCSymbol *GOTRef = OutContext.createTempSymbol();
867 MCSymbol *NextInstr = OutContext.createTempSymbol();
Hal Finkel7c8ae532014-07-25 17:47:22 +0000868
Lang Hames9ff69c82015-04-24 19:11:51 +0000869 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::BL)
Hal Finkel7c8ae532014-07-25 17:47:22 +0000870 // FIXME: We would like an efficient form for this, so we don't have to do
871 // a lot of extra uniquing.
Jim Grosbach13760bd2015-05-30 01:25:56 +0000872 .addExpr(MCSymbolRefExpr::create(NextInstr, OutContext)));
Hal Finkel7c8ae532014-07-25 17:47:22 +0000873 const MCExpr *OffsExpr =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000874 MCBinaryExpr::createSub(MCSymbolRefExpr::create(GOTSymbol, OutContext),
875 MCSymbolRefExpr::create(GOTRef, OutContext),
Hal Finkel7c8ae532014-07-25 17:47:22 +0000876 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000877 OutStreamer->EmitLabel(GOTRef);
878 OutStreamer->EmitValue(OffsExpr, 4);
879 OutStreamer->EmitLabel(NextInstr);
880 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR)
881 .addReg(MI->getOperand(0).getReg()));
882 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LWZ)
883 .addReg(MI->getOperand(1).getReg())
884 .addImm(0)
885 .addReg(MI->getOperand(0).getReg()));
886 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD4)
887 .addReg(MI->getOperand(0).getReg())
888 .addReg(MI->getOperand(1).getReg())
889 .addReg(MI->getOperand(0).getReg()));
Hal Finkel7c8ae532014-07-25 17:47:22 +0000890 return;
891 }
Roman Divacky32143e22013-12-20 18:08:54 +0000892 case PPC::PPC32GOT: {
NAKAMURA Takumi70ad98a2015-09-22 11:13:55 +0000893 MCSymbol *GOTSymbol =
894 OutContext.getOrCreateSymbol(StringRef("_GLOBAL_OFFSET_TABLE_"));
895 const MCExpr *SymGotTlsL = MCSymbolRefExpr::create(
896 GOTSymbol, MCSymbolRefExpr::VK_PPC_LO, OutContext);
897 const MCExpr *SymGotTlsHA = MCSymbolRefExpr::create(
898 GOTSymbol, MCSymbolRefExpr::VK_PPC_HA, OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000899 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LI)
900 .addReg(MI->getOperand(0).getReg())
901 .addExpr(SymGotTlsL));
902 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
903 .addReg(MI->getOperand(0).getReg())
904 .addReg(MI->getOperand(0).getReg())
905 .addExpr(SymGotTlsHA));
Roman Divacky32143e22013-12-20 18:08:54 +0000906 return;
907 }
Bill Schmidtc56f1d32012-12-11 20:30:11 +0000908 case PPC::ADDIStlsgdHA: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000909 // Transform: %xd = ADDIStlsgdHA %x2, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000910 // Into: %xd = ADDIS8 %x2, sym@got@tlsgd@ha
Eric Christopherd4986802015-02-10 00:44:17 +0000911 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
Bill Schmidtc56f1d32012-12-11 20:30:11 +0000912 const MachineOperand &MO = MI->getOperand(2);
913 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +0000914 MCSymbol *MOSymbol = getSymbol(GValue);
Bill Schmidtc56f1d32012-12-11 20:30:11 +0000915 const MCExpr *SymGotTlsGD =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000916 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA,
Bill Schmidtc56f1d32012-12-11 20:30:11 +0000917 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000918 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
919 .addReg(MI->getOperand(0).getReg())
920 .addReg(MI->getOperand(1).getReg())
921 .addExpr(SymGotTlsGD));
Bill Schmidtc56f1d32012-12-11 20:30:11 +0000922 return;
923 }
Hal Finkel7c8ae532014-07-25 17:47:22 +0000924 case PPC::ADDItlsgdL:
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000925 // Transform: %xd = ADDItlsgdL %xs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000926 // Into: %xd = ADDI8 %xs, sym@got@tlsgd@l
Hal Finkel7c8ae532014-07-25 17:47:22 +0000927 case PPC::ADDItlsgdL32: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000928 // Transform: %rd = ADDItlsgdL32 %rs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000929 // Into: %rd = ADDI %rs, sym@got@tlsgd
Bill Schmidtc56f1d32012-12-11 20:30:11 +0000930 const MachineOperand &MO = MI->getOperand(2);
931 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +0000932 MCSymbol *MOSymbol = getSymbol(GValue);
Jim Grosbach13760bd2015-05-30 01:25:56 +0000933 const MCExpr *SymGotTlsGD = MCSymbolRefExpr::create(
Eric Christopherd4986802015-02-10 00:44:17 +0000934 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO
935 : MCSymbolRefExpr::VK_PPC_GOT_TLSGD,
936 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000937 EmitToStreamer(*OutStreamer,
Eric Christopherd4986802015-02-10 00:44:17 +0000938 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
Hal Finkel7c8ae532014-07-25 17:47:22 +0000939 .addReg(MI->getOperand(0).getReg())
940 .addReg(MI->getOperand(1).getReg())
941 .addExpr(SymGotTlsGD));
Bill Schmidtc56f1d32012-12-11 20:30:11 +0000942 return;
943 }
Bill Schmidt82f1c772015-02-10 19:09:05 +0000944 case PPC::GETtlsADDR:
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000945 // Transform: %x3 = GETtlsADDR %x3, @sym
Bill Schmidt82f1c772015-02-10 19:09:05 +0000946 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsgd)
947 case PPC::GETtlsADDR32: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000948 // Transform: %r3 = GETtlsADDR32 %r3, @sym
Bill Schmidt82f1c772015-02-10 19:09:05 +0000949 // Into: BL_TLS __tls_get_addr(sym at tlsgd)@PLT
950 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSGD);
951 return;
952 }
Bill Schmidt24b8dd62012-12-12 19:29:35 +0000953 case PPC::ADDIStlsldHA: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000954 // Transform: %xd = ADDIStlsldHA %x2, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000955 // Into: %xd = ADDIS8 %x2, sym@got@tlsld@ha
Eric Christopherd4986802015-02-10 00:44:17 +0000956 assert(Subtarget->isPPC64() && "Not supported for 32-bit PowerPC");
Bill Schmidt24b8dd62012-12-12 19:29:35 +0000957 const MachineOperand &MO = MI->getOperand(2);
958 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +0000959 MCSymbol *MOSymbol = getSymbol(GValue);
Bill Schmidt24b8dd62012-12-12 19:29:35 +0000960 const MCExpr *SymGotTlsLD =
Jim Grosbach13760bd2015-05-30 01:25:56 +0000961 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA,
Bill Schmidt24b8dd62012-12-12 19:29:35 +0000962 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000963 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS8)
964 .addReg(MI->getOperand(0).getReg())
965 .addReg(MI->getOperand(1).getReg())
966 .addExpr(SymGotTlsLD));
Bill Schmidt24b8dd62012-12-12 19:29:35 +0000967 return;
968 }
Hal Finkel7c8ae532014-07-25 17:47:22 +0000969 case PPC::ADDItlsldL:
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000970 // Transform: %xd = ADDItlsldL %xs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000971 // Into: %xd = ADDI8 %xs, sym@got@tlsld@l
Hal Finkel7c8ae532014-07-25 17:47:22 +0000972 case PPC::ADDItlsldL32: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000973 // Transform: %rd = ADDItlsldL32 %rs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000974 // Into: %rd = ADDI %rs, sym@got@tlsld
Bill Schmidt24b8dd62012-12-12 19:29:35 +0000975 const MachineOperand &MO = MI->getOperand(2);
976 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +0000977 MCSymbol *MOSymbol = getSymbol(GValue);
Jim Grosbach13760bd2015-05-30 01:25:56 +0000978 const MCExpr *SymGotTlsLD = MCSymbolRefExpr::create(
Eric Christopherd4986802015-02-10 00:44:17 +0000979 MOSymbol, Subtarget->isPPC64() ? MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO
980 : MCSymbolRefExpr::VK_PPC_GOT_TLSLD,
981 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +0000982 EmitToStreamer(*OutStreamer,
Eric Christopherd4986802015-02-10 00:44:17 +0000983 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
984 .addReg(MI->getOperand(0).getReg())
985 .addReg(MI->getOperand(1).getReg())
986 .addExpr(SymGotTlsLD));
Bill Schmidt24b8dd62012-12-12 19:29:35 +0000987 return;
988 }
Bill Schmidt82f1c772015-02-10 19:09:05 +0000989 case PPC::GETtlsldADDR:
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000990 // Transform: %x3 = GETtlsldADDR %x3, @sym
Bill Schmidt82f1c772015-02-10 19:09:05 +0000991 // Into: BL8_NOP_TLS __tls_get_addr(sym at tlsld)
992 case PPC::GETtlsldADDR32: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000993 // Transform: %r3 = GETtlsldADDR32 %r3, @sym
Bill Schmidt82f1c772015-02-10 19:09:05 +0000994 // Into: BL_TLS __tls_get_addr(sym at tlsld)@PLT
995 EmitTlsCall(MI, MCSymbolRefExpr::VK_PPC_TLSLD);
996 return;
997 }
Hal Finkel7c8ae532014-07-25 17:47:22 +0000998 case PPC::ADDISdtprelHA:
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +0000999 // Transform: %xd = ADDISdtprelHA %xs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00001000 // Into: %xd = ADDIS8 %xs, sym@dtprel@ha
Hal Finkel7c8ae532014-07-25 17:47:22 +00001001 case PPC::ADDISdtprelHA32: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +00001002 // Transform: %rd = ADDISdtprelHA32 %rs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00001003 // Into: %rd = ADDIS %rs, sym@dtprel@ha
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001004 const MachineOperand &MO = MI->getOperand(2);
1005 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +00001006 MCSymbol *MOSymbol = getSymbol(GValue);
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001007 const MCExpr *SymDtprel =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001008 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_HA,
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001009 OutContext);
Eric Christopherd4986802015-02-10 00:44:17 +00001010 EmitToStreamer(
Lang Hames9ff69c82015-04-24 19:11:51 +00001011 *OutStreamer,
Eric Christopherd4986802015-02-10 00:44:17 +00001012 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDIS8 : PPC::ADDIS)
1013 .addReg(MI->getOperand(0).getReg())
Hal Finkeld2fd9be2015-08-30 07:44:05 +00001014 .addReg(MI->getOperand(1).getReg())
Eric Christopherd4986802015-02-10 00:44:17 +00001015 .addExpr(SymDtprel));
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001016 return;
1017 }
Hal Finkel7c8ae532014-07-25 17:47:22 +00001018 case PPC::ADDIdtprelL:
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +00001019 // Transform: %xd = ADDIdtprelL %xs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00001020 // Into: %xd = ADDI8 %xs, sym@dtprel@l
Hal Finkel7c8ae532014-07-25 17:47:22 +00001021 case PPC::ADDIdtprelL32: {
Francis Visoiu Mistrih5df3bbf2017-12-14 10:03:09 +00001022 // Transform: %rd = ADDIdtprelL32 %rs, @sym
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00001023 // Into: %rd = ADDI %rs, sym@dtprel@l
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001024 const MachineOperand &MO = MI->getOperand(2);
1025 const GlobalValue *GValue = MO.getGlobal();
Rafael Espindola79858aa2013-10-29 17:07:16 +00001026 MCSymbol *MOSymbol = getSymbol(GValue);
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001027 const MCExpr *SymDtprel =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001028 MCSymbolRefExpr::create(MOSymbol, MCSymbolRefExpr::VK_PPC_DTPREL_LO,
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001029 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +00001030 EmitToStreamer(*OutStreamer,
Eric Christopherd4986802015-02-10 00:44:17 +00001031 MCInstBuilder(Subtarget->isPPC64() ? PPC::ADDI8 : PPC::ADDI)
1032 .addReg(MI->getOperand(0).getReg())
1033 .addReg(MI->getOperand(1).getReg())
1034 .addExpr(SymDtprel));
Bill Schmidt24b8dd62012-12-12 19:29:35 +00001035 return;
1036 }
Ulrich Weigandd5ebc622013-07-03 17:05:42 +00001037 case PPC::MFOCRF:
1038 case PPC::MFOCRF8:
Eric Christopherd4986802015-02-10 00:44:17 +00001039 if (!Subtarget->hasMFOCRF()) {
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00001040 // Transform: %r3 = MFOCRF %cr7
1041 // Into: %r3 = MFCR ;; cr7
Ulrich Weigandd5ebc622013-07-03 17:05:42 +00001042 unsigned NewOpcode =
1043 MI->getOpcode() == PPC::MFOCRF ? PPC::MFCR : PPC::MFCR8;
Lang Hames9ff69c82015-04-24 19:11:51 +00001044 OutStreamer->AddComment(PPCInstPrinter::
1045 getRegisterName(MI->getOperand(1).getReg()));
1046 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
Ulrich Weigandd5ebc622013-07-03 17:05:42 +00001047 .addReg(MI->getOperand(0).getReg()));
1048 return;
1049 }
1050 break;
Ulrich Weigand49f487e2013-07-03 17:59:07 +00001051 case PPC::MTOCRF:
1052 case PPC::MTOCRF8:
Eric Christopherd4986802015-02-10 00:44:17 +00001053 if (!Subtarget->hasMFOCRF()) {
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00001054 // Transform: %cr7 = MTOCRF %r3
1055 // Into: MTCRF mask, %r3 ;; cr7
Ulrich Weigand49f487e2013-07-03 17:59:07 +00001056 unsigned NewOpcode =
1057 MI->getOpcode() == PPC::MTOCRF ? PPC::MTCRF : PPC::MTCRF8;
1058 unsigned Mask = 0x80 >> OutContext.getRegisterInfo()
1059 ->getEncodingValue(MI->getOperand(0).getReg());
Lang Hames9ff69c82015-04-24 19:11:51 +00001060 OutStreamer->AddComment(PPCInstPrinter::
1061 getRegisterName(MI->getOperand(0).getReg()));
1062 EmitToStreamer(*OutStreamer, MCInstBuilder(NewOpcode)
1063 .addImm(Mask)
1064 .addReg(MI->getOperand(1).getReg()));
Ulrich Weigand49f487e2013-07-03 17:59:07 +00001065 return;
1066 }
1067 break;
Bill Schmidt48fc20a2013-07-01 20:52:27 +00001068 case PPC::LD:
1069 case PPC::STD:
Bill Schmidt8d86fe72013-08-30 15:18:11 +00001070 case PPC::LWA_32:
Bill Schmidt48fc20a2013-07-01 20:52:27 +00001071 case PPC::LWA: {
1072 // Verify alignment is legal, so we don't create relocations
1073 // that can't be supported.
1074 // FIXME: This test is currently disabled for Darwin. The test
1075 // suite shows a handful of test cases that fail this check for
1076 // Darwin. Those need to be investigated before this sanity test
1077 // can be enabled for those subtargets.
Eric Christopherd4986802015-02-10 00:44:17 +00001078 if (!Subtarget->isDarwin()) {
Bill Schmidt48fc20a2013-07-01 20:52:27 +00001079 unsigned OpNum = (MI->getOpcode() == PPC::STD) ? 2 : 1;
1080 const MachineOperand &MO = MI->getOperand(OpNum);
1081 if (MO.isGlobal() && MO.getGlobal()->getAlignment() < 4)
1082 llvm_unreachable("Global must be word-aligned for LD, STD, LWA!");
1083 }
1084 // Now process the instruction normally.
1085 break;
1086 }
Dale Johannesenbc41cfa2010-04-26 20:05:01 +00001087 }
Misha Brukmanb4402432005-04-21 23:30:14 +00001088
Justin Hibbitsa88b6052014-11-12 15:16:30 +00001089 LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, isDarwin);
Lang Hames9ff69c82015-04-24 19:11:51 +00001090 EmitToStreamer(*OutStreamer, TmpInst);
Misha Brukmane05203f2004-06-21 16:55:25 +00001091}
1092
Tim Shen918ed872017-02-10 21:03:24 +00001093void PPCLinuxAsmPrinter::EmitInstruction(const MachineInstr *MI) {
1094 if (!Subtarget->isPPC64())
1095 return PPCAsmPrinter::EmitInstruction(MI);
1096
1097 switch (MI->getOpcode()) {
1098 default:
1099 return PPCAsmPrinter::EmitInstruction(MI);
1100 case TargetOpcode::PATCHABLE_FUNCTION_ENTER: {
1101 // .begin:
1102 // b .end # lis 0, FuncId[16..32]
1103 // nop # li 0, FuncId[0..15]
1104 // std 0, -8(1)
1105 // mflr 0
1106 // bl __xray_FunctionEntry
1107 // mtlr 0
1108 // .end:
1109 //
1110 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1111 // of instructions change.
1112 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1113 MCSymbol *EndOfSled = OutContext.createTempSymbol();
1114 OutStreamer->EmitLabel(BeginOfSled);
1115 EmitToStreamer(*OutStreamer,
1116 MCInstBuilder(PPC::B).addExpr(
1117 MCSymbolRefExpr::create(EndOfSled, OutContext)));
1118 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1119 EmitToStreamer(
1120 *OutStreamer,
1121 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1122 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1123 EmitToStreamer(*OutStreamer,
1124 MCInstBuilder(PPC::BL8_NOP)
1125 .addExpr(MCSymbolRefExpr::create(
1126 OutContext.getOrCreateSymbol("__xray_FunctionEntry"),
1127 OutContext)));
1128 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
1129 OutStreamer->EmitLabel(EndOfSled);
1130 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_ENTER);
1131 break;
1132 }
Tim Shencee75362017-09-22 18:30:02 +00001133 case TargetOpcode::PATCHABLE_RET: {
1134 unsigned RetOpcode = MI->getOperand(0).getImm();
1135 MCInst RetInst;
1136 RetInst.setOpcode(RetOpcode);
1137 for (const auto &MO :
1138 make_range(std::next(MI->operands_begin()), MI->operands_end())) {
1139 MCOperand MCOp;
1140 if (LowerPPCMachineOperandToMCOperand(MO, MCOp, *this, false))
1141 RetInst.addOperand(MCOp);
1142 }
1143
1144 bool IsConditional;
1145 if (RetOpcode == PPC::BCCLR) {
1146 IsConditional = true;
1147 } else if (RetOpcode == PPC::TCRETURNdi8 || RetOpcode == PPC::TCRETURNri8 ||
1148 RetOpcode == PPC::TCRETURNai8) {
1149 break;
1150 } else if (RetOpcode == PPC::BLR8 || RetOpcode == PPC::TAILB8) {
1151 IsConditional = false;
1152 } else {
1153 EmitToStreamer(*OutStreamer, RetInst);
1154 break;
1155 }
1156
1157 MCSymbol *FallthroughLabel;
1158 if (IsConditional) {
1159 // Before:
1160 // bgtlr cr0
1161 //
1162 // After:
1163 // ble cr0, .end
1164 // .p2align 3
1165 // .begin:
1166 // blr # lis 0, FuncId[16..32]
1167 // nop # li 0, FuncId[0..15]
1168 // std 0, -8(1)
1169 // mflr 0
1170 // bl __xray_FunctionExit
1171 // mtlr 0
1172 // blr
1173 // .end:
1174 //
1175 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1176 // of instructions change.
1177 FallthroughLabel = OutContext.createTempSymbol();
1178 EmitToStreamer(
1179 *OutStreamer,
1180 MCInstBuilder(PPC::BCC)
1181 .addImm(PPC::InvertPredicate(
1182 static_cast<PPC::Predicate>(MI->getOperand(1).getImm())))
1183 .addReg(MI->getOperand(2).getReg())
1184 .addExpr(MCSymbolRefExpr::create(FallthroughLabel, OutContext)));
1185 RetInst = MCInst();
1186 RetInst.setOpcode(PPC::BLR8);
1187 }
Tim Shen918ed872017-02-10 21:03:24 +00001188 // .p2align 3
1189 // .begin:
1190 // b(lr)? # lis 0, FuncId[16..32]
1191 // nop # li 0, FuncId[0..15]
1192 // std 0, -8(1)
1193 // mflr 0
1194 // bl __xray_FunctionExit
1195 // mtlr 0
Tim Shen918ed872017-02-10 21:03:24 +00001196 // b(lr)?
1197 //
1198 // Update compiler-rt/lib/xray/xray_powerpc64.cc accordingly when number
1199 // of instructions change.
Tim Shen918ed872017-02-10 21:03:24 +00001200 OutStreamer->EmitCodeAlignment(8);
1201 MCSymbol *BeginOfSled = OutContext.createTempSymbol();
1202 OutStreamer->EmitLabel(BeginOfSled);
Tim Shencee75362017-09-22 18:30:02 +00001203 EmitToStreamer(*OutStreamer, RetInst);
Tim Shen918ed872017-02-10 21:03:24 +00001204 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::NOP));
1205 EmitToStreamer(
1206 *OutStreamer,
1207 MCInstBuilder(PPC::STD).addReg(PPC::X0).addImm(-8).addReg(PPC::X1));
1208 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MFLR8).addReg(PPC::X0));
1209 EmitToStreamer(*OutStreamer,
1210 MCInstBuilder(PPC::BL8_NOP)
1211 .addExpr(MCSymbolRefExpr::create(
1212 OutContext.getOrCreateSymbol("__xray_FunctionExit"),
1213 OutContext)));
1214 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::MTLR8).addReg(PPC::X0));
Tim Shencee75362017-09-22 18:30:02 +00001215 EmitToStreamer(*OutStreamer, RetInst);
1216 if (IsConditional)
1217 OutStreamer->EmitLabel(FallthroughLabel);
Tim Shen918ed872017-02-10 21:03:24 +00001218 recordSled(BeginOfSled, *MI, SledKind::FUNCTION_EXIT);
1219 break;
1220 }
Tim Shencee75362017-09-22 18:30:02 +00001221 case TargetOpcode::PATCHABLE_FUNCTION_EXIT:
1222 llvm_unreachable("PATCHABLE_FUNCTION_EXIT should never be emitted");
Tim Shen918ed872017-02-10 21:03:24 +00001223 case TargetOpcode::PATCHABLE_TAIL_CALL:
Dean Michael Berris711dec22017-09-08 01:47:56 +00001224 // TODO: Define a trampoline `__xray_FunctionTailExit` and differentiate a
1225 // normal function exit from a tail exit.
Tim Shencee75362017-09-22 18:30:02 +00001226 llvm_unreachable("Tail call is handled in the normal case. See comments "
Tim Shen21a960b2017-02-10 21:17:35 +00001227 "around this assert.");
Tim Shen918ed872017-02-10 21:03:24 +00001228 }
1229}
1230
Hal Finkel3ee2af72014-07-18 23:29:49 +00001231void PPCLinuxAsmPrinter::EmitStartOfAsmFile(Module &M) {
Eric Christopher5c0e0092015-02-17 07:21:21 +00001232 if (static_cast<const PPCTargetMachine &>(TM).isELFv2ABI()) {
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001233 PPCTargetStreamer *TS =
Lang Hames9ff69c82015-04-24 19:11:51 +00001234 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001235
1236 if (TS)
1237 TS->emitAbiVersion(2);
1238 }
1239
Eric Christopher5c0e0092015-02-17 07:21:21 +00001240 if (static_cast<const PPCTargetMachine &>(TM).isPPC64() ||
Rafael Espindola0db11db2016-06-27 14:19:45 +00001241 !isPositionIndependent())
Hal Finkel3ee2af72014-07-18 23:29:49 +00001242 return AsmPrinter::EmitStartOfAsmFile(M);
1243
Davide Italiano4cccc482016-06-17 18:07:14 +00001244 if (M.getPICLevel() == PICLevel::SmallPIC)
Justin Hibbitsa88b6052014-11-12 15:16:30 +00001245 return AsmPrinter::EmitStartOfAsmFile(M);
1246
Lang Hames9ff69c82015-04-24 19:11:51 +00001247 OutStreamer->SwitchSection(OutContext.getELFSection(
Rafael Espindolaba31e272015-01-29 17:33:21 +00001248 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC));
Hal Finkel3ee2af72014-07-18 23:29:49 +00001249
Jim Grosbach6f482002015-05-18 18:43:14 +00001250 MCSymbol *TOCSym = OutContext.getOrCreateSymbol(Twine(".LTOC"));
1251 MCSymbol *CurrentPos = OutContext.createTempSymbol();
Hal Finkel3ee2af72014-07-18 23:29:49 +00001252
Lang Hames9ff69c82015-04-24 19:11:51 +00001253 OutStreamer->EmitLabel(CurrentPos);
Hal Finkel3ee2af72014-07-18 23:29:49 +00001254
1255 // The GOT pointer points to the middle of the GOT, in order to reference the
1256 // entire 64kB range. 0x8000 is the midpoint.
1257 const MCExpr *tocExpr =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001258 MCBinaryExpr::createAdd(MCSymbolRefExpr::create(CurrentPos, OutContext),
1259 MCConstantExpr::create(0x8000, OutContext),
Hal Finkel3ee2af72014-07-18 23:29:49 +00001260 OutContext);
1261
Lang Hames9ff69c82015-04-24 19:11:51 +00001262 OutStreamer->EmitAssignment(TOCSym, tocExpr);
Hal Finkel3ee2af72014-07-18 23:29:49 +00001263
Lang Hames9ff69c82015-04-24 19:11:51 +00001264 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
Hal Finkel3ee2af72014-07-18 23:29:49 +00001265}
1266
Chris Lattnerbc1e6f02010-01-27 07:21:55 +00001267void PPCLinuxAsmPrinter::EmitFunctionEntryLabel() {
Hal Finkel3ee2af72014-07-18 23:29:49 +00001268 // linux/ppc32 - Normal entry label.
NAKAMURA Takumi10c80e72015-09-22 11:19:03 +00001269 if (!Subtarget->isPPC64() &&
Rafael Espindola0db11db2016-06-27 14:19:45 +00001270 (!isPositionIndependent() ||
Matthias Braunf1caa282017-12-15 22:22:58 +00001271 MF->getFunction().getParent()->getPICLevel() == PICLevel::SmallPIC))
Chris Lattnerbc1e6f02010-01-27 07:21:55 +00001272 return AsmPrinter::EmitFunctionEntryLabel();
Hal Finkel3ee2af72014-07-18 23:29:49 +00001273
Eric Christopherd4986802015-02-10 00:44:17 +00001274 if (!Subtarget->isPPC64()) {
Hal Finkel3ee2af72014-07-18 23:29:49 +00001275 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
Strahinja Petrovic06cf6a62018-03-27 11:23:53 +00001276 if (PPCFI->usesPICBase() && !Subtarget->isSecurePlt()) {
Hal Finkel3ee2af72014-07-18 23:29:49 +00001277 MCSymbol *RelocSymbol = PPCFI->getPICOffsetSymbol();
1278 MCSymbol *PICBase = MF->getPICBaseSymbol();
Lang Hames9ff69c82015-04-24 19:11:51 +00001279 OutStreamer->EmitLabel(RelocSymbol);
Hal Finkel3ee2af72014-07-18 23:29:49 +00001280
1281 const MCExpr *OffsExpr =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001282 MCBinaryExpr::createSub(
1283 MCSymbolRefExpr::create(OutContext.getOrCreateSymbol(Twine(".LTOC")),
Hal Finkel3ee2af72014-07-18 23:29:49 +00001284 OutContext),
Jim Grosbach13760bd2015-05-30 01:25:56 +00001285 MCSymbolRefExpr::create(PICBase, OutContext),
Hal Finkel3ee2af72014-07-18 23:29:49 +00001286 OutContext);
Lang Hames9ff69c82015-04-24 19:11:51 +00001287 OutStreamer->EmitValue(OffsExpr, 4);
1288 OutStreamer->EmitLabel(CurrentFnSym);
Hal Finkel3ee2af72014-07-18 23:29:49 +00001289 return;
1290 } else
1291 return AsmPrinter::EmitFunctionEntryLabel();
1292 }
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001293
1294 // ELFv2 ABI - Normal entry label.
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001295 if (Subtarget->isELFv2ABI()) {
1296 // In the Large code model, we allow arbitrary displacements between
1297 // the text section and its associated TOC section. We place the
Hiroshi Inoue0f7f59f2018-06-13 08:54:13 +00001298 // full 8-byte offset to the TOC in memory immediately preceding
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001299 // the function global entry point.
1300 if (TM.getCodeModel() == CodeModel::Large
1301 && !MF->getRegInfo().use_empty(PPC::X2)) {
1302 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
1303
1304 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1305 MCSymbol *GlobalEPSymbol = PPCFI->getGlobalEPSymbol();
1306 const MCExpr *TOCDeltaExpr =
1307 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1308 MCSymbolRefExpr::create(GlobalEPSymbol,
1309 OutContext),
1310 OutContext);
1311
1312 OutStreamer->EmitLabel(PPCFI->getTOCOffsetSymbol());
1313 OutStreamer->EmitValue(TOCDeltaExpr, 8);
1314 }
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001315 return AsmPrinter::EmitFunctionEntryLabel();
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001316 }
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001317
Chris Lattnerbc1e6f02010-01-27 07:21:55 +00001318 // Emit an official procedure descriptor.
Lang Hames9ff69c82015-04-24 19:11:51 +00001319 MCSectionSubPair Current = OutStreamer->getCurrentSection();
Rafael Espindola0709a7b2015-05-21 19:20:38 +00001320 MCSectionELF *Section = OutStreamer->getContext().getELFSection(
Rafael Espindolaba31e272015-01-29 17:33:21 +00001321 ".opd", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
Lang Hames9ff69c82015-04-24 19:11:51 +00001322 OutStreamer->SwitchSection(Section);
1323 OutStreamer->EmitLabel(CurrentFnSym);
1324 OutStreamer->EmitValueToAlignment(8);
Rafael Espindola092b6192015-03-05 19:47:50 +00001325 MCSymbol *Symbol1 = CurrentFnSymForSize;
Adhemerval Zanellaf2aceda2012-10-25 12:27:42 +00001326 // Generates a R_PPC64_ADDR64 (from FK_DATA_8) relocation for the function
1327 // entry point.
Jim Grosbach13760bd2015-05-30 01:25:56 +00001328 OutStreamer->EmitValue(MCSymbolRefExpr::create(Symbol1, OutContext),
Lang Hames9ff69c82015-04-24 19:11:51 +00001329 8 /*size*/);
Jim Grosbach6f482002015-05-18 18:43:14 +00001330 MCSymbol *Symbol2 = OutContext.getOrCreateSymbol(StringRef(".TOC."));
Adhemerval Zanellaf2aceda2012-10-25 12:27:42 +00001331 // Generates a R_PPC64_TOC relocation for TOC base insertion.
Lang Hames9ff69c82015-04-24 19:11:51 +00001332 OutStreamer->EmitValue(
Jim Grosbach13760bd2015-05-30 01:25:56 +00001333 MCSymbolRefExpr::create(Symbol2, MCSymbolRefExpr::VK_PPC_TOCBASE, OutContext),
Lang Hames9ff69c82015-04-24 19:11:51 +00001334 8/*size*/);
Roman Divackyd4f6f422012-09-18 16:55:29 +00001335 // Emit a null environment pointer.
Lang Hames9ff69c82015-04-24 19:11:51 +00001336 OutStreamer->EmitIntValue(0, 8 /* size */);
1337 OutStreamer->SwitchSection(Current.first, Current.second);
Chris Lattnerbc1e6f02010-01-27 07:21:55 +00001338}
1339
Tilmann Schellerd1aaa322009-08-15 11:54:46 +00001340bool PPCLinuxAsmPrinter::doFinalization(Module &M) {
Mehdi Aminibd7287e2015-07-16 06:11:10 +00001341 const DataLayout &DL = getDataLayout();
Tilmann Schellerd1aaa322009-08-15 11:54:46 +00001342
Mehdi Aminibd7287e2015-07-16 06:11:10 +00001343 bool isPPC64 = DL.getPointerSizeInBits() == 64;
Tilmann Schellerd1aaa322009-08-15 11:54:46 +00001344
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001345 PPCTargetStreamer &TS =
Lang Hames9ff69c82015-04-24 19:11:51 +00001346 static_cast<PPCTargetStreamer &>(*OutStreamer->getTargetStreamer());
Rafael Espindolaa17151a2013-10-08 13:08:17 +00001347
Hal Finkel3ee2af72014-07-18 23:29:49 +00001348 if (!TOC.empty()) {
Rafael Espindola0709a7b2015-05-21 19:20:38 +00001349 MCSectionELF *Section;
1350
Hal Finkel3ee2af72014-07-18 23:29:49 +00001351 if (isPPC64)
Lang Hames9ff69c82015-04-24 19:11:51 +00001352 Section = OutStreamer->getContext().getELFSection(
Rafael Espindolaba31e272015-01-29 17:33:21 +00001353 ".toc", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
1354 else
Lang Hames9ff69c82015-04-24 19:11:51 +00001355 Section = OutStreamer->getContext().getELFSection(
Rafael Espindolaba31e272015-01-29 17:33:21 +00001356 ".got2", ELF::SHT_PROGBITS, ELF::SHF_WRITE | ELF::SHF_ALLOC);
Lang Hames9ff69c82015-04-24 19:11:51 +00001357 OutStreamer->SwitchSection(Section);
Tilmann Schellerd1aaa322009-08-15 11:54:46 +00001358
Ulrich Weigand2c93acd2012-11-12 19:13:24 +00001359 for (MapVector<MCSymbol*, MCSymbol*>::iterator I = TOC.begin(),
Chris Lattner3d571ff2010-01-16 02:09:06 +00001360 E = TOC.end(); I != E; ++I) {
Lang Hames9ff69c82015-04-24 19:11:51 +00001361 OutStreamer->EmitLabel(I->second);
Ulrich Weigandc8c2ea22014-10-31 10:33:14 +00001362 MCSymbol *S = I->first;
Hal Finkel18d0e3f42016-08-30 01:43:38 +00001363 if (isPPC64) {
Hal Finkel3ee2af72014-07-18 23:29:49 +00001364 TS.emitTCEntry(*S);
Hal Finkel18d0e3f42016-08-30 01:43:38 +00001365 } else {
1366 OutStreamer->EmitValueToAlignment(4);
Lang Hames9ff69c82015-04-24 19:11:51 +00001367 OutStreamer->EmitSymbolValue(S, 4);
Hal Finkel18d0e3f42016-08-30 01:43:38 +00001368 }
Tilmann Schellerd1aaa322009-08-15 11:54:46 +00001369 }
1370 }
1371
1372 return AsmPrinter::doFinalization(M);
1373}
Jim Laskey28663c72006-12-21 20:26:09 +00001374
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001375/// EmitFunctionBodyStart - Emit a global entry point prefix for ELFv2.
1376void PPCLinuxAsmPrinter::EmitFunctionBodyStart() {
1377 // In the ELFv2 ABI, in functions that use the TOC register, we need to
1378 // provide two entry points. The ABI guarantees that when calling the
1379 // local entry point, r2 is set up by the caller to contain the TOC base
1380 // for this function, and when calling the global entry point, r12 is set
1381 // up by the caller to hold the address of the global entry point. We
1382 // thus emit a prefix sequence along the following lines:
1383 //
1384 // func:
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001385 // .Lfunc_gepNN:
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001386 // # global entry point
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001387 // addis r2,r12,(.TOC.-.Lfunc_gepNN)@ha
1388 // addi r2,r2,(.TOC.-.Lfunc_gepNN)@l
1389 // .Lfunc_lepNN:
1390 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
1391 // # local entry point, followed by function body
1392 //
1393 // For the Large code model, we create
1394 //
1395 // .Lfunc_tocNN:
1396 // .quad .TOC.-.Lfunc_gepNN # done by EmitFunctionEntryLabel
1397 // func:
1398 // .Lfunc_gepNN:
1399 // # global entry point
1400 // ld r2,.Lfunc_tocNN-.Lfunc_gepNN(r12)
1401 // add r2,r2,r12
1402 // .Lfunc_lepNN:
1403 // .localentry func, .Lfunc_lepNN-.Lfunc_gepNN
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001404 // # local entry point, followed by function body
1405 //
1406 // This ensures we have r2 set up correctly while executing the function
1407 // body, no matter which entry point is called.
Eric Christopherd4986802015-02-10 00:44:17 +00001408 if (Subtarget->isELFv2ABI()
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001409 // Only do all that if the function uses r2 in the first place.
1410 && !MF->getRegInfo().use_empty(PPC::X2)) {
Hal Finkel530fa5f2016-10-03 04:06:44 +00001411 // Note: The logic here must be synchronized with the code in the
1412 // branch-selection pass which sets the offset of the first block in the
1413 // function. This matters because it affects the alignment.
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001414 const PPCFunctionInfo *PPCFI = MF->getInfo<PPCFunctionInfo>();
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001415
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001416 MCSymbol *GlobalEntryLabel = PPCFI->getGlobalEPSymbol();
Lang Hames9ff69c82015-04-24 19:11:51 +00001417 OutStreamer->EmitLabel(GlobalEntryLabel);
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001418 const MCSymbolRefExpr *GlobalEntryLabelExp =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001419 MCSymbolRefExpr::create(GlobalEntryLabel, OutContext);
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001420
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001421 if (TM.getCodeModel() != CodeModel::Large) {
1422 MCSymbol *TOCSymbol = OutContext.getOrCreateSymbol(StringRef(".TOC."));
1423 const MCExpr *TOCDeltaExpr =
1424 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCSymbol, OutContext),
1425 GlobalEntryLabelExp, OutContext);
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001426
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001427 const MCExpr *TOCDeltaHi =
1428 PPCMCExpr::createHa(TOCDeltaExpr, false, OutContext);
1429 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDIS)
1430 .addReg(PPC::X2)
1431 .addReg(PPC::X12)
1432 .addExpr(TOCDeltaHi));
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001433
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001434 const MCExpr *TOCDeltaLo =
1435 PPCMCExpr::createLo(TOCDeltaExpr, false, OutContext);
1436 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADDI)
1437 .addReg(PPC::X2)
1438 .addReg(PPC::X2)
1439 .addExpr(TOCDeltaLo));
1440 } else {
1441 MCSymbol *TOCOffset = PPCFI->getTOCOffsetSymbol();
1442 const MCExpr *TOCOffsetDeltaExpr =
1443 MCBinaryExpr::createSub(MCSymbolRefExpr::create(TOCOffset, OutContext),
1444 GlobalEntryLabelExp, OutContext);
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001445
Ulrich Weigand46ff7ec2016-01-13 13:12:23 +00001446 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::LD)
1447 .addReg(PPC::X2)
1448 .addExpr(TOCOffsetDeltaExpr)
1449 .addReg(PPC::X12));
1450 EmitToStreamer(*OutStreamer, MCInstBuilder(PPC::ADD8)
1451 .addReg(PPC::X2)
1452 .addReg(PPC::X2)
1453 .addReg(PPC::X12));
1454 }
1455
1456 MCSymbol *LocalEntryLabel = PPCFI->getLocalEPSymbol();
Lang Hames9ff69c82015-04-24 19:11:51 +00001457 OutStreamer->EmitLabel(LocalEntryLabel);
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001458 const MCSymbolRefExpr *LocalEntryLabelExp =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001459 MCSymbolRefExpr::create(LocalEntryLabel, OutContext);
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001460 const MCExpr *LocalOffsetExp =
Jim Grosbach13760bd2015-05-30 01:25:56 +00001461 MCBinaryExpr::createSub(LocalEntryLabelExp,
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001462 GlobalEntryLabelExp, OutContext);
1463
1464 PPCTargetStreamer *TS =
Lang Hames9ff69c82015-04-24 19:11:51 +00001465 static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001466
1467 if (TS)
Rafael Espindola95fb9b92015-06-02 20:38:46 +00001468 TS->emitLocalEntry(cast<MCSymbolELF>(CurrentFnSym), LocalOffsetExp);
Ulrich Weigandaa0ac4f2014-07-20 23:31:44 +00001469 }
1470}
1471
Roman Divacky8c4b6a32012-08-28 19:06:55 +00001472/// EmitFunctionBodyEnd - Print the traceback table before the .size
1473/// directive.
1474///
1475void PPCLinuxAsmPrinter::EmitFunctionBodyEnd() {
1476 // Only the 64-bit target requires a traceback table. For now,
1477 // we only emit the word of zeroes that GDB requires to find
Hal Finkel1859d262012-08-29 20:22:24 +00001478 // the end of the function, and zeroes for the eight-byte
1479 // mandatory fields.
1480 // FIXME: We should fill in the eight-byte mandatory fields as described in
1481 // the PPC64 ELF ABI (this is a low-priority item because GDB does not
1482 // currently make use of these fields).
Eric Christopherd4986802015-02-10 00:44:17 +00001483 if (Subtarget->isPPC64()) {
Lang Hames9ff69c82015-04-24 19:11:51 +00001484 OutStreamer->EmitIntValue(0, 4/*size*/);
1485 OutStreamer->EmitIntValue(0, 8/*size*/);
Hal Finkel1859d262012-08-29 20:22:24 +00001486 }
Roman Divacky8c4b6a32012-08-28 19:06:55 +00001487}
1488
Bob Wilsonb633d7a2009-09-30 22:06:26 +00001489void PPCDarwinAsmPrinter::EmitStartOfAsmFile(Module &M) {
Dan Gohmanbdc24ad2008-03-25 21:45:14 +00001490 static const char *const CPUDirectives[] = {
Dale Johannesen6ca3ccf2008-02-14 23:35:16 +00001491 "",
Jim Laskey59e7a772006-12-12 20:57:08 +00001492 "ppc",
Hal Finkel6fa56972011-10-17 04:03:49 +00001493 "ppc440",
Jim Laskey59e7a772006-12-12 20:57:08 +00001494 "ppc601",
1495 "ppc602",
1496 "ppc603",
1497 "ppc7400",
1498 "ppc750",
1499 "ppc970",
Hal Finkel9f9f8922012-04-01 19:22:40 +00001500 "ppcA2",
Justin Hibbitsceb3cd92018-07-18 04:24:49 +00001501 "ppce500",
Hal Finkel742b5352012-08-28 16:12:39 +00001502 "ppce500mc",
1503 "ppce5500",
NAKAMURA Takumi3d591ae02013-02-04 00:47:33 +00001504 "power3",
1505 "power4",
1506 "power5",
1507 "power5x",
Hal Finkelf2b9c382012-06-11 15:43:08 +00001508 "power6",
NAKAMURA Takumi3d591ae02013-02-04 00:47:33 +00001509 "power6x",
Hal Finkelf2b9c382012-06-11 15:43:08 +00001510 "power7",
Nemanja Ivanovic6e29baf2016-05-09 18:54:58 +00001511 // FIXME: why is power8 missing here?
Bill Schmidt0a9170d2013-07-26 01:35:43 +00001512 "ppc64",
Nemanja Ivanovic6e29baf2016-05-09 18:54:58 +00001513 "ppc64le",
1514 "power9"
Jim Laskey59e7a772006-12-12 20:57:08 +00001515 };
1516
Eric Christopher5c0e0092015-02-17 07:21:21 +00001517 // Get the numerically largest directive.
1518 // FIXME: How should we merge darwin directives?
1519 unsigned Directive = PPC::DIR_NONE;
1520 for (const Function &F : M) {
Eric Christopher1947a9e22015-02-20 07:32:59 +00001521 const PPCSubtarget &STI = TM.getSubtarget<PPCSubtarget>(F);
Eric Christopher5c0e0092015-02-17 07:21:21 +00001522 unsigned FDir = STI.getDarwinDirective();
1523 Directive = Directive > FDir ? FDir : STI.getDarwinDirective();
1524 if (STI.hasMFOCRF() && Directive < PPC::DIR_970)
1525 Directive = PPC::DIR_970;
1526 if (STI.hasAltivec() && Directive < PPC::DIR_7400)
1527 Directive = PPC::DIR_7400;
1528 if (STI.isPPC64() && Directive < PPC::DIR_64)
1529 Directive = PPC::DIR_64;
1530 }
1531
Jim Laskey59e7a772006-12-12 20:57:08 +00001532 assert(Directive <= PPC::DIR_64 && "Directive out of range.");
Rafael Espindola6b9ee9b2014-01-25 02:35:56 +00001533
1534 assert(Directive < array_lengthof(CPUDirectives) &&
1535 "CPUDirectives[] might not be up-to-date!");
1536 PPCTargetStreamer &TStreamer =
Lang Hames9ff69c82015-04-24 19:11:51 +00001537 *static_cast<PPCTargetStreamer *>(OutStreamer->getTargetStreamer());
Rafael Espindola6b9ee9b2014-01-25 02:35:56 +00001538 TStreamer.emitMachine(CPUDirectives[Directive]);
Anton Korobeynikov7c20ede2008-08-08 18:22:59 +00001539
Jim Laskeyec05b042006-11-28 18:21:52 +00001540 // Prime text sections so they are adjacent. This reduces the likelihood a
1541 // large data or debug section causes a branch to exceed 16M limit.
NAKAMURA Takumi70ad98a2015-09-22 11:13:55 +00001542 const TargetLoweringObjectFileMachO &TLOFMacho =
1543 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
Lang Hames9ff69c82015-04-24 19:11:51 +00001544 OutStreamer->SwitchSection(TLOFMacho.getTextCoalSection());
Jim Laskeyec05b042006-11-28 18:21:52 +00001545 if (TM.getRelocationModel() == Reloc::PIC_) {
Lang Hames9ff69c82015-04-24 19:11:51 +00001546 OutStreamer->SwitchSection(
Chris Lattner433d4062010-04-08 20:40:11 +00001547 OutContext.getMachOSection("__TEXT", "__picsymbolstub1",
David Majnemer7b583052014-03-07 07:36:05 +00001548 MachO::S_SYMBOL_STUBS |
1549 MachO::S_ATTR_PURE_INSTRUCTIONS,
Chris Lattner4b7dadb2009-08-19 05:49:37 +00001550 32, SectionKind::getText()));
Jim Laskeyec05b042006-11-28 18:21:52 +00001551 } else if (TM.getRelocationModel() == Reloc::DynamicNoPIC) {
Lang Hames9ff69c82015-04-24 19:11:51 +00001552 OutStreamer->SwitchSection(
Chris Lattner433d4062010-04-08 20:40:11 +00001553 OutContext.getMachOSection("__TEXT","__symbol_stub1",
David Majnemer7b583052014-03-07 07:36:05 +00001554 MachO::S_SYMBOL_STUBS |
1555 MachO::S_ATTR_PURE_INSTRUCTIONS,
Chris Lattner4b7dadb2009-08-19 05:49:37 +00001556 16, SectionKind::getText()));
Jim Laskeyec05b042006-11-28 18:21:52 +00001557 }
Lang Hames9ff69c82015-04-24 19:11:51 +00001558 OutStreamer->SwitchSection(getObjFileLowering().getTextSection());
Nate Begeman15527112005-07-21 01:25:49 +00001559}
1560
Chris Lattner2f7c2792010-01-20 21:19:44 +00001561bool PPCDarwinAsmPrinter::doFinalization(Module &M) {
Mehdi Aminibd7287e2015-07-16 06:11:10 +00001562 bool isPPC64 = getDataLayout().getPointerSizeInBits() == 64;
Chris Lattner2f7c2792010-01-20 21:19:44 +00001563
1564 // Darwin/PPC always uses mach-o.
NAKAMURA Takumi70ad98a2015-09-22 11:13:55 +00001565 const TargetLoweringObjectFileMachO &TLOFMacho =
1566 static_cast<const TargetLoweringObjectFileMachO &>(getObjFileLowering());
Chandler Carruth651f0192016-11-03 23:33:46 +00001567 if (MMI) {
1568 MachineModuleInfoMachO &MMIMacho =
1569 MMI->getObjFileInfo<MachineModuleInfoMachO>();
NAKAMURA Takumi70ad98a2015-09-22 11:13:55 +00001570
Chandler Carruth651f0192016-11-03 23:33:46 +00001571 if (MAI->doesSupportExceptionHandling()) {
1572 // Add the (possibly multiple) personalities to the set of global values.
1573 // Only referenced functions get into the Personalities list.
1574 for (const Function *Personality : MMI->getPersonalities()) {
1575 if (Personality) {
1576 MCSymbol *NLPSym =
1577 getSymbolWithGlobalValueBase(Personality, "$non_lazy_ptr");
1578 MachineModuleInfoImpl::StubValueTy &StubSym =
1579 MMIMacho.getGVStubEntry(NLPSym);
1580 StubSym =
1581 MachineModuleInfoImpl::StubValueTy(getSymbol(Personality), true);
1582 }
Chris Lattner1ff47942010-01-20 21:16:14 +00001583 }
Chris Lattner9ffa4e22009-07-15 01:14:44 +00001584 }
Dale Johannesen763e1102007-11-20 23:24:42 +00001585
Chandler Carruth651f0192016-11-03 23:33:46 +00001586 // Output stubs for dynamically-linked functions.
1587 MachineModuleInfoMachO::SymbolListTy Stubs = MMIMacho.GetGVStubList();
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +00001588
Chandler Carruth651f0192016-11-03 23:33:46 +00001589 // Output macho stubs for external and common global variables.
1590 if (!Stubs.empty()) {
1591 // Switch with ".non_lazy_symbol_pointer" directive.
1592 OutStreamer->SwitchSection(TLOFMacho.getNonLazySymbolPointerSection());
1593 EmitAlignment(isPPC64 ? 3 : 2);
NAKAMURA Takumia9cb5382015-09-22 11:14:39 +00001594
Chandler Carruth651f0192016-11-03 23:33:46 +00001595 for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
1596 // L_foo$stub:
1597 OutStreamer->EmitLabel(Stubs[i].first);
1598 // .indirect_symbol _foo
1599 MachineModuleInfoImpl::StubValueTy &MCSym = Stubs[i].second;
1600 OutStreamer->EmitSymbolAttribute(MCSym.getPointer(),
1601 MCSA_IndirectSymbol);
Bill Wendlingdd3fe942010-03-12 02:00:43 +00001602
Chandler Carruth651f0192016-11-03 23:33:46 +00001603 if (MCSym.getInt())
1604 // External to current translation unit.
1605 OutStreamer->EmitIntValue(0, isPPC64 ? 8 : 4 /*size*/);
1606 else
1607 // Internal to current translation unit.
1608 //
1609 // When we place the LSDA into the TEXT section, the type info
1610 // pointers
1611 // need to be indirect and pc-rel. We accomplish this by using NLPs.
1612 // However, sometimes the types are local to the file. So we need to
1613 // fill in the value for the NLP in those cases.
1614 OutStreamer->EmitValue(
1615 MCSymbolRefExpr::create(MCSym.getPointer(), OutContext),
1616 isPPC64 ? 8 : 4 /*size*/);
1617 }
1618
1619 Stubs.clear();
1620 OutStreamer->AddBlankLine();
Chris Lattner54a11df2005-12-13 04:33:58 +00001621 }
Nate Begeman0ad7f812004-08-14 22:09:10 +00001622 }
Misha Brukmanb4402432005-04-21 23:30:14 +00001623
Chris Lattner7432ceef2005-11-01 00:12:36 +00001624 // Funny Darwin hack: This flag tells the linker that no global symbols
1625 // contain code that falls through to other global symbols (e.g. the obvious
1626 // implementation of multiple entry points). If this doesn't occur, the
1627 // linker can safely perform dead code stripping. Since LLVM never generates
1628 // code that does this, it is always safe to set.
Lang Hames9ff69c82015-04-24 19:11:51 +00001629 OutStreamer->EmitAssemblerFlag(MCAF_SubsectionsViaSymbols);
Chris Lattner7432ceef2005-11-01 00:12:36 +00001630
Dan Gohmancf0a5342007-07-25 19:33:14 +00001631 return AsmPrinter::doFinalization(M);
Misha Brukmane05203f2004-06-21 16:55:25 +00001632}
Nate Begeman4bfceb12004-09-04 05:00:00 +00001633
Jim Laskey41621a72006-12-20 20:56:46 +00001634/// createPPCAsmPrinterPass - Returns a pass that prints the PPC assembly code
1635/// for a MachineFunction to the given output stream, in a format that the
Chris Lattnera81a75c2006-09-20 17:12:19 +00001636/// Darwin assembler can deal with.
1637///
David Blaikie94598322015-01-18 20:29:04 +00001638static AsmPrinter *
1639createPPCAsmPrinterPass(TargetMachine &tm,
1640 std::unique_ptr<MCStreamer> &&Streamer) {
Daniel Sandersc81f4502015-06-16 15:44:21 +00001641 if (tm.getTargetTriple().isMacOSX())
David Blaikie94598322015-01-18 20:29:04 +00001642 return new PPCDarwinAsmPrinter(tm, std::move(Streamer));
1643 return new PPCLinuxAsmPrinter(tm, std::move(Streamer));
Chris Lattnera81a75c2006-09-20 17:12:19 +00001644}
Anton Korobeynikov28dc9d02008-08-17 13:54:28 +00001645
Bob Wilson5a495fe2009-06-23 23:59:40 +00001646// Force static initialization.
NAKAMURA Takumi10c80e72015-09-22 11:19:03 +00001647extern "C" void LLVMInitializePowerPCAsmPrinter() {
Mehdi Aminif42454b2016-10-09 23:00:34 +00001648 TargetRegistry::RegisterAsmPrinter(getThePPC32Target(),
1649 createPPCAsmPrinterPass);
1650 TargetRegistry::RegisterAsmPrinter(getThePPC64Target(),
1651 createPPCAsmPrinterPass);
1652 TargetRegistry::RegisterAsmPrinter(getThePPC64LETarget(),
1653 createPPCAsmPrinterPass);
Daniel Dunbare8338102009-07-15 20:24:03 +00001654}