0fe8f1efcec7329c90124d610b57f4e50be2d560
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9TargetMachine.cpp
1 //===-- Sparc.cpp - General implementation file for the Sparc Target ------===//
2 //
3 // This file contains the code for the Sparc Target that does not fit in any of
4 // the other files in this directory.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "SparcInternals.h"
9 #include "llvm/Target/Sparc.h"
10 #include "llvm/CodeGen/InstrScheduling.h"
11 #include "llvm/CodeGen/InstrSelection.h"
12 #include "llvm/CodeGen/MachineCodeForInstruction.h"
13 #include "llvm/CodeGen/MachineCodeForMethod.h"
14 #include "llvm/CodeGen/RegisterAllocation.h"
15 #include "llvm/Function.h"
16 #include "llvm/BasicBlock.h"
17 #include "llvm/PassManager.h"
18 #include <iostream>
19 using std::cerr;
20
21 // Build the MachineInstruction Description Array...
22 const MachineInstrDescriptor SparcMachineInstrDesc[] = {
23 #define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
24           NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS)             \
25   { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE,             \
26           NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS },
27 #include "SparcInstr.def"
28 };
29
30 //----------------------------------------------------------------------------
31 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
32 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
33 //----------------------------------------------------------------------------
34
35 TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
36
37
38
39 //---------------------------------------------------------------------------
40 // class UltraSparcFrameInfo 
41 // 
42 // Purpose:
43 //   Interface to stack frame layout info for the UltraSPARC.
44 //   Starting offsets for each area of the stack frame are aligned at
45 //   a multiple of getStackFrameSizeAlignment().
46 //---------------------------------------------------------------------------
47
48 int
49 UltraSparcFrameInfo::getFirstAutomaticVarOffset(MachineCodeForMethod& ,
50                                                 bool& pos) const
51 {
52   pos = false;                          // static stack area grows downwards
53   return StaticAreaOffsetFromFP;
54 }
55
56 int
57 UltraSparcFrameInfo::getRegSpillAreaOffset(MachineCodeForMethod& mcInfo,
58                                            bool& pos) const
59 {
60   pos = false;                          // static stack area grows downwards
61   unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
62   if (int mod = autoVarsSize % getStackFrameSizeAlignment())  
63     autoVarsSize += (getStackFrameSizeAlignment() - mod);
64   return StaticAreaOffsetFromFP - autoVarsSize; 
65 }
66
67 int
68 UltraSparcFrameInfo::getTmpAreaOffset(MachineCodeForMethod& mcInfo,
69                                       bool& pos) const
70 {
71   pos = false;                          // static stack area grows downwards
72   unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
73   unsigned int spillAreaSize = mcInfo.getRegSpillsSize();
74   int offset = autoVarsSize + spillAreaSize;
75   if (int mod = offset % getStackFrameSizeAlignment())  
76     offset += (getStackFrameSizeAlignment() - mod);
77   return StaticAreaOffsetFromFP - offset;
78 }
79
80 int
81 UltraSparcFrameInfo::getDynamicAreaOffset(MachineCodeForMethod& mcInfo,
82                                           bool& pos) const
83 {
84   // Dynamic stack area grows downwards starting at top of opt-args area.
85   // The opt-args, required-args, and register-save areas are empty except
86   // during calls and traps, so they are shifted downwards on each
87   // dynamic-size alloca.
88   pos = false;
89   unsigned int optArgsSize = mcInfo.getMaxOptionalArgsSize();
90   int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
91   assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
92   return offset;
93 }
94
95
96 //---------------------------------------------------------------------------
97 // class UltraSparcMachine 
98 // 
99 // Purpose:
100 //   Primary interface to machine description for the UltraSPARC.
101 //   Primarily just initializes machine-dependent parameters in
102 //   class TargetMachine, and creates machine-dependent subclasses
103 //   for classes such as MachineInstrInfo. 
104 // 
105 //---------------------------------------------------------------------------
106
107 UltraSparc::UltraSparc()
108   : TargetMachine("UltraSparc-Native"),
109     instrInfo(*this),
110     schedInfo(*this),
111     regInfo(*this),
112     frameInfo(*this),
113     cacheInfo(*this)
114 {
115   optSizeForSubWordData = 4;
116   minMemOpWordSize = 8; 
117   maxAtomicMemOpWordSize = 8;
118 }
119
120
121
122 //===---------------------------------------------------------------------===//
123 // GenerateCodeForTarget Pass
124 // 
125 // Native code generation for a specified target.
126 //===---------------------------------------------------------------------===//
127
128 class ConstructMachineCodeForFunction : public MethodPass {
129   TargetMachine &Target;
130 public:
131   inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
132   bool runOnMethod(Function *F) {
133     MachineCodeForMethod::construct(F, Target);
134     return false;
135   }
136 };
137
138 class InstructionSelection : public MethodPass {
139   TargetMachine &Target;
140 public:
141   inline InstructionSelection(TargetMachine &T) : Target(T) {}
142   bool runOnMethod(Function *F) {
143     if (SelectInstructionsForMethod(F, Target)) {
144       cerr << "Instr selection failed for function " << F->getName() << "\n";
145       abort();
146     }
147     return false;
148   }
149 };
150
151 struct FreeMachineCodeForFunction : public MethodPass {
152   static void freeMachineCode(Instruction *I) {
153     MachineCodeForInstruction::destroy(I);
154   }
155   
156   bool runOnMethod(Function *F) {
157     for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
158       for (BasicBlock::iterator I = (*FI)->begin(), E = (*FI)->end();
159            I != E; ++I)
160         MachineCodeForInstruction::get(*I).dropAllReferences();
161     
162     for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
163       for (BasicBlock::iterator I = (*FI)->begin(), E = (*FI)->end();
164            I != E; ++I)
165         freeMachineCode(*I);
166     
167     return false;
168   }
169 };
170
171
172
173 // addPassesToEmitAssembly - This method controls the entire code generation
174 // process for the ultra sparc.
175 //
176 void UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) {
177   // Construct and initialize the MachineCodeForMethod object for this fn.
178   PM.add(new ConstructMachineCodeForFunction(*this));
179
180   PM.add(new InstructionSelection(*this));
181
182   PM.add(createInstructionSchedulingWithSSAPass(*this));
183
184   PM.add(getRegisterAllocator(*this));
185   
186   //PM.add(new OptimizeLeafProcedures());
187   //PM.add(new DeleteFallThroughBranches());
188   //PM.add(new RemoveChainedBranches());    // should be folded with previous
189   //PM.add(new RemoveRedundantOps());       // operations with %g0, NOP, etc.
190   
191   PM.add(createPrologEpilogCodeInserter(*this));
192   
193   // Output assembly language to the .s file.  Assembly emission is split into
194   // two parts: Function output and Global value output.  This is because
195   // function output is pipelined with all of the rest of code generation stuff,
196   // allowing machine code representations for functions to be free'd after the
197   // function has been emitted.
198   //
199   PM.add(getMethodAsmPrinterPass(PM, Out));
200   PM.add(new FreeMachineCodeForFunction());  // Free stuff no longer needed
201
202   // Emit Module level assembly after all of the functions have been processed.
203   PM.add(getModuleAsmPrinterPass(PM, Out));
204
205   // Emit bytecode to the sparc assembly file into its special section next
206   PM.add(getEmitBytecodeToAsmPass(Out));
207 }