PPCSubtarget.cpp revision 9770be91de745e4727c65c45d13de2a787aef89f
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
30using 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.
39static 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__))
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")
152    .Case("A2", "a2")
153    .Case("POWER6", "pwr6")
154    .Case("POWER7", "pwr7")
155    .Default(generic);
156}
157#endif
158
159
160PPCSubtarget::PPCSubtarget(const std::string &TT, const std::string &CPU,
161                           const std::string &FS, bool is64Bit)
162  : PPCGenSubtargetInfo(TT, CPU, FS)
163  , StackAlignment(16)
164  , DarwinDirective(PPC::DIR_NONE)
165  , IsGigaProcessor(false)
166  , Has64BitSupport(false)
167  , Use64BitRegs(false)
168  , IsPPC64(is64Bit)
169  , HasAltivec(false)
170  , HasFSQRT(false)
171  , HasSTFIWX(false)
172  , IsBookE(false)
173  , HasLazyResolverStubs(false)
174  , IsJITCodeModel(false)
175  , TargetTriple(TT) {
176
177  // Determine default and user specified characteristics
178  std::string CPUName = CPU;
179  if (CPUName.empty())
180    CPUName = "generic";
181#if defined(__APPLE__) || \
182      (defined(__linux__) && (defined(__ppc__) || defined(__powerpc__)))
183  if (CPUName == "generic")
184    CPUName = GetCurrentPowerPCCPU();
185#endif
186
187  // Parse features string.
188  ParseSubtargetFeatures(CPUName, FS);
189
190  // Initialize scheduling itinerary for the specified CPU.
191  InstrItins = getInstrItineraryForCPU(CPUName);
192
193  // If we are generating code for ppc64, verify that options make sense.
194  if (is64Bit) {
195    Has64BitSupport = true;
196    // Silently force 64-bit register use on ppc64.
197    Use64BitRegs = true;
198  }
199
200  // If the user requested use of 64-bit regs, but the cpu selected doesn't
201  // support it, ignore.
202  if (use64BitRegs() && !has64BitSupport())
203    Use64BitRegs = false;
204
205  // Set up darwin-specific properties.
206  if (isDarwin())
207    HasLazyResolverStubs = true;
208}
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;
217
218  // Calls to external functions need to use indirect calls
219  IsJITCodeModel = true;
220}
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.
226bool PPCSubtarget::hasLazyResolverStub(const GlobalValue *GV,
227                                       const TargetMachine &TM) const {
228  // We never have stubs if HasLazyResolverStubs=false or if in static mode.
229  if (!HasLazyResolverStubs || TM.getRelocationModel() == Reloc::Static)
230    return false;
231  // If symbol visibility is hidden, the extra load is not needed if
232  // the symbol is definitely defined in the current translation unit.
233  bool isDecl = GV->isDeclaration() && !GV->isMaterializable();
234  if (GV->hasHiddenVisibility() && !isDecl && !GV->hasCommonLinkage())
235    return false;
236  return GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
237         GV->hasCommonLinkage() || isDecl;
238}
239
240bool PPCSubtarget::enablePostRAScheduler(
241           CodeGenOpt::Level OptLevel,
242           TargetSubtargetInfo::AntiDepBreakMode& Mode,
243           RegClassVector& CriticalPathRCs) const {
244  // 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;
252
253  CriticalPathRCs.clear();
254
255  if (isPPC64())
256    CriticalPathRCs.push_back(&PPC::G8RCRegClass);
257  else
258    CriticalPathRCs.push_back(&PPC::GPRCRegClass);
259
260  CriticalPathRCs.push_back(&PPC::F8RCRegClass);
261  CriticalPathRCs.push_back(&PPC::VRRCRegClass);
262
263  return OptLevel >= CodeGenOpt::Default;
264}
265
266