blob: a3dd8c883512d261ba082458ae58e6da601bcdad [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"
Mehwish Nagda634cd1c2002-07-15 23:58:21 +000015#include "llvm/CodeGen/MappingInfo.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000016#include "llvm/Function.h"
Chris Lattner221d6882002-02-12 21:07:25 +000017#include "llvm/BasicBlock.h"
Chris Lattner0feb3582002-02-03 23:41:51 +000018#include "llvm/PassManager.h"
Chris Lattner697954c2002-01-20 22:54:45 +000019#include <iostream>
20using std::cerr;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000021
Chris Lattner9a3d63b2001-09-19 15:56:23 +000022// Build the MachineInstruction Description Array...
23const MachineInstrDescriptor SparcMachineInstrDesc[] = {
24#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
25 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
26 { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
27 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS },
28#include "SparcInstr.def"
29};
Vikram S. Adve0fb49802001-09-18 13:01:29 +000030
31//----------------------------------------------------------------------------
Chris Lattner46cbff62001-09-14 16:56:32 +000032// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
33// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
Vikram S. Adve0fb49802001-09-18 13:01:29 +000034//----------------------------------------------------------------------------
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +000035
Chris Lattner46cbff62001-09-14 16:56:32 +000036TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
Chris Lattner20b1ea02001-09-14 03:47:57 +000037
38
Vikram S. Adve9db43182001-10-22 13:44:23 +000039
Vikram S. Adve9db43182001-10-22 13:44:23 +000040//---------------------------------------------------------------------------
41// class UltraSparcFrameInfo
42//
43// Purpose:
44// Interface to stack frame layout info for the UltraSPARC.
Vikram S. Adve00521d72001-11-12 23:26:35 +000045// Starting offsets for each area of the stack frame are aligned at
46// a multiple of getStackFrameSizeAlignment().
Vikram S. Adve9db43182001-10-22 13:44:23 +000047//---------------------------------------------------------------------------
48
49int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000050UltraSparcFrameInfo::getFirstAutomaticVarOffset(MachineCodeForMethod& ,
51 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000052{
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000053 pos = false; // static stack area grows downwards
54 return StaticAreaOffsetFromFP;
Vikram S. Adve9db43182001-10-22 13:44:23 +000055}
56
57int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000058UltraSparcFrameInfo::getRegSpillAreaOffset(MachineCodeForMethod& mcInfo,
59 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000060{
Vikram S. Adve0bc05162002-04-25 04:43:45 +000061 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
62
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000063 pos = false; // static stack area grows downwards
64 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000065 return StaticAreaOffsetFromFP - autoVarsSize;
Vikram S. Adve9db43182001-10-22 13:44:23 +000066}
67
68int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000069UltraSparcFrameInfo::getTmpAreaOffset(MachineCodeForMethod& mcInfo,
70 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000071{
Vikram S. Adve0bc05162002-04-25 04:43:45 +000072 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
73 mcInfo.freezeSpillsArea(); // ensure no more spill slots are added
74
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000075 pos = false; // static stack area grows downwards
76 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
77 unsigned int spillAreaSize = mcInfo.getRegSpillsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000078 int offset = autoVarsSize + spillAreaSize;
Vikram S. Adve00521d72001-11-12 23:26:35 +000079 return StaticAreaOffsetFromFP - offset;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000080}
81
82int
83UltraSparcFrameInfo::getDynamicAreaOffset(MachineCodeForMethod& mcInfo,
84 bool& pos) const
85{
Vikram S. Advee6d2c412002-03-18 03:08:07 +000086 // Dynamic stack area grows downwards starting at top of opt-args area.
87 // The opt-args, required-args, and register-save areas are empty except
88 // during calls and traps, so they are shifted downwards on each
89 // dynamic-size alloca.
90 pos = false;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000091 unsigned int optArgsSize = mcInfo.getMaxOptionalArgsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000092 int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
Vikram S. Advee6d2c412002-03-18 03:08:07 +000093 assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
Vikram S. Adve00521d72001-11-12 23:26:35 +000094 return offset;
Vikram S. Adve9db43182001-10-22 13:44:23 +000095}
96
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000097
Chris Lattner20b1ea02001-09-14 03:47:57 +000098//---------------------------------------------------------------------------
99// class UltraSparcMachine
100//
101// Purpose:
102// Primary interface to machine description for the UltraSPARC.
103// Primarily just initializes machine-dependent parameters in
104// class TargetMachine, and creates machine-dependent subclasses
105// for classes such as MachineInstrInfo.
106//
107//---------------------------------------------------------------------------
108
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000109UltraSparc::UltraSparc()
110 : TargetMachine("UltraSparc-Native"),
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000111 instrInfo(*this),
112 schedInfo(*this),
113 regInfo(*this),
Vikram S. Adveb7048402001-11-09 02:16:04 +0000114 frameInfo(*this),
115 cacheInfo(*this)
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000116{
Chris Lattner20b1ea02001-09-14 03:47:57 +0000117 optSizeForSubWordData = 4;
118 minMemOpWordSize = 8;
119 maxAtomicMemOpWordSize = 8;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000120}
121
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000122
Chris Lattner0feb3582002-02-03 23:41:51 +0000123
124//===---------------------------------------------------------------------===//
125// GenerateCodeForTarget Pass
126//
127// Native code generation for a specified target.
128//===---------------------------------------------------------------------===//
129
Chris Lattnerf57b8452002-04-27 06:56:12 +0000130class ConstructMachineCodeForFunction : public FunctionPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000131 TargetMachine &Target;
132public:
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000133 inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
Chris Lattner96c466b2002-04-29 14:57:45 +0000134
135 const char *getPassName() const {
136 return "Sparc ConstructMachineCodeForFunction";
137 }
138
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000139 bool runOnFunction(Function &F) {
140 MachineCodeForMethod::construct(&F, Target);
Chris Lattner0feb3582002-02-03 23:41:51 +0000141 return false;
142 }
143};
144
Chris Lattnerf57b8452002-04-27 06:56:12 +0000145class InstructionSelection : public FunctionPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000146 TargetMachine &Target;
147public:
148 inline InstructionSelection(TargetMachine &T) : Target(T) {}
Chris Lattner96c466b2002-04-29 14:57:45 +0000149 const char *getPassName() const { return "Sparc Instruction Selection"; }
150
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000151 bool runOnFunction(Function &F) {
152 if (SelectInstructionsForMethod(&F, Target)) {
153 cerr << "Instr selection failed for function " << F.getName() << "\n";
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000154 abort();
155 }
Chris Lattner0feb3582002-02-03 23:41:51 +0000156 return false;
157 }
158};
159
Mehwish Nagda634cd1c2002-07-15 23:58:21 +0000160
Chris Lattnerf57b8452002-04-27 06:56:12 +0000161struct FreeMachineCodeForFunction : public FunctionPass {
Chris Lattner96c466b2002-04-29 14:57:45 +0000162 const char *getPassName() const { return "Sparc FreeMachineCodeForFunction"; }
163
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000164 static void freeMachineCode(Instruction &I) {
165 MachineCodeForInstruction::destroy(&I);
Chris Lattner0feb3582002-02-03 23:41:51 +0000166 }
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000167
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000168 bool runOnFunction(Function &F) {
169 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
170 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
171 MachineCodeForInstruction::get(I).dropAllReferences();
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000172
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000173 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
174 for_each(FI->begin(), FI->end(), freeMachineCode);
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000175
Chris Lattner0feb3582002-02-03 23:41:51 +0000176 return false;
177 }
178};
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000179
Chris Lattner6b04e712002-02-04 00:39:14 +0000180// 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));
Mehwish Nagda634cd1c2002-07-15 23:58:21 +0000199
200 PM.add(MappingInfoForFunction(Out));
201
Chris Lattner0feb3582002-02-03 23:41:51 +0000202 // Output assembly language to the .s file. Assembly emission is split into
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000203 // two parts: Function output and Global value output. This is because
204 // function output is pipelined with all of the rest of code generation stuff,
205 // allowing machine code representations for functions to be free'd after the
206 // function has been emitted.
Chris Lattner0feb3582002-02-03 23:41:51 +0000207 //
Chris Lattnerf57b8452002-04-27 06:56:12 +0000208 PM.add(getFunctionAsmPrinterPass(PM, Out));
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000209 PM.add(new FreeMachineCodeForFunction()); // Free stuff no longer needed
Chris Lattnercf4525b2002-02-03 07:49:15 +0000210
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000211 // Emit Module level assembly after all of the functions have been processed.
Chris Lattner0feb3582002-02-03 23:41:51 +0000212 PM.add(getModuleAsmPrinterPass(PM, Out));
Chris Lattner9530a6f2002-02-11 22:35:46 +0000213
214 // Emit bytecode to the sparc assembly file into its special section next
215 PM.add(getEmitBytecodeToAsmPass(Out));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000216}
Mehwish Nagda634cd1c2002-07-15 23:58:21 +0000217