blob: 55bc3f9127e30f3c5a49fbe034d2252da2a57a4c [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===//
Nate Begeman3bcfcd92005-08-04 07:12:09 +00002//
3// 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.
Nate Begeman3bcfcd92005-08-04 07:12:09 +00007//
8//===----------------------------------------------------------------------===//
9//
Evan Cheng0d639a22011-07-01 21:01:15 +000010// This file implements the PPC specific subclass of TargetSubtargetInfo.
Nate Begeman3bcfcd92005-08-04 07:12:09 +000011//
12//===----------------------------------------------------------------------===//
13
Chris Lattnerbfca1ab2005-10-14 23:51:18 +000014#include "PPCSubtarget.h"
Hal Finkel58ca3602011-12-02 04:58:02 +000015#include "PPCRegisterInfo.h"
Chris Lattnerbfca1ab2005-10-14 23:51:18 +000016#include "PPC.h"
Hal Finkelba671c02012-06-11 15:43:13 +000017#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/StringSwitch.h"
Daniel Dunbar31b44e82009-08-02 22:11:08 +000019#include "llvm/GlobalValue.h"
Chris Lattnerf4646a72006-12-11 23:22:45 +000020#include "llvm/Target/TargetMachine.h"
Hal Finkelba671c02012-06-11 15:43:13 +000021#include "llvm/Support/DataStream.h"
22#include "llvm/Support/Debug.h"
Evan Cheng2bb40352011-08-24 18:08:43 +000023#include "llvm/Support/TargetRegistry.h"
Dan Gohman906152a2009-01-05 17:59:02 +000024#include <cstdlib>
Evan Cheng54b68e32011-07-01 20:45:01 +000025
Evan Cheng54b68e32011-07-01 20:45:01 +000026#define GET_SUBTARGETINFO_TARGET_DESC
Evan Cheng4d1ca962011-07-08 01:53:10 +000027#define GET_SUBTARGETINFO_CTOR
Evan Chengc9c090d2011-07-01 22:36:09 +000028#include "PPCGenSubtargetInfo.inc"
Evan Cheng54b68e32011-07-01 20:45:01 +000029
Chris Lattner983a4152005-08-05 22:05:03 +000030using namespace llvm;
Chris Lattner983a4152005-08-05 22:05:03 +000031
Nate Begeman3bcfcd92005-08-04 07:12:09 +000032#if defined(__APPLE__)
33#include <mach/mach.h>
34#include <mach/mach_host.h>
35#include <mach/host_info.h>
36#include <mach/machine.h>
37
Jim Laskey19058c32005-09-01 21:38:21 +000038/// GetCurrentPowerPCFeatures - Returns the current CPUs features.
39static const char *GetCurrentPowerPCCPU() {
Nate Begeman3bcfcd92005-08-04 07:12:09 +000040 host_basic_info_data_t hostInfo;
41 mach_msg_type_number_t infoCount;
42
43 infoCount = HOST_BASIC_INFO_COUNT;
44 host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostInfo,
45 &infoCount);
Jim Laskey19058c32005-09-01 21:38:21 +000046
47 if (hostInfo.cpu_type != CPU_TYPE_POWERPC) return "generic";
48
49 switch(hostInfo.cpu_subtype) {
50 case CPU_SUBTYPE_POWERPC_601: return "601";
51 case CPU_SUBTYPE_POWERPC_602: return "602";
52 case CPU_SUBTYPE_POWERPC_603: return "603";
53 case CPU_SUBTYPE_POWERPC_603e: return "603e";
54 case CPU_SUBTYPE_POWERPC_603ev: return "603ev";
55 case CPU_SUBTYPE_POWERPC_604: return "604";
56 case CPU_SUBTYPE_POWERPC_604e: return "604e";
57 case CPU_SUBTYPE_POWERPC_620: return "620";
58 case CPU_SUBTYPE_POWERPC_750: return "750";
59 case CPU_SUBTYPE_POWERPC_7400: return "7400";
60 case CPU_SUBTYPE_POWERPC_7450: return "7450";
61 case CPU_SUBTYPE_POWERPC_970: return "970";
62 default: ;
63 }
Nate Begeman3bcfcd92005-08-04 07:12:09 +000064
Jim Laskey19058c32005-09-01 21:38:21 +000065 return "generic";
66}
Hal Finkelba671c02012-06-11 15:43:13 +000067#elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
68static const char *GetCurrentPowerPCCPU() {
69 // Access to the Processor Version Register (PVR) on PowerPC is privileged,
70 // and so we must use an operating-system interface to determine the current
71 // processor type. On Linux, this is exposed through the /proc/cpuinfo file.
72 const char *generic = "generic";
73
74 // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
75 // memory buffer because the 'file' has 0 size (it can be read from only
76 // as a stream).
77
78 std::string Err;
79 DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
80 if (!DS) {
81 DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
82 return generic;
83 }
84
85 // The cpu line is second (after the 'processor: 0' line), so if this
86 // buffer is too small then something has changed (or is wrong).
87 char buffer[1024];
88 size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
89 delete DS;
90
91 const char *CPUInfoStart = buffer;
92 const char *CPUInfoEnd = buffer + CPUInfoSize;
93
94 const char *CIP = CPUInfoStart;
95
96 const char *CPUStart = 0;
97 size_t CPULen = 0;
98
99 // We need to find the first line which starts with cpu, spaces, and a colon.
100 // After the colon, there may be some additional spaces and then the cpu type.
101 while (CIP < CPUInfoEnd && CPUStart == 0) {
102 if (CIP < CPUInfoEnd && *CIP == '\n')
103 ++CIP;
104
105 if (CIP < CPUInfoEnd && *CIP == 'c') {
106 ++CIP;
107 if (CIP < CPUInfoEnd && *CIP == 'p') {
108 ++CIP;
109 if (CIP < CPUInfoEnd && *CIP == 'u') {
110 ++CIP;
111 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
112 ++CIP;
113
114 if (CIP < CPUInfoEnd && *CIP == ':') {
115 ++CIP;
116 while (CIP < CPUInfoEnd && (*CIP == ' ' || *CIP == '\t'))
117 ++CIP;
118
119 if (CIP < CPUInfoEnd) {
120 CPUStart = CIP;
121 while (CIP < CPUInfoEnd && (*CIP != ' ' && *CIP != '\t' &&
122 *CIP != ',' && *CIP != '\n'))
123 ++CIP;
124 CPULen = CIP - CPUStart;
125 }
126 }
127 }
128 }
129 }
130
131 if (CPUStart == 0)
132 while (CIP < CPUInfoEnd && *CIP != '\n')
133 ++CIP;
134 }
135
136 if (CPUStart == 0)
137 return generic;
138
139 return StringSwitch<const char *>(StringRef(CPUStart, CPULen))
140 .Case("604e", "604e")
141 .Case("604", "604")
142 .Case("7400", "7400")
143 .Case("7410", "7400")
144 .Case("7447", "7400")
145 .Case("7455", "7450")
146 .Case("G4", "g4")
147 .Case("POWER4", "g4")
148 .Case("PPC970FX", "970")
149 .Case("PPC970MP", "970")
150 .Case("G5", "g5")
151 .Case("POWER5", "g5")
Hal Finkel25d4c562012-06-11 19:56:57 +0000152 .Case("A2", "a2")
Hal Finkelba671c02012-06-11 15:43:13 +0000153 .Case("POWER6", "pwr6")
154 .Case("POWER7", "pwr7")
155 .Default(generic);
156}
Nate Begeman3bcfcd92005-08-04 07:12:09 +0000157#endif
158
Jim Laskeya2b52352005-10-26 17:30:34 +0000159
Evan Chengfe6e4052011-06-30 01:53:36 +0000160PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU,
161 const std::string &FS, bool is64Bit)
Evan Cheng1a72add62011-07-07 07:07:08 +0000162 : PPCGenSubtargetInfo(TT, CPU, FS)
Evan Cheng54b68e32011-07-01 20:45:01 +0000163 , StackAlignment(16)
Dale Johannesen6ca3ccf2008-02-14 23:35:16 +0000164 , DarwinDirective(PPC::DIR_NONE)
Hal Finkelbfd3d082012-06-11 19:57:01 +0000165 , HasMFOCRF(false)
Chris Lattnera35f3062006-06-16 17:34:12 +0000166 , Has64BitSupport(false)
167 , Use64BitRegs(false)
Chris Lattner16682ff2006-06-16 17:50:12 +0000168 , IsPPC64(is64Bit)
Jim Laskeya2b52352005-10-26 17:30:34 +0000169 , HasAltivec(false)
170 , HasFSQRT(false)
Chris Lattner27f53452006-03-01 05:50:56 +0000171 , HasSTFIWX(false)
Hal Finkel6fa56972011-10-17 04:03:49 +0000172 , IsBookE(false)
Chris Lattnerdcbc0f32008-01-02 19:35:16 +0000173 , HasLazyResolverStubs(false)
Torok Edwin31e90d22010-08-04 20:47:44 +0000174 , IsJITCodeModel(false)
Daniel Dunbara37aab22011-04-19 20:54:28 +0000175 , TargetTriple(TT) {
Chris Lattner983a4152005-08-05 22:05:03 +0000176
Jim Laskey19058c32005-09-01 21:38:21 +0000177 // Determine default and user specified characteristics
Evan Chengfe6e4052011-06-30 01:53:36 +0000178 std::string CPUName = CPU;
179 if (CPUName.empty())
180 CPUName = "generic";
Hal Finkelba671c02012-06-11 15:43:13 +0000181#if defined(__APPLE__) || \
182 (defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)))
Evan Chengfe6e4052011-06-30 01:53:36 +0000183 if (CPUName == "generic")
184 CPUName = GetCurrentPowerPCCPU();
Jim Laskey19058c32005-09-01 21:38:21 +0000185#endif
Jim Laskeya2b52352005-10-26 17:30:34 +0000186
187 // Parse features string.
Evan Cheng1a72add62011-07-07 07:07:08 +0000188 ParseSubtargetFeatures(CPUName, FS);
Jim Laskey19058c32005-09-01 21:38:21 +0000189
Evan Cheng54b68e32011-07-01 20:45:01 +0000190 // Initialize scheduling itinerary for the specified CPU.
191 InstrItins = getInstrItineraryForCPU(CPUName);
192
Chris Lattner16682ff2006-06-16 17:50:12 +0000193 // If we are generating code for ppc64, verify that options make sense.
194 if (is64Bit) {
Dale Johannesen2e019122008-02-15 18:40:53 +0000195 Has64BitSupport = true;
Chris Lattner61d70312006-06-16 20:05:06 +0000196 // Silently force 64-bit register use on ppc64.
197 Use64BitRegs = true;
Chris Lattner16682ff2006-06-16 17:50:12 +0000198 }
199
200 // If the user requested use of 64-bit regs, but the cpu selected doesn't
Dale Johannesen2e019122008-02-15 18:40:53 +0000201 // support it, ignore.
202 if (use64BitRegs() && !has64BitSupport())
Chris Lattner16682ff2006-06-16 17:50:12 +0000203 Use64BitRegs = false;
Chris Lattnerf4646a72006-12-11 23:22:45 +0000204
205 // Set up darwin-specific properties.
Chris Lattnere6555212009-08-11 22:49:34 +0000206 if (isDarwin())
Chris Lattnerf4646a72006-12-11 23:22:45 +0000207 HasLazyResolverStubs = true;
Chris Lattnerf4646a72006-12-11 23:22:45 +0000208}
209
210/// SetJITMode - This is called to inform the subtarget info that we are
211/// producing code for the JIT.
212void PPCSubtarget::SetJITMode() {
213 // JIT mode doesn't want lazy resolver stubs, it knows exactly where
214 // everything is. This matters for PPC64, which codegens in PIC mode without
215 // stubs.
216 HasLazyResolverStubs = false;
Torok Edwin31e90d22010-08-04 20:47:44 +0000217
218 // Calls to external functions need to use indirect calls
219 IsJITCodeModel = true;
Chris Lattnerf4646a72006-12-11 23:22:45 +0000220}
221
222
223/// hasLazyResolverStub - Return true if accesses to the specified global have
224/// to go through a dyld lazy resolution stub. This means that an extra load
225/// is required to get the address of the global.
Daniel Dunbar31b44e82009-08-02 22:11:08 +0000226bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV,
227 const TargetMachine &TM) const {
Chris Lattneredb9d842010-11-15 02:46:57 +0000228 // We never have stubs if HasLazyResolverStubs=false or if in static mode.
Chris Lattnerf4646a72006-12-11 23:22:45 +0000229 if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static)
230 return false;
Evan Cheng2a03c7e2008-12-05 01:06:39 +0000231 // If symbol visibility is hidden, the extra load is not needed if
232 // the symbol is definitely defined in the current translation unit.
Jeffrey Yasskin091217b2010-01-27 20:34:15 +0000233 bool isDecl = GV->isDeclaration() && !GV->isMaterializable();
Evan Cheng2a03c7e2008-12-05 01:06:39 +0000234 if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage())
235 return false;
Chris Lattnerf4646a72006-12-11 23:22:45 +0000236 return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
Evan Cheng2a03c7e2008-12-05 01:06:39 +0000237 GV->hasCommonLinkage() || isDecl;
Nate Begeman3bcfcd92005-08-04 07:12:09 +0000238}
Hal Finkel58ca3602011-12-02 04:58:02 +0000239
240bool PPCSubtarget::enablePostRAScheduler(
241 CodeGenOpt::Level OptLevel,
242 TargetSubtargetInfo::AntiDepBreakMode& Mode,
243 RegClassVector& CriticalPathRCs) const {
Hal Finkela8100282012-06-10 11:15:36 +0000244 // FIXME: It would be best to use TargetSubtargetInfo::ANTIDEP_ALL here,
245 // but we can't because we can't reassign the cr registers. There is a
246 // dependence between the cr register and the RLWINM instruction used
247 // to extract its value which the anti-dependency breaker can't currently
248 // see. Maybe we should make a late-expanded pseudo to encode this dependency.
249 // (the relevant code is in PPCDAGToDAGISel::SelectSETCC)
250
251 Mode = TargetSubtargetInfo::ANTIDEP_CRITICAL;
Hal Finkel58ca3602011-12-02 04:58:02 +0000252
Hal Finkel58ca3602011-12-02 04:58:02 +0000253 CriticalPathRCs.clear();
254
255 if (isPPC64())
256 CriticalPathRCs.push_back(&PPC::G8RCRegClass);
257 else
258 CriticalPathRCs.push_back(&PPC::GPRCRegClass);
Hal Finkela8100282012-06-10 11:15:36 +0000259
260 CriticalPathRCs.push_back(&PPC::F8RCRegClass);
261 CriticalPathRCs.push_back(&PPC::VRRCRegClass);
Hal Finkel58ca3602011-12-02 04:58:02 +0000262
263 return OptLevel >= CodeGenOpt::Default;
264}
265