Clean up 32/64bit and Darwin/AIX split. Next steps: 64 bit ISel, AIX asm printer.
[oota-llvm.git] / lib / Target / PowerPC / PPCTargetMachine.cpp
1 //===-- PowerPCTargetMachine.cpp - Define TargetMachine for PowerPC -------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 // 
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "PowerPC.h"
14 #include "PowerPCTargetMachine.h"
15 #include "PPC32TargetMachine.h"
16 #include "PPC64TargetMachine.h"
17 #include "PPC32JITInfo.h"
18 #include "PPC64JITInfo.h"
19 #include "llvm/Module.h"
20 #include "llvm/PassManager.h"
21 #include "llvm/CodeGen/IntrinsicLowering.h"
22 #include "llvm/CodeGen/MachineFunction.h"
23 #include "llvm/CodeGen/Passes.h"
24 #include "llvm/Target/TargetOptions.h"
25 #include "llvm/Target/TargetMachineRegistry.h"
26 #include "llvm/Transforms/Scalar.h"
27 #include "Support/CommandLine.h"
28 #include <iostream>
29 using namespace llvm;
30
31 namespace {
32   cl::opt<bool> 
33     AIX("aix", 
34     cl::desc("Generate AIX/xcoff rather than Darwin/macho"), 
35     cl::Hidden);
36   const std::string PPC32 = "PowerPC/32bit";
37   const std::string PPC64 = "PowerPC/64bit";
38   
39   // Register the targets
40   RegisterTarget<PPC32TargetMachine> 
41   X("ppc32", "  PowerPC 32bit (experimental)");
42   RegisterTarget<PPC64TargetMachine> 
43   Y("ppc64", "  PowerPC 64bit (unimplemented)");
44 }
45
46 PowerPCTargetMachine::PowerPCTargetMachine(const std::string &name,
47                                            IntrinsicLowering *IL,
48                                            const TargetData &TD,
49                                            const TargetFrameInfo &TFI,
50                                            const PowerPCJITInfo &TJI) 
51   : TargetMachine(name, IL, TD), FrameInfo(TFI), JITInfo(TJI) {}
52
53 unsigned PowerPCTargetMachine::getJITMatchQuality() {
54 #if defined(__POWERPC__) || defined (__ppc__) || defined(_POWER)
55   return 10;
56 #else
57   return 0;
58 #endif
59 }
60
61 /// addPassesToEmitAssembly - Add passes to the specified pass manager
62 /// to implement a static compiler for this target.
63 ///
64 bool PowerPCTargetMachine::addPassesToEmitAssembly(PassManager &PM,
65                                                    std::ostream &Out) {
66   bool LP64 = (0 != dynamic_cast<PPC64TargetMachine *>(this));
67   
68   // FIXME: Implement efficient support for garbage collection intrinsics.
69   PM.add(createLowerGCPass());
70
71   // FIXME: Implement the invoke/unwind instructions!
72   PM.add(createLowerInvokePass());
73
74   // FIXME: Implement the switch instruction in the instruction selector!
75   PM.add(createLowerSwitchPass());
76
77   PM.add(createLowerConstantExpressionsPass());
78
79   // Make sure that no unreachable blocks are instruction selected.
80   PM.add(createUnreachableBlockEliminationPass());
81
82   if (LP64)
83     PM.add(createPPC32ISelSimple(*this));
84   else
85     PM.add(createPPC32ISelSimple(*this));
86
87   if (PrintMachineCode)
88     PM.add(createMachineFunctionPrinterPass(&std::cerr));
89
90   PM.add(createRegisterAllocator());
91
92   if (PrintMachineCode)
93     PM.add(createMachineFunctionPrinterPass(&std::cerr));
94
95   // I want a PowerPC specific prolog/epilog code inserter so I can put the 
96   // fills/spills in the right spots.
97   PM.add(createPowerPCPEI());
98   
99   // Must run branch selection immediately preceding the printer
100   PM.add(createPPCBranchSelectionPass());
101   
102   if (AIX)
103     PM.add(createPPC32AsmPrinter(Out, *this));
104   else
105     PM.add(createPPC32AsmPrinter(Out, *this));
106     
107   PM.add(createMachineCodeDeleter());
108   return false;
109 }
110
111 void PowerPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) {
112   // FIXME: Implement efficient support for garbage collection intrinsics.
113   PM.add(createLowerGCPass());
114
115   // FIXME: Implement the invoke/unwind instructions!
116   PM.add(createLowerInvokePass());
117
118   // FIXME: Implement the switch instruction in the instruction selector!
119   PM.add(createLowerSwitchPass());
120
121   PM.add(createLowerConstantExpressionsPass());
122
123   // Make sure that no unreachable blocks are instruction selected.
124   PM.add(createUnreachableBlockEliminationPass());
125
126   PM.add(createPPC32ISelSimple(TM));
127   PM.add(createRegisterAllocator());
128   PM.add(createPrologEpilogCodeInserter());
129 }
130
131 void PowerPCJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
132   assert(0 && "Cannot execute PowerPCJITInfo::replaceMachineCodeForFunction()");
133 }
134
135 void *PowerPCJITInfo::getJITStubForFunction(Function *F, 
136                                             MachineCodeEmitter &MCE) {
137   assert(0 && "Cannot execute PowerPCJITInfo::getJITStubForFunction()");
138   return 0;
139 }
140
141 /// PowerPCTargetMachine ctor - Create an ILP32 architecture model
142 ///
143 PPC32TargetMachine::PPC32TargetMachine(const Module &M,
144                                                IntrinsicLowering *IL)
145   : PowerPCTargetMachine(PPC32, IL, 
146                          TargetData(PPC32,false,4,4,4,4,4,4,2,1,4),
147                          TargetFrameInfo(TargetFrameInfo::StackGrowsDown,16,0),
148                          PPC32JITInfo(*this)) {}
149
150 /// PPC64TargetMachine ctor - Create a LP64 architecture model
151 ///
152 PPC64TargetMachine::PPC64TargetMachine(const Module &M, IntrinsicLowering *IL)
153   : PowerPCTargetMachine(PPC64, IL,
154                          TargetData(PPC64,false,8,4,4,4,4,4,2,1,4),
155                          TargetFrameInfo(TargetFrameInfo::StackGrowsDown,16,0),
156                          PPC64JITInfo(*this)) {}
157
158 unsigned PPC32TargetMachine::getModuleMatchQuality(const Module &M) {
159   if (M.getEndianness()  == Module::BigEndian &&
160       M.getPointerSize() == Module::Pointer32)
161     return 10;                                   // Direct match
162   else if (M.getEndianness() != Module::AnyEndianness ||
163            M.getPointerSize() != Module::AnyPointerSize)
164     return 0;                                    // Match for some other target
165
166   return getJITMatchQuality()/2;
167 }
168
169 unsigned PPC64TargetMachine::getModuleMatchQuality(const Module &M) {
170   if (M.getEndianness()  == Module::BigEndian &&
171       M.getPointerSize() == Module::Pointer64)
172     return 10;                                   // Direct match
173   else if (M.getEndianness() != Module::AnyEndianness ||
174            M.getPointerSize() != Module::AnyPointerSize)
175     return 0;                                    // Match for some other target
176
177   return getJITMatchQuality()/2;
178 }