blob: be9159a86cc782e9d768fc59c6a9212b96d66593 [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 Nagda5acd1662002-08-05 23:23:19 +000015#include "llvm/Reoptimizer/Mapping/MappingInfo.h"
16#include "llvm/Reoptimizer/Mapping/FInfo.h"
Chris Lattner2fbfdcf2002-04-07 20:49:59 +000017#include "llvm/Function.h"
Chris Lattner221d6882002-02-12 21:07:25 +000018#include "llvm/BasicBlock.h"
Chris Lattner0feb3582002-02-03 23:41:51 +000019#include "llvm/PassManager.h"
Chris Lattner697954c2002-01-20 22:54:45 +000020#include <iostream>
21using std::cerr;
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000022
Chris Lattner9a3d63b2001-09-19 15:56:23 +000023// Build the MachineInstruction Description Array...
24const MachineInstrDescriptor SparcMachineInstrDesc[] = {
25#define I(ENUM, OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
26 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS) \
27 { OPCODESTRING, NUMOPERANDS, RESULTPOS, MAXIMM, IMMSE, \
28 NUMDELAYSLOTS, LATENCY, SCHEDCLASS, INSTFLAGS },
29#include "SparcInstr.def"
30};
Vikram S. Adve0fb49802001-09-18 13:01:29 +000031
32//----------------------------------------------------------------------------
Chris Lattner46cbff62001-09-14 16:56:32 +000033// allocateSparcTargetMachine - Allocate and return a subclass of TargetMachine
34// that implements the Sparc backend. (the llvm/CodeGen/Sparc.h interface)
Vikram S. Adve0fb49802001-09-18 13:01:29 +000035//----------------------------------------------------------------------------
Ruchira Sasankacc3ccac2001-10-15 16:25:28 +000036
Chris Lattner46cbff62001-09-14 16:56:32 +000037TargetMachine *allocateSparcTargetMachine() { return new UltraSparc(); }
Chris Lattner20b1ea02001-09-14 03:47:57 +000038
39
Vikram S. Adve9db43182001-10-22 13:44:23 +000040
Vikram S. Adve9db43182001-10-22 13:44:23 +000041//---------------------------------------------------------------------------
42// class UltraSparcFrameInfo
43//
44// Purpose:
45// Interface to stack frame layout info for the UltraSPARC.
Vikram S. Adve00521d72001-11-12 23:26:35 +000046// Starting offsets for each area of the stack frame are aligned at
47// a multiple of getStackFrameSizeAlignment().
Vikram S. Adve9db43182001-10-22 13:44:23 +000048//---------------------------------------------------------------------------
49
50int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000051UltraSparcFrameInfo::getFirstAutomaticVarOffset(MachineCodeForMethod& ,
52 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000053{
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000054 pos = false; // static stack area grows downwards
55 return StaticAreaOffsetFromFP;
Vikram S. Adve9db43182001-10-22 13:44:23 +000056}
57
58int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000059UltraSparcFrameInfo::getRegSpillAreaOffset(MachineCodeForMethod& mcInfo,
60 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000061{
Vikram S. Adve0bc05162002-04-25 04:43:45 +000062 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
63
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000064 pos = false; // static stack area grows downwards
65 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000066 return StaticAreaOffsetFromFP - autoVarsSize;
Vikram S. Adve9db43182001-10-22 13:44:23 +000067}
68
69int
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000070UltraSparcFrameInfo::getTmpAreaOffset(MachineCodeForMethod& mcInfo,
71 bool& pos) const
Vikram S. Adve9db43182001-10-22 13:44:23 +000072{
Vikram S. Adve0bc05162002-04-25 04:43:45 +000073 mcInfo.freezeAutomaticVarsArea(); // ensure no more auto vars are added
74 mcInfo.freezeSpillsArea(); // ensure no more spill slots are added
75
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000076 pos = false; // static stack area grows downwards
77 unsigned int autoVarsSize = mcInfo.getAutomaticVarsSize();
78 unsigned int spillAreaSize = mcInfo.getRegSpillsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000079 int offset = autoVarsSize + spillAreaSize;
Vikram S. Adve00521d72001-11-12 23:26:35 +000080 return StaticAreaOffsetFromFP - offset;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000081}
82
83int
84UltraSparcFrameInfo::getDynamicAreaOffset(MachineCodeForMethod& mcInfo,
85 bool& pos) const
86{
Vikram S. Advee6d2c412002-03-18 03:08:07 +000087 // Dynamic stack area grows downwards starting at top of opt-args area.
88 // The opt-args, required-args, and register-save areas are empty except
89 // during calls and traps, so they are shifted downwards on each
90 // dynamic-size alloca.
91 pos = false;
Vikram S. Adve7f37fe52001-11-08 04:55:13 +000092 unsigned int optArgsSize = mcInfo.getMaxOptionalArgsSize();
Vikram S. Adve00521d72001-11-12 23:26:35 +000093 int offset = optArgsSize + FirstOptionalOutgoingArgOffsetFromSP;
Vikram S. Advee6d2c412002-03-18 03:08:07 +000094 assert((offset - OFFSET) % getStackFrameSizeAlignment() == 0);
Vikram S. Adve00521d72001-11-12 23:26:35 +000095 return offset;
Vikram S. Adve9db43182001-10-22 13:44:23 +000096}
97
Ruchira Sasankae38bd5332001-09-15 00:30:44 +000098
Chris Lattner20b1ea02001-09-14 03:47:57 +000099//---------------------------------------------------------------------------
100// class UltraSparcMachine
101//
102// Purpose:
103// Primary interface to machine description for the UltraSPARC.
104// Primarily just initializes machine-dependent parameters in
105// class TargetMachine, and creates machine-dependent subclasses
106// for classes such as MachineInstrInfo.
107//
108//---------------------------------------------------------------------------
109
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000110UltraSparc::UltraSparc()
111 : TargetMachine("UltraSparc-Native"),
Vikram S. Adve7f37fe52001-11-08 04:55:13 +0000112 instrInfo(*this),
113 schedInfo(*this),
114 regInfo(*this),
Vikram S. Adveb7048402001-11-09 02:16:04 +0000115 frameInfo(*this),
116 cacheInfo(*this)
Vikram S. Adve0fb49802001-09-18 13:01:29 +0000117{
Chris Lattner20b1ea02001-09-14 03:47:57 +0000118 optSizeForSubWordData = 4;
119 minMemOpWordSize = 8;
120 maxAtomicMemOpWordSize = 8;
Chris Lattner20b1ea02001-09-14 03:47:57 +0000121}
122
Ruchira Sasankae38bd5332001-09-15 00:30:44 +0000123
Chris Lattner0feb3582002-02-03 23:41:51 +0000124
125//===---------------------------------------------------------------------===//
126// GenerateCodeForTarget Pass
127//
128// Native code generation for a specified target.
129//===---------------------------------------------------------------------===//
130
Chris Lattnerf57b8452002-04-27 06:56:12 +0000131class ConstructMachineCodeForFunction : public FunctionPass {
Chris Lattner0feb3582002-02-03 23:41:51 +0000132 TargetMachine &Target;
133public:
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000134 inline ConstructMachineCodeForFunction(TargetMachine &T) : Target(T) {}
Chris Lattner96c466b2002-04-29 14:57:45 +0000135
136 const char *getPassName() const {
137 return "Sparc ConstructMachineCodeForFunction";
138 }
139
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000140 bool runOnFunction(Function &F) {
141 MachineCodeForMethod::construct(&F, Target);
Chris Lattner0feb3582002-02-03 23:41:51 +0000142 return false;
143 }
144};
145
Chris Lattnerf57b8452002-04-27 06:56:12 +0000146struct FreeMachineCodeForFunction : public FunctionPass {
Chris Lattner96c466b2002-04-29 14:57:45 +0000147 const char *getPassName() const { return "Sparc FreeMachineCodeForFunction"; }
148
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000149 static void freeMachineCode(Instruction &I) {
150 MachineCodeForInstruction::destroy(&I);
Chris Lattner0feb3582002-02-03 23:41:51 +0000151 }
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000152
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000153 bool runOnFunction(Function &F) {
154 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
155 for (BasicBlock::iterator I = FI->begin(), E = FI->end(); I != E; ++I)
156 MachineCodeForInstruction::get(I).dropAllReferences();
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000157
Chris Lattner0b12b5f2002-06-25 16:13:21 +0000158 for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI)
159 for_each(FI->begin(), FI->end(), freeMachineCode);
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000160
Chris Lattner0feb3582002-02-03 23:41:51 +0000161 return false;
162 }
163};
Ruchira Sasanka89fb46b2001-09-18 22:52:44 +0000164
Chris Lattner6b04e712002-02-04 00:39:14 +0000165// addPassesToEmitAssembly - This method controls the entire code generation
166// process for the ultra sparc.
167//
Chris Lattner0feb3582002-02-03 23:41:51 +0000168void UltraSparc::addPassesToEmitAssembly(PassManager &PM, std::ostream &Out) {
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000169 // Construct and initialize the MachineCodeForMethod object for this fn.
170 PM.add(new ConstructMachineCodeForFunction(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000171
Chris Lattner057430d2002-07-30 03:56:16 +0000172 PM.add(createInstructionSelectionPass(*this));
Ruchira Sasankad00982a2002-01-07 19:20:28 +0000173
Vikram S. Adved7e6bec2002-03-24 03:35:16 +0000174 PM.add(createInstructionSchedulingWithSSAPass(*this));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000175
Chris Lattner2f9b28e2002-02-04 15:54:09 +0000176 PM.add(getRegisterAllocator(*this));
Chris Lattner0feb3582002-02-03 23:41:51 +0000177
178 //PM.add(new OptimizeLeafProcedures());
179 //PM.add(new DeleteFallThroughBranches());
180 //PM.add(new RemoveChainedBranches()); // should be folded with previous
181 //PM.add(new RemoveRedundantOps()); // operations with %g0, NOP, etc.
182
Chris Lattner1d21f3e2002-04-09 05:21:26 +0000183 PM.add(createPrologEpilogCodeInserter(*this));
Mehwish Nagda634cd1c2002-07-15 23:58:21 +0000184
Anand Shukla59938292002-08-27 16:45:17 +0000185 PM.add(MappingInfoForFunction(Out));
Mehwish Nagda634cd1c2002-07-15 23:58:21 +0000186
Chris Lattner0feb3582002-02-03 23:41:51 +0000187 // Output assembly language to the .s file. Assembly emission is split into
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000188 // two parts: Function output and Global value output. This is because
189 // function output is pipelined with all of the rest of code generation stuff,
190 // allowing machine code representations for functions to be free'd after the
191 // function has been emitted.
Chris Lattner0feb3582002-02-03 23:41:51 +0000192 //
Chris Lattnerf57b8452002-04-27 06:56:12 +0000193 PM.add(getFunctionAsmPrinterPass(PM, Out));
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000194 PM.add(new FreeMachineCodeForFunction()); // Free stuff no longer needed
Anand Shukla59938292002-08-27 16:45:17 +0000195
Chris Lattner2fbfdcf2002-04-07 20:49:59 +0000196 // Emit Module level assembly after all of the functions have been processed.
Chris Lattner0feb3582002-02-03 23:41:51 +0000197 PM.add(getModuleAsmPrinterPass(PM, Out));
Chris Lattner9530a6f2002-02-11 22:35:46 +0000198
199 // Emit bytecode to the sparc assembly file into its special section next
200 PM.add(getEmitBytecodeToAsmPass(Out));
Anand Shukla59938292002-08-27 16:45:17 +0000201 PM.add(getFunctionInfo(Out));
Chris Lattnercf4525b2002-02-03 07:49:15 +0000202}
Mehwish Nagda634cd1c2002-07-15 23:58:21 +0000203