blob: 0fe8f1efcec7329c90124d610b57f4e50be2d560 [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. Adve7f37fe52001-11-08 04:55:13 +000060 pos = false; // static stack area grows downwards
61 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000062 if (int mod = autoVarsSize % getStackFrameSizeAlignment())
63 autoVarsSize += (getStackFrameSizeAlignment() - mod);
64 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. Adve7f37fe52001-11-08 04:55:13 +000071 pos = false; // static stack area grows downwards
72 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
73 unsigned int spillAreaSize = mcInfo.getRegSpillsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000074 int offset = autoVarsSize + spillAreaSize;
75 if (int mod = offset % getStackFrameSizeAlignment())
76 offset += (getStackFrameSizeAlignment() - mod);
77 return StaticAreaOffsetFromFP - offset;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000078}
79
80int
81UltraSparcFrameInfo::getDynamicAreaOffset(MachineCodeForMethod& mcInfo,
82 bool& pos) const
83{
Vikram S. Advee6d2c412002-03-18 03:08:07 +000084 // 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;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000089 unsigned int optArgsSize = mcInfo.getMaxOptionalArgsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000090 int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
Vikram S. Advee6d2c412002-03-18 03:08:07 +000091 assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
Vikram S. Adve00521d72001-11-12 23:26:35 +000092 return offset;
Vikram S. Adve9db43182001-10-22 13:44:23 +000093}
94
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000095
Chris Lattner20b1ea02001-09-14 03:47:57 +000096//---------------------------------------------------------------------------
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
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000107UltraSparc::UltraSparc()
108 : TargetMachine("UltraSparc-Native"),
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000109 instrInfo(*this),
110 schedInfo(*this),
111 regInfo(*this),
Vikram S. Adveb7048402001-11-09 02:16:04 +0000112 frameInfo(*this),
113 cacheInfo(*this)
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000114{
Chris Lattner20b1ea02001-09-14 03:47:57 +0000115 optSizeForSubWordData = 4;
116 minMemOpWordSize = 8;
117 maxAtomicMemOpWordSize = 8;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000118}
119
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000120
Chris Lattner0feb3582002-02-03 23:41:51 +0000121
122//===---------------------------------------------------------------------===//
123// GenerateCodeForTarget Pass
124//
125// Native code generation for a specified target.
126//===---------------------------------------------------------------------===//
127
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000128class ConstructMachineCodeForFunction : public MethodPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000129 TargetMachine &Target;
130public:
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000131 inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
132 bool runOnMethod(Function *F) {
133 MachineCodeForMethod::construct(F, Target);
Chris Lattner0feb3582002-02-03 23:41:51 +0000134 return false;
135 }
136};
137
138class InstructionSelection : public MethodPass {
139 TargetMachine &Target;
140public:
141 inline InstructionSelection(TargetMachine &T) : Target(T) {}
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000142 bool runOnMethod(Function *F) {
143 if (SelectInstructionsForMethod(F, Target)) {
144 cerr << "Instr selection failed for function " << F->getName() << "\n";
145 abort();
146 }
Chris Lattner0feb3582002-02-03 23:41:51 +0000147 return false;
148 }
149};
150
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000151struct FreeMachineCodeForFunction : public MethodPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000152 static void freeMachineCode(Instruction *I) {
153 MachineCodeForInstruction::destroy(I);
154 }
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000155
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000156 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();
Chris Lattner221d6882002-02-12 21:07:25 +0000159 I != E; ++I)
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000160 MachineCodeForInstruction::get(*I).dropAllReferences();
161
Chris Lattnerb7653df2002-04-08 22:03:57 +0000162 for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000163 for (BasicBlock::iterator I = (*FI)->begin(), E = (*FI)->end();
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000164 I != E; ++I)
Chris Lattner221d6882002-02-12 21:07:25 +0000165 freeMachineCode(*I);
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000166
Chris Lattner0feb3582002-02-03 23:41:51 +0000167 return false;
168 }
169};
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000170
171
Chris Lattner6b04e712002-02-04 00:39:14 +0000172
173// addPassesToEmitAssembly - This method controls the entire code generation
174// process for the ultra sparc.
175//
Chris Lattner0feb3582002-02-03 23:41:51 +0000176void UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) {
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000177 // Construct and initialize the MachineCodeForMethod object for this fn.
178 PM.add(new ConstructMachineCodeForFunction(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000179
Chris Lattner0feb3582002-02-03 23:41:51 +0000180 PM.add(new InstructionSelection(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000181
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000182 PM.add(createInstructionSchedulingWithSSAPass(*this));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000183
Chris Lattner2f9b28e2002-02-04 15:54:09 +0000184 PM.add(getRegisterAllocator(*this));
Chris Lattner0feb3582002-02-03 23:41:51 +0000185
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
Chris Lattner1d21f3e2002-04-09 05:21:26 +0000191 PM.add(createPrologEpilogCodeInserter(*this));
Chris Lattner0feb3582002-02-03 23:41:51 +0000192
193 // Output assembly language to the .s file. Assembly emission is split into
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000194 // 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.
Chris Lattner0feb3582002-02-03 23:41:51 +0000198 //
199 PM.add(getMethodAsmPrinterPass(PM, Out));
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000200 PM.add(new FreeMachineCodeForFunction()); // Free stuff no longer needed
Chris Lattnercf4525b2002-02-03 07:49:15 +0000201
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000202 // Emit Module level assembly after all of the functions have been processed.
Chris Lattner0feb3582002-02-03 23:41:51 +0000203 PM.add(getModuleAsmPrinterPass(PM, Out));
Chris Lattner9530a6f2002-02-11 22:35:46 +0000204
205 // Emit bytecode to the sparc assembly file into its special section next
206 PM.add(getEmitBytecodeToAsmPass(Out));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000207}