1 //===-- Sparc.cpp - General implementation file for the Sparc Target ------===//
3 // This file contains the code for the Sparc Target that does not fit in any of
4 // the other files in this directory.
6 //===----------------------------------------------------------------------===//
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"
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"
30 //----------------------------------------------------------------------------
31 // allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
32 // that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
33 //----------------------------------------------------------------------------
35 TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
39 //---------------------------------------------------------------------------
40 // class UltraSparcFrameInfo
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 //---------------------------------------------------------------------------
49 UltraSparcFrameInfo::getFirstAutomaticVarOffset(MachineCodeForMethod& ,
52 pos = false; // static stack area grows downwards
53 return StaticAreaOffsetFromFP;
57 UltraSparcFrameInfo::getRegSpillAreaOffset(MachineCodeForMethod& mcInfo,
60 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
62 pos = false; // static stack area grows downwards
63 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
64 return StaticAreaOffsetFromFP - autoVarsSize;
68 UltraSparcFrameInfo::getTmpAreaOffset(MachineCodeForMethod& mcInfo,
71 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
72 mcInfo.freezeSpillsArea(); // ensure no more spill slots are added
74 pos = false; // static stack area grows downwards
75 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
76 unsigned int spillAreaSize = mcInfo.getRegSpillsSize();
77 int offset = autoVarsSize + spillAreaSize;
78 return StaticAreaOffsetFromFP - offset;
82 UltraSparcFrameInfo::getDynamicAreaOffset(MachineCodeForMethod& mcInfo,
85 // Dynamic stack area grows downwards starting at top of opt-args area.
86 // The opt-args, required-args, and register-save areas are empty except
87 // during calls and traps, so they are shifted downwards on each
88 // dynamic-size alloca.
90 unsigned int optArgsSize = mcInfo.getMaxOptionalArgsSize();
91 int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
92 assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
97 //---------------------------------------------------------------------------
98 // class UltraSparcMachine
101 // Primary interface to machine description for the UltraSPARC.
102 // Primarily just initializes machine-dependent parameters in
103 // class TargetMachine, and creates machine-dependent subclasses
104 // for classes such as MachineInstrInfo.
106 //---------------------------------------------------------------------------
108 UltraSparc::UltraSparc()
109 : TargetMachine("UltraSparc-Native"),
116 optSizeForSubWordData = 4;
117 minMemOpWordSize = 8;
118 maxAtomicMemOpWordSize = 8;
123 //===---------------------------------------------------------------------===//
124 // GenerateCodeForTarget Pass
126 // Native code generation for a specified target.
127 //===---------------------------------------------------------------------===//
129 class ConstructMachineCodeForFunction : public FunctionPass {
130 TargetMachine &Target;
132 inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
134 const char *getPassName() const {
135 return "Sparc ConstructMachineCodeForFunction";
138 bool runOnFunction(Function &F) {
139 MachineCodeForMethod::construct(&F, Target);
144 struct FreeMachineCodeForFunction : public FunctionPass {
145 const char *getPassName() const { return "Sparc FreeMachineCodeForFunction"; }
147 static void freeMachineCode(Instruction &I) {
148 MachineCodeForInstruction::destroy(&I);
151 bool runOnFunction(Function &F) {
152 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
153 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
154 MachineCodeForInstruction::get(I).dropAllReferences();
156 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
157 for_each(FI->begin(), FI->end(), freeMachineCode);
163 // addPassesToEmitAssembly - This method controls the entire code generation
164 // process for the ultra sparc.
166 void UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) {
167 // Construct and initialize the MachineCodeForMethod object for this fn.
168 PM.add(new ConstructMachineCodeForFunction(*this));
170 PM.add(createInstructionSelectionPass(*this));
172 PM.add(createInstructionSchedulingWithSSAPass(*this));
174 PM.add(getRegisterAllocator(*this));
176 //PM.add(new OptimizeLeafProcedures());
177 //PM.add(new DeleteFallThroughBranches());
178 //PM.add(new RemoveChainedBranches()); // should be folded with previous
179 //PM.add(new RemoveRedundantOps()); // operations with %g0, NOP, etc.
181 PM.add(createPrologEpilogCodeInserter(*this));
183 //PM.add(MappingInfoForFunction(Out));
185 // Output assembly language to the .s file. Assembly emission is split into
186 // two parts: Function output and Global value output. This is because
187 // function output is pipelined with all of the rest of code generation stuff,
188 // allowing machine code representations for functions to be free'd after the
189 // function has been emitted.
191 PM.add(getFunctionAsmPrinterPass(PM, Out));
192 PM.add(new FreeMachineCodeForFunction()); // Free stuff no longer needed
194 // Emit Module level assembly after all of the functions have been processed.
195 PM.add(getModuleAsmPrinterPass(PM, Out));
197 // Emit bytecode to the sparc assembly file into its special section next
198 PM.add(getEmitBytecodeToAsmPass(Out));