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