blob: be6e9f4670de70bc3c31a342c63b75c58512bdda [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 Lattnerf57b8452002-04-27 06:56:12 +0000129class ConstructMachineCodeForFunction : public FunctionPass {
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) {}
Chris Lattner96c466b2002-04-29 14:57:45 +0000133
134 const char *getPassName() const {
135 return "Sparc ConstructMachineCodeForFunction";
136 }
137
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000138 bool runOnFunction(Function &F) {
139 MachineCodeForMethod::construct(&F, Target);
Chris Lattner0feb3582002-02-03 23:41:51 +0000140 return false;
141 }
142};
143
Chris Lattnerf57b8452002-04-27 06:56:12 +0000144class InstructionSelection : public FunctionPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000145 TargetMachine &Target;
146public:
147 inline InstructionSelection(TargetMachine &T) : Target(T) {}
Chris Lattner96c466b2002-04-29 14:57:45 +0000148 const char *getPassName() const { return "Sparc Instruction Selection"; }
149
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000150 bool runOnFunction(Function &F) {
151 if (SelectInstructionsForMethod(&F, Target)) {
152 cerr << "Instr selection failed for function " << F.getName() << "\n";
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000153 abort();
154 }
Chris Lattner0feb3582002-02-03 23:41:51 +0000155 return false;
156 }
157};
158
Chris Lattnerf57b8452002-04-27 06:56:12 +0000159struct FreeMachineCodeForFunction : public FunctionPass {
Chris Lattner96c466b2002-04-29 14:57:45 +0000160 const char *getPassName() const { return "Sparc FreeMachineCodeForFunction"; }
161
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000162 static void freeMachineCode(Instruction &I) {
163 MachineCodeForInstruction::destroy(&I);
Chris Lattner0feb3582002-02-03 23:41:51 +0000164 }
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000165
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000166 bool runOnFunction(Function &F) {
167 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
168 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
169 MachineCodeForInstruction::get(I).dropAllReferences();
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000170
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000171 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
172 for_each(FI->begin(), FI->end(), freeMachineCode);
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000173
Chris Lattner0feb3582002-02-03 23:41:51 +0000174 return false;
175 }
176};
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000177
178
Chris Lattner6b04e712002-02-04 00:39:14 +0000179
180// addPassesToEmitAssembly - This method controls the entire code generation
181// process for the ultra sparc.
182//
Chris Lattner0feb3582002-02-03 23:41:51 +0000183void UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) {
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000184 // Construct and initialize the MachineCodeForMethod object for this fn.
185 PM.add(new ConstructMachineCodeForFunction(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000186
Chris Lattner0feb3582002-02-03 23:41:51 +0000187 PM.add(new InstructionSelection(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000188
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000189 PM.add(createInstructionSchedulingWithSSAPass(*this));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000190
Chris Lattner2f9b28e2002-02-04 15:54:09 +0000191 PM.add(getRegisterAllocator(*this));
Chris Lattner0feb3582002-02-03 23:41:51 +0000192
193 //PM.add(new OptimizeLeafProcedures());
194 //PM.add(new DeleteFallThroughBranches());
195 //PM.add(new RemoveChainedBranches()); // should be folded with previous
196 //PM.add(new RemoveRedundantOps()); // operations with %g0, NOP, etc.
197
Chris Lattner1d21f3e2002-04-09 05:21:26 +0000198 PM.add(createPrologEpilogCodeInserter(*this));
Chris Lattner0feb3582002-02-03 23:41:51 +0000199
200 // Output assembly language to the .s file. Assembly emission is split into
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000201 // two parts: Function output and Global value output. This is because
202 // function output is pipelined with all of the rest of code generation stuff,
203 // allowing machine code representations for functions to be free'd after the
204 // function has been emitted.
Chris Lattner0feb3582002-02-03 23:41:51 +0000205 //
Chris Lattnerf57b8452002-04-27 06:56:12 +0000206 PM.add(getFunctionAsmPrinterPass(PM, Out));
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000207 PM.add(new FreeMachineCodeForFunction()); // Free stuff no longer needed
Chris Lattnercf4525b2002-02-03 07:49:15 +0000208
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000209 // Emit Module level assembly after all of the functions have been processed.
Chris Lattner0feb3582002-02-03 23:41:51 +0000210 PM.add(getModuleAsmPrinterPass(PM, Out));
Chris Lattner9530a6f2002-02-11 22:35:46 +0000211
212 // Emit bytecode to the sparc assembly file into its special section next
213 PM.add(getEmitBytecodeToAsmPass(Out));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000214}