Add local CPU detection for Linux PPC.
[oota-llvm.git] / lib / Target / PowerPC / PPCSubtarget.cpp
1 //===-- PowerPCSubtarget.cpp - PPC Subtarget Information ------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the PPC specific subclass of TargetSubtargetInfo.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PPCSubtarget.h"
15 #include "PPCRegisterInfo.h"
16 #include "PPC.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/ADT/StringSwitch.h"
19 #include "llvm/GlobalValue.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/Support/DataStream.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/TargetRegistry.h"
24 #include <cstdlib>
25
26 #define GET_SUBTARGETINFO_TARGET_DESC
27 #define GET_SUBTARGETINFO_CTOR
28 #include "PPCGenSubtargetInfo.inc"
29
30 using namespace llvm;
31
32 #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
38 /// GetCurrentPowerPCFeatures - Returns the current CPUs features.
39 static const char *GetCurrentPowerPCCPU() {
40   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);
46             
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   }
64   
65   return "generic";
66 }
67 #elif defined(__linux__) && (defined(__ppc__) || defined(__powerpc__))
68 static 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")
152     .Case("POWER6", "pwr6")
153     .Case("POWER7", "pwr7")
154     .Default(generic);
155 }
156 #endif
157
158
159 PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU,
160                            const std::string &FS, bool is64Bit)
161   : PPCGenSubtargetInfo(TT, CPU, FS)
162   , StackAlignment(16)
163   , DarwinDirective(PPC::DIR_NONE)
164   , IsGigaProcessor(false)
165   , Has64BitSupport(false)
166   , Use64BitRegs(false)
167   , IsPPC64(is64Bit)
168   , HasAltivec(false)
169   , HasFSQRT(false)
170   , HasSTFIWX(false)
171   , IsBookE(false)
172   , HasLazyResolverStubs(false)
173   , IsJITCodeModel(false)
174   , TargetTriple(TT) {
175
176   // Determine default and user specified characteristics
177   std::string CPUName = CPU;
178   if (CPUName.empty())
179     CPUName = "generic";
180 #if defined(__APPLE__) || \
181       (defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)))
182   if (CPUName == "generic")
183     CPUName = GetCurrentPowerPCCPU();
184 #endif
185
186   // Parse features string.
187   ParseSubtargetFeatures(CPUName, FS);
188
189   // Initialize scheduling itinerary for the specified CPU.
190   InstrItins = getInstrItineraryForCPU(CPUName);
191
192   // If we are generating code for ppc64, verify that options make sense.
193   if (is64Bit) {
194     Has64BitSupport = true;
195     // Silently force 64-bit register use on ppc64.
196     Use64BitRegs = true;
197   }
198   
199   // If the user requested use of 64-bit regs, but the cpu selected doesn't
200   // support it, ignore.
201   if (use64BitRegs() && !has64BitSupport())
202     Use64BitRegs = false;
203
204   // Set up darwin-specific properties.
205   if (isDarwin())
206     HasLazyResolverStubs = true;
207 }
208
209 /// SetJITMode - This is called to inform the subtarget info that we are
210 /// producing code for the JIT.
211 void PPCSubtarget::SetJITMode() {
212   // JIT mode doesn't want lazy resolver stubs, it knows exactly where
213   // everything is.  This matters for PPC64, which codegens in PIC mode without
214   // stubs.
215   HasLazyResolverStubs = false;
216
217   // Calls to external functions need to use indirect calls
218   IsJITCodeModel = true;
219 }
220
221
222 /// hasLazyResolverStub - Return true if accesses to the specified global have
223 /// to go through a dyld lazy resolution stub.  This means that an extra load
224 /// is required to get the address of the global.
225 bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV,
226                                        const TargetMachine &TM) const {
227   // We never have stubs if HasLazyResolverStubs=false or if in static mode.
228   if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static)
229     return false;
230   // If symbol visibility is hidden, the extra load is not needed if
231   // the symbol is definitely defined in the current translation unit.
232   bool isDecl = GV->isDeclaration() && !GV->isMaterializable();
233   if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage())
234     return false;
235   return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
236          GV->hasCommonLinkage() || isDecl;
237 }
238
239 bool PPCSubtarget::enablePostRAScheduler(
240            CodeGenOpt::Level OptLevel,
241            TargetSubtargetInfo::AntiDepBreakMode& Mode,
242            RegClassVector& CriticalPathRCs) const {
243   // FIXME: It would be best to use TargetSubtargetInfo::ANTIDEP_ALL here,
244   // but we can't because we can't reassign the cr registers. There is a
245   // dependence between the cr register and the RLWINM instruction used
246   // to extract its value which the anti-dependency breaker can't currently
247   // see. Maybe we should make a late-expanded pseudo to encode this dependency.
248   // (the relevant code is in PPCDAGToDAGISel::SelectSETCC)
249
250   Mode = TargetSubtargetInfo::ANTIDEP_CRITICAL;
251
252   CriticalPathRCs.clear();
253
254   if (isPPC64())
255     CriticalPathRCs.push_back(&PPC::G8RCRegClass);
256   else
257     CriticalPathRCs.push_back(&PPC::GPRCRegClass);
258     
259   CriticalPathRCs.push_back(&PPC::F8RCRegClass);
260   CriticalPathRCs.push_back(&PPC::VRRCRegClass);
261
262   return OptLevel >= CodeGenOpt::Default;
263 }
264