blob: de778e25628a5f1c67799fbd612648a08112895b [file] [log] [blame]
Chris Lattner1d21f3e2002-04-09 05:21:26 +00001//===-- 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//===----------------------------------------------------------------------===//
Vikram S. Adve9db43182001-10-22 13:44:23 +00007
Chris Lattner20b1ea02001-09-14 03:47:57 +00008#include "SparcInternals.h"
Vikram S. Adve9db43182001-10-22 13:44:23 +00009#include "llvm/Target/Sparc.h"
Chris Lattner20b1ea02001-09-14 03:47:57 +000010#include "llvm/CodeGen/InstrScheduling.h"
11#include "llvm/CodeGen/InstrSelection.h"
Chris Lattnercf4525b2002-02-03 07:49:15 +000012#include "llvm/CodeGen/MachineCodeForInstruction.h"
13#include "llvm/CodeGen/MachineCodeForMethod.h"
Chris Lattner6dd98a62002-02-04 00:33:08 +000014#include "llvm/CodeGen/RegisterAllocation.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000015#include "llvm/Function.h"
Chris Lattner221d6882002-02-12 21:07:25 +000016#include "llvm/BasicBlock.h"
Chris Lattner0feb3582002-02-03 23:41:51 +000017#include "llvm/PassManager.h"
Chris Lattner697954c2002-01-20 22:54:45 +000018#include <iostream>
19using std::cerr;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000020
Chris Lattner9a3d63b2001-09-19 15:56:23 +000021// Build the MachineInstruction Description Array...
22const 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};
Vikram S. Adve0fb49802001-09-18 13:01:29 +000029
30//----------------------------------------------------------------------------
Chris Lattner46cbff62001-09-14 16:56:32 +000031// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
32// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
Vikram S. Adve0fb49802001-09-18 13:01:29 +000033//----------------------------------------------------------------------------
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +000034
Chris Lattner46cbff62001-09-14 16:56:32 +000035TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
Chris Lattner20b1ea02001-09-14 03:47:57 +000036
37
Vikram S. Adve9db43182001-10-22 13:44:23 +000038
Vikram S. Adve9db43182001-10-22 13:44:23 +000039//---------------------------------------------------------------------------
40// class UltraSparcFrameInfo
41//
42// Purpose:
43// Interface to stack frame layout info for the UltraSPARC.
Vikram S. Adve00521d72001-11-12 23:26:35 +000044// Starting offsets for each area of the stack frame are aligned at
45// a multiple of getStackFrameSizeAlignment().
Vikram S. Adve9db43182001-10-22 13:44:23 +000046//---------------------------------------------------------------------------
47
48int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000049UltraSparcFrameInfo::getFirstAutomaticVarOffset(MachineCodeForMethod& ,
50 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000051{
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000052 pos = false; // static stack area grows downwards
53 return StaticAreaOffsetFromFP;
Vikram S. Adve9db43182001-10-22 13:44:23 +000054}
55
56int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000057UltraSparcFrameInfo::getRegSpillAreaOffset(MachineCodeForMethod& mcInfo,
58 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000059{
Vikram S. Adve0bc05162002-04-25 04:43:45 +000060 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
61
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000062 pos = false; // static stack area grows downwards
63 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000064 return StaticAreaOffsetFromFP - autoVarsSize;
Vikram S. Adve9db43182001-10-22 13:44:23 +000065}
66
67int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000068UltraSparcFrameInfo::getTmpAreaOffset(MachineCodeForMethod& mcInfo,
69 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000070{
Vikram S. Adve0bc05162002-04-25 04:43:45 +000071 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
72 mcInfo.freezeSpillsArea(); // ensure no more spill slots are added
73
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000074 pos = false; // static stack area grows downwards
75 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
76 unsigned int spillAreaSize = mcInfo.getRegSpillsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000077 int offset = autoVarsSize + spillAreaSize;
Vikram S. Adve00521d72001-11-12 23:26:35 +000078 return StaticAreaOffsetFromFP - offset;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000079}
80
81int
82UltraSparcFrameInfo::getDynamicAreaOffset(MachineCodeForMethod& mcInfo,
83 bool& pos) const
84{
Vikram S. Advee6d2c412002-03-18 03:08:07 +000085 // 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.
89 pos = false;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000090 unsigned int optArgsSize = mcInfo.getMaxOptionalArgsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000091 int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
Vikram S. Advee6d2c412002-03-18 03:08:07 +000092 assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
Vikram S. Adve00521d72001-11-12 23:26:35 +000093 return offset;
Vikram S. Adve9db43182001-10-22 13:44:23 +000094}
95
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000096
Chris Lattner20b1ea02001-09-14 03:47:57 +000097//---------------------------------------------------------------------------
98// class UltraSparcMachine
99//
100// Purpose:
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.
105//
106//---------------------------------------------------------------------------
107
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000108UltraSparc::UltraSparc()
109 : TargetMachine("UltraSparc-Native"),
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000110 instrInfo(*this),
111 schedInfo(*this),
112 regInfo(*this),
Vikram S. Adveb7048402001-11-09 02:16:04 +0000113 frameInfo(*this),
114 cacheInfo(*this)
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000115{
Chris Lattner20b1ea02001-09-14 03:47:57 +0000116 optSizeForSubWordData = 4;
117 minMemOpWordSize = 8;
118 maxAtomicMemOpWordSize = 8;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000119}
120
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000121
Chris Lattner0feb3582002-02-03 23:41:51 +0000122
123//===---------------------------------------------------------------------===//
124// GenerateCodeForTarget Pass
125//
126// Native code generation for a specified target.
127//===---------------------------------------------------------------------===//
128
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000129class ConstructMachineCodeForFunction : public MethodPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000130 TargetMachine &Target;
131public:
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000132 inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
133 bool runOnMethod(Function *F) {
134 MachineCodeForMethod::construct(F, Target);
Chris Lattner0feb3582002-02-03 23:41:51 +0000135 return false;
136 }
137};
138
139class InstructionSelection : public MethodPass {
140 TargetMachine &Target;
141public:
142 inline InstructionSelection(TargetMachine &T) : Target(T) {}
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000143 bool runOnMethod(Function *F) {
144 if (SelectInstructionsForMethod(F, Target)) {
145 cerr << "Instr selection failed for function " << F->getName() << "\n";
146 abort();
147 }
Chris Lattner0feb3582002-02-03 23:41:51 +0000148 return false;
149 }
150};
151
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000152struct FreeMachineCodeForFunction : public MethodPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000153 static void freeMachineCode(Instruction *I) {
154 MachineCodeForInstruction::destroy(I);
155 }
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000156
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000157 bool runOnMethod(Function *F) {
158 for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
159 for (BasicBlock::iterator I = (*FI)->begin(), E = (*FI)->end();
Chris Lattner221d6882002-02-12 21:07:25 +0000160 I != E; ++I)
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000161 MachineCodeForInstruction::get(*I).dropAllReferences();
162
Chris Lattnerb7653df2002-04-08 22:03:57 +0000163 for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000164 for (BasicBlock::iterator I = (*FI)->begin(), E = (*FI)->end();
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000165 I != E; ++I)
Chris Lattner221d6882002-02-12 21:07:25 +0000166 freeMachineCode(*I);
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000167
Chris Lattner0feb3582002-02-03 23:41:51 +0000168 return false;
169 }
170};
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000171
172
Chris Lattner6b04e712002-02-04 00:39:14 +0000173
174// addPassesToEmitAssembly - This method controls the entire code generation
175// process for the ultra sparc.
176//
Chris Lattner0feb3582002-02-03 23:41:51 +0000177void UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) {
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000178 // Construct and initialize the MachineCodeForMethod object for this fn.
179 PM.add(new ConstructMachineCodeForFunction(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000180
Chris Lattner0feb3582002-02-03 23:41:51 +0000181 PM.add(new InstructionSelection(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000182
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000183 PM.add(createInstructionSchedulingWithSSAPass(*this));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000184
Chris Lattner2f9b28e2002-02-04 15:54:09 +0000185 PM.add(getRegisterAllocator(*this));
Chris Lattner0feb3582002-02-03 23:41:51 +0000186
187 //PM.add(new OptimizeLeafProcedures());
188 //PM.add(new DeleteFallThroughBranches());
189 //PM.add(new RemoveChainedBranches()); // should be folded with previous
190 //PM.add(new RemoveRedundantOps()); // operations with %g0, NOP, etc.
191
Chris Lattner1d21f3e2002-04-09 05:21:26 +0000192 PM.add(createPrologEpilogCodeInserter(*this));
Chris Lattner0feb3582002-02-03 23:41:51 +0000193
194 // Output assembly language to the .s file. Assembly emission is split into
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000195 // two parts: Function output and Global value output. This is because
196 // function output is pipelined with all of the rest of code generation stuff,
197 // allowing machine code representations for functions to be free'd after the
198 // function has been emitted.
Chris Lattner0feb3582002-02-03 23:41:51 +0000199 //
200 PM.add(getMethodAsmPrinterPass(PM, Out));
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000201 PM.add(new FreeMachineCodeForFunction()); // Free stuff no longer needed
Chris Lattnercf4525b2002-02-03 07:49:15 +0000202
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000203 // Emit Module level assembly after all of the functions have been processed.
Chris Lattner0feb3582002-02-03 23:41:51 +0000204 PM.add(getModuleAsmPrinterPass(PM, Out));
Chris Lattner9530a6f2002-02-11 22:35:46 +0000205
206 // Emit bytecode to the sparc assembly file into its special section next
207 PM.add(getEmitBytecodeToAsmPass(Out));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000208}