1dff0c46cSDimitry Andric //===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
1017a519f9SDimitry Andric // This file implements the PPC specific subclass of TargetSubtargetInfo.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky
14f22ef01cSRoman Divacky #include "PPCSubtarget.h"
15f22ef01cSRoman Divacky #include "PPC.h"
16139f7f9bSDimitry Andric #include "PPCRegisterInfo.h"
17ff0cc061SDimitry Andric #include "PPCTargetMachine.h"
18f785676fSDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
19f785676fSDimitry Andric #include "llvm/CodeGen/MachineScheduler.h"
20f785676fSDimitry Andric #include "llvm/IR/Attributes.h"
21f785676fSDimitry Andric #include "llvm/IR/Function.h"
2291bc56edSDimitry Andric #include "llvm/IR/GlobalValue.h"
2339d628a0SDimitry Andric #include "llvm/Support/CommandLine.h"
246122f3e6SDimitry Andric #include "llvm/Support/TargetRegistry.h"
25139f7f9bSDimitry Andric #include "llvm/Target/TargetMachine.h"
26f22ef01cSRoman Divacky #include <cstdlib>
2717a519f9SDimitry Andric
2891bc56edSDimitry Andric using namespace llvm;
2991bc56edSDimitry Andric
3091bc56edSDimitry Andric #define DEBUG_TYPE "ppc-subtarget"
3191bc56edSDimitry Andric
3217a519f9SDimitry Andric #define GET_SUBTARGETINFO_TARGET_DESC
3317a519f9SDimitry Andric #define GET_SUBTARGETINFO_CTOR
3417a519f9SDimitry Andric #include "PPCGenSubtargetInfo.inc"
3517a519f9SDimitry Andric
3639d628a0SDimitry Andric static cl::opt<bool> UseSubRegLiveness("ppc-track-subreg-liveness",
3739d628a0SDimitry Andric cl::desc("Enable subregister liveness tracking for PPC"), cl::Hidden);
38f22ef01cSRoman Divacky
39ff0cc061SDimitry Andric static cl::opt<bool> QPXStackUnaligned("qpx-stack-unaligned",
40ff0cc061SDimitry Andric cl::desc("Even when QPX is enabled the stack is not 32-byte aligned"),
41ff0cc061SDimitry Andric cl::Hidden);
4291bc56edSDimitry Andric
initializeSubtargetDependencies(StringRef CPU,StringRef FS)4391bc56edSDimitry Andric PPCSubtarget &PPCSubtarget::initializeSubtargetDependencies(StringRef CPU,
4491bc56edSDimitry Andric StringRef FS) {
45f785676fSDimitry Andric initializeEnvironment();
4639d628a0SDimitry Andric initSubtargetFeatures(CPU, FS);
4791bc56edSDimitry Andric return *this;
48f785676fSDimitry Andric }
49f22ef01cSRoman Divacky
PPCSubtarget(const Triple & TT,const std::string & CPU,const std::string & FS,const PPCTargetMachine & TM)508f0fd8f6SDimitry Andric PPCSubtarget::PPCSubtarget(const Triple &TT, const std::string &CPU,
5139d628a0SDimitry Andric const std::string &FS, const PPCTargetMachine &TM)
5239d628a0SDimitry Andric : PPCGenSubtargetInfo(TT, CPU, FS), TargetTriple(TT),
5339d628a0SDimitry Andric IsPPC64(TargetTriple.getArch() == Triple::ppc64 ||
5439d628a0SDimitry Andric TargetTriple.getArch() == Triple::ppc64le),
55ff0cc061SDimitry Andric TM(TM), FrameLowering(initializeSubtargetDependencies(CPU, FS)),
56875ed548SDimitry Andric InstrInfo(*this), TLInfo(TM, *this) {}
5791bc56edSDimitry Andric
initializeEnvironment()58f785676fSDimitry Andric void PPCSubtarget::initializeEnvironment() {
59f785676fSDimitry Andric StackAlignment = 16;
60f785676fSDimitry Andric DarwinDirective = PPC::DIR_NONE;
61f785676fSDimitry Andric HasMFOCRF = false;
62f785676fSDimitry Andric Has64BitSupport = false;
63f785676fSDimitry Andric Use64BitRegs = false;
6491bc56edSDimitry Andric UseCRBits = false;
6511c1fce8SDimitry Andric HasHardFloat = false;
66f785676fSDimitry Andric HasAltivec = false;
6739d628a0SDimitry Andric HasSPE = false;
684ba319b5SDimitry Andric HasFPU = false;
69f785676fSDimitry Andric HasQPX = false;
7091bc56edSDimitry Andric HasVSX = false;
7139d628a0SDimitry Andric HasP8Vector = false;
72ff0cc061SDimitry Andric HasP8Altivec = false;
73ff0cc061SDimitry Andric HasP8Crypto = false;
743ca95b02SDimitry Andric HasP9Vector = false;
753ca95b02SDimitry Andric HasP9Altivec = false;
76f785676fSDimitry Andric HasFCPSGN = false;
77f785676fSDimitry Andric HasFSQRT = false;
78f785676fSDimitry Andric HasFRE = false;
79f785676fSDimitry Andric HasFRES = false;
80f785676fSDimitry Andric HasFRSQRTE = false;
81f785676fSDimitry Andric HasFRSQRTES = false;
82f785676fSDimitry Andric HasRecipPrec = false;
83f785676fSDimitry Andric HasSTFIWX = false;
84f785676fSDimitry Andric HasLFIWAX = false;
85f785676fSDimitry Andric HasFPRND = false;
86f785676fSDimitry Andric HasFPCVT = false;
87f785676fSDimitry Andric HasISEL = false;
88ff0cc061SDimitry Andric HasBPERMD = false;
89ff0cc061SDimitry Andric HasExtDiv = false;
9039d628a0SDimitry Andric HasCMPB = false;
91f785676fSDimitry Andric HasLDBRX = false;
92f785676fSDimitry Andric IsBookE = false;
9339d628a0SDimitry Andric HasOnlyMSYNC = false;
9439d628a0SDimitry Andric IsPPC4xx = false;
9539d628a0SDimitry Andric IsPPC6xx = false;
9639d628a0SDimitry Andric IsE500 = false;
978f0fd8f6SDimitry Andric FeatureMFTB = false;
98f785676fSDimitry Andric DeprecatedDST = false;
99f785676fSDimitry Andric HasLazyResolverStubs = false;
100ff0cc061SDimitry Andric HasICBT = false;
101ff0cc061SDimitry Andric HasInvariantFunctionDescriptors = false;
102ff0cc061SDimitry Andric HasPartwordAtomics = false;
103ff0cc061SDimitry Andric HasDirectMove = false;
104ff0cc061SDimitry Andric IsQPXStackUnaligned = false;
105ff0cc061SDimitry Andric HasHTM = false;
1067d523365SDimitry Andric HasFusion = false;
1077d523365SDimitry Andric HasFloat128 = false;
1083ca95b02SDimitry Andric IsISA3_0 = false;
109b6054a7bSDimitry Andric UseLongCalls = false;
1104ba319b5SDimitry Andric SecurePlt = false;
1113ca95b02SDimitry Andric
1123ca95b02SDimitry Andric HasPOPCNTD = POPCNTD_Unavailable;
113f785676fSDimitry Andric }
114f785676fSDimitry Andric
initSubtargetFeatures(StringRef CPU,StringRef FS)11539d628a0SDimitry Andric void PPCSubtarget::initSubtargetFeatures(StringRef CPU, StringRef FS) {
116f22ef01cSRoman Divacky // Determine default and user specified characteristics
11717a519f9SDimitry Andric std::string CPUName = CPU;
1183ca95b02SDimitry Andric if (CPUName.empty() || CPU == "generic") {
119ff0cc061SDimitry Andric // If cross-compiling with -march=ppc64le without -mcpu
120ff0cc061SDimitry Andric if (TargetTriple.getArch() == Triple::ppc64le)
121ff0cc061SDimitry Andric CPUName = "ppc64le";
122ff0cc061SDimitry Andric else
12317a519f9SDimitry Andric CPUName = "generic";
124ff0cc061SDimitry Andric }
125f22ef01cSRoman Divacky
12617a519f9SDimitry Andric // Initialize scheduling itinerary for the specified CPU.
12717a519f9SDimitry Andric InstrItins = getInstrItineraryForCPU(CPUName);
128f22ef01cSRoman Divacky
1293861d79fSDimitry Andric // Parse features string.
13039d628a0SDimitry Andric ParseSubtargetFeatures(CPUName, FS);
1313861d79fSDimitry Andric
132f22ef01cSRoman Divacky // If the user requested use of 64-bit regs, but the cpu selected doesn't
133f22ef01cSRoman Divacky // support it, ignore.
13439d628a0SDimitry Andric if (IsPPC64 && has64BitSupport())
13539d628a0SDimitry Andric Use64BitRegs = true;
136f22ef01cSRoman Divacky
137f22ef01cSRoman Divacky // Set up darwin-specific properties.
138f22ef01cSRoman Divacky if (isDarwin())
139f22ef01cSRoman Divacky HasLazyResolverStubs = true;
140139f7f9bSDimitry Andric
141*85573313SDimitry Andric if ((TargetTriple.isOSFreeBSD() && TargetTriple.getOSMajorVersion() >= 13)
142*85573313SDimitry Andric || TargetTriple.isOSNetBSD() || TargetTriple.isOSOpenBSD())
143*85573313SDimitry Andric SecurePlt = true;
144*85573313SDimitry Andric
1454ba319b5SDimitry Andric if (HasSPE && IsPPC64)
1464ba319b5SDimitry Andric report_fatal_error( "SPE is only supported for 32-bit targets.\n", false);
1474ba319b5SDimitry Andric if (HasSPE && (HasAltivec || HasQPX || HasVSX || HasFPU))
1484ba319b5SDimitry Andric report_fatal_error(
1494ba319b5SDimitry Andric "SPE and traditional floating point cannot both be enabled.\n", false);
1504ba319b5SDimitry Andric
1514ba319b5SDimitry Andric // If not SPE, set standard FPU
1524ba319b5SDimitry Andric if (!HasSPE)
1534ba319b5SDimitry Andric HasFPU = true;
1544ba319b5SDimitry Andric
155139f7f9bSDimitry Andric // QPX requires a 32-byte aligned stack. Note that we need to do this if
156139f7f9bSDimitry Andric // we're compiling for a BG/Q system regardless of whether or not QPX
157139f7f9bSDimitry Andric // is enabled because external functions will assume this alignment.
158ff0cc061SDimitry Andric IsQPXStackUnaligned = QPXStackUnaligned;
159ff0cc061SDimitry Andric StackAlignment = getPlatformStackAlignment();
160f785676fSDimitry Andric
161f785676fSDimitry Andric // Determine endianness.
162ff0cc061SDimitry Andric // FIXME: Part of the TargetMachine.
163f785676fSDimitry Andric IsLittleEndian = (TargetTriple.getArch() == Triple::ppc64le);
164f22ef01cSRoman Divacky }
165f22ef01cSRoman Divacky
1663ca95b02SDimitry Andric /// Return true if accesses to the specified global have to go through a dyld
1673ca95b02SDimitry Andric /// lazy resolution stub. This means that an extra load is required to get the
1683ca95b02SDimitry Andric /// address of the global.
hasLazyResolverStub(const GlobalValue * GV) const169ff0cc061SDimitry Andric bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV) const {
1703ca95b02SDimitry Andric if (!HasLazyResolverStubs)
171f22ef01cSRoman Divacky return false;
1723ca95b02SDimitry Andric if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
1733ca95b02SDimitry Andric return true;
1743ca95b02SDimitry Andric // 32 bit macho has no relocation for a-b if a is undefined, even if b is in
1753ca95b02SDimitry Andric // the section that is being relocated. This means we have to use o load even
1763ca95b02SDimitry Andric // for GVs that are known to be local to the dso.
1773ca95b02SDimitry Andric if (GV->isDeclarationForLinker() || GV->hasCommonLinkage())
1783ca95b02SDimitry Andric return true;
179f22ef01cSRoman Divacky return false;
180f22ef01cSRoman Divacky }
181dff0c46cSDimitry Andric
enableMachineScheduler() const182f785676fSDimitry Andric bool PPCSubtarget::enableMachineScheduler() const {
1834ba319b5SDimitry Andric return true;
184f785676fSDimitry Andric }
185f785676fSDimitry Andric
18691bc56edSDimitry Andric // This overrides the PostRAScheduler bit in the SchedModel for each CPU.
enablePostRAScheduler() const1878f0fd8f6SDimitry Andric bool PPCSubtarget::enablePostRAScheduler() const { return true; }
18891bc56edSDimitry Andric
getAntiDepBreakMode() const18991bc56edSDimitry Andric PPCGenSubtargetInfo::AntiDepBreakMode PPCSubtarget::getAntiDepBreakMode() const {
19091bc56edSDimitry Andric return TargetSubtargetInfo::ANTIDEP_ALL;
19191bc56edSDimitry Andric }
19291bc56edSDimitry Andric
getCriticalPathRCs(RegClassVector & CriticalPathRCs) const19391bc56edSDimitry Andric void PPCSubtarget::getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
19491bc56edSDimitry Andric CriticalPathRCs.clear();
19591bc56edSDimitry Andric CriticalPathRCs.push_back(isPPC64() ?
19691bc56edSDimitry Andric &PPC::G8RCRegClass : &PPC::GPRCRegClass);
19791bc56edSDimitry Andric }
19891bc56edSDimitry Andric
overrideSchedPolicy(MachineSchedPolicy & Policy,unsigned NumRegionInstrs) const199f785676fSDimitry Andric void PPCSubtarget::overrideSchedPolicy(MachineSchedPolicy &Policy,
200f785676fSDimitry Andric unsigned NumRegionInstrs) const {
2014ba319b5SDimitry Andric // The GenericScheduler that we use defaults to scheduling bottom up only.
2024ba319b5SDimitry Andric // We want to schedule from both the top and the bottom and so we set
2034ba319b5SDimitry Andric // OnlyBottomUp to false.
2044ba319b5SDimitry Andric // We want to do bi-directional scheduling since it provides a more balanced
2054ba319b5SDimitry Andric // schedule leading to better performance.
206f785676fSDimitry Andric Policy.OnlyBottomUp = false;
207f785676fSDimitry Andric // Spilling is generally expensive on all PPC cores, so always enable
208f785676fSDimitry Andric // register-pressure tracking.
209f785676fSDimitry Andric Policy.ShouldTrackPressure = true;
210f785676fSDimitry Andric }
211f785676fSDimitry Andric
useAA() const212f785676fSDimitry Andric bool PPCSubtarget::useAA() const {
2134ba319b5SDimitry Andric return true;
214f785676fSDimitry Andric }
215f785676fSDimitry Andric
enableSubRegLiveness() const21639d628a0SDimitry Andric bool PPCSubtarget::enableSubRegLiveness() const {
21739d628a0SDimitry Andric return UseSubRegLiveness;
21839d628a0SDimitry Andric }
21939d628a0SDimitry Andric
2207a7e6055SDimitry Andric unsigned char
classifyGlobalReference(const GlobalValue * GV) const2217a7e6055SDimitry Andric PPCSubtarget::classifyGlobalReference(const GlobalValue *GV) const {
2227d523365SDimitry Andric // Note that currently we don't generate non-pic references.
2237d523365SDimitry Andric // If a caller wants that, this will have to be updated.
2247d523365SDimitry Andric
2257d523365SDimitry Andric // Large code model always uses the TOC even for local symbols.
2267d523365SDimitry Andric if (TM.getCodeModel() == CodeModel::Large)
2277d523365SDimitry Andric return PPCII::MO_PIC_FLAG | PPCII::MO_NLP_FLAG;
2287d523365SDimitry Andric
2297a7e6055SDimitry Andric if (TM.shouldAssumeDSOLocal(*GV->getParent(), GV))
2307a7e6055SDimitry Andric return PPCII::MO_PIC_FLAG;
2317a7e6055SDimitry Andric return PPCII::MO_PIC_FLAG | PPCII::MO_NLP_FLAG;
2327d523365SDimitry Andric }
2337d523365SDimitry Andric
isELFv2ABI() const234ff0cc061SDimitry Andric bool PPCSubtarget::isELFv2ABI() const { return TM.isELFv2ABI(); }
isPPC64() const235ff0cc061SDimitry Andric bool PPCSubtarget::isPPC64() const { return TM.isPPC64(); }
236