1 //===-- SparcV9FrameInfo.h - Define TargetFrameInfo for SparcV9 -*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Interface to stack frame layout info for the UltraSPARC.
11 // Starting offsets for each area of the stack frame are aligned at
12 // a multiple of getStackFrameSizeAlignment().
14 //----------------------------------------------------------------------------
16 #ifndef SPARC_FRAMEINFO_H
17 #define SPARC_FRAMEINFO_H
19 #include "llvm/Target/TargetFrameInfo.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "SparcV9RegInfo.h"
25 class SparcV9FrameInfo: public TargetFrameInfo {
26 const TargetMachine ⌖
28 SparcV9FrameInfo(const TargetMachine &TM)
29 : TargetFrameInfo(StackGrowsDown, StackFrameSizeAlignment, 0), target(TM) {}
32 // These methods provide constant parameters of the frame layout.
34 int getStackFrameSizeAlignment() const { return StackFrameSizeAlignment;}
35 int getMinStackFrameSize() const { return MinStackFrameSize; }
36 int getNumFixedOutgoingArgs() const { return NumFixedOutgoingArgs; }
37 int getSizeOfEachArgOnStack() const { return SizeOfEachArgOnStack; }
38 bool argsOnStackHaveFixedSize() const { return true; }
40 // This method adjusts a stack offset to meet alignment rules of target.
41 // The fixed OFFSET (0x7ff) must be subtracted and the result aligned.
42 virtual int adjustAlignment(int unalignedOffset, bool growUp,
43 unsigned int align) const {
44 return unalignedOffset + (growUp? +1:-1)*((unalignedOffset-OFFSET) % align);
47 // These methods compute offsets using the frame contents for a
48 // particular function. The frame contents are obtained from the
49 // MachineCodeInfoForMethod object for the given function.
51 int getFirstIncomingArgOffset(MachineFunction& mcInfo, bool& growUp) const {
52 growUp = true; // arguments area grows upwards
53 return FirstIncomingArgOffsetFromFP;
55 int getFirstOutgoingArgOffset(MachineFunction& mcInfo, bool& growUp) const {
56 growUp = true; // arguments area grows upwards
57 return FirstOutgoingArgOffsetFromSP;
59 int getFirstOptionalOutgoingArgOffset(MachineFunction& mcInfo,
61 growUp = true; // arguments area grows upwards
62 return FirstOptionalOutgoingArgOffsetFromSP;
65 int getFirstAutomaticVarOffset(MachineFunction& mcInfo, bool& growUp) const;
66 int getRegSpillAreaOffset(MachineFunction& mcInfo, bool& growUp) const;
67 int getTmpAreaOffset(MachineFunction& mcInfo, bool& growUp) const;
68 int getDynamicAreaOffset(MachineFunction& mcInfo, bool& growUp) const;
71 // These methods specify the base register used for each stack area
72 // (generally FP or SP)
74 virtual int getIncomingArgBaseRegNum() const {
75 return (int) target.getRegInfo()->getFramePointer();
77 virtual int getOutgoingArgBaseRegNum() const {
78 return (int) target.getRegInfo()->getStackPointer();
80 virtual int getOptionalOutgoingArgBaseRegNum() const {
81 return (int) target.getRegInfo()->getStackPointer();
83 virtual int getAutomaticVarBaseRegNum() const {
84 return (int) target.getRegInfo()->getFramePointer();
86 virtual int getRegSpillAreaBaseRegNum() const {
87 return (int) target.getRegInfo()->getFramePointer();
89 virtual int getDynamicAreaBaseRegNum() const {
90 return (int) target.getRegInfo()->getStackPointer();
93 virtual int getIncomingArgOffset(MachineFunction& mcInfo,
94 unsigned argNum) const {
95 assert(argsOnStackHaveFixedSize());
97 unsigned relativeOffset = argNum * getSizeOfEachArgOnStack();
98 bool growUp; // do args grow up or down
99 int firstArg = getFirstIncomingArgOffset(mcInfo, growUp);
100 return growUp ? firstArg + relativeOffset : firstArg - relativeOffset;
103 virtual int getOutgoingArgOffset(MachineFunction& mcInfo,
104 unsigned argNum) const {
105 assert(argsOnStackHaveFixedSize());
106 //assert(((int) argNum - this->getNumFixedOutgoingArgs())
107 // <= (int) mcInfo.getInfo()->getMaxOptionalNumArgs());
109 unsigned relativeOffset = argNum * getSizeOfEachArgOnStack();
110 bool growUp; // do args grow up or down
111 int firstArg = getFirstOutgoingArgOffset(mcInfo, growUp);
112 return growUp ? firstArg + relativeOffset : firstArg - relativeOffset;
116 /*----------------------------------------------------------------------
117 This diagram shows the stack frame layout used by llc on SparcV9 V9.
118 Note that only the location of automatic variables, spill area,
119 temporary storage, and dynamically allocated stack area are chosen
120 by us. The rest conform to the SparcV9 V9 ABI.
121 All stack addresses are offset by OFFSET = 0x7ff (2047).
123 Alignment assumptions and other invariants:
124 (1) %sp+OFFSET and %fp+OFFSET are always aligned on 16-byte boundary
125 (2) Variables in automatic, spill, temporary, or dynamic regions
126 are aligned according to their size as in all memory accesses.
127 (3) Everything below the dynamically allocated stack area is only used
128 during a call to another function, so it is never needed when
129 the current function is active. This is why space can be allocated
130 dynamically by incrementing %sp any time within the function.
135 %fp+OFFSET+176 Optional extra incoming arguments# 1..N
136 %fp+OFFSET+168 Incoming argument #6
138 %fp+OFFSET+128 Incoming argument #1
140 ---%fp+OFFSET-0--------Bottom of caller's stack frame--------------------
141 %fp+OFFSET-8 Automatic variables <-- ****TOP OF STACK FRAME****
146 %sp+OFFSET+176+8N Bottom of dynamically allocated stack area
147 %sp+OFFSET+168+8N Optional extra outgoing argument# N
149 %sp+OFFSET+176 Optional extra outgoing argument# 1
150 %sp+OFFSET+168 Outgoing argument #6
152 %sp+OFFSET+128 Outgoing argument #1
153 %sp+OFFSET+120 Save area for %i7
155 %sp+OFFSET+0 Save area for %l0 <-- ****BOTTOM OF STACK FRAME****
157 *----------------------------------------------------------------------*/
159 // All stack addresses must be offset by 0x7ff (2047) on SparcV9 V9.
160 static const int OFFSET = (int) 0x7ff;
161 static const int StackFrameSizeAlignment = 16;
162 static const int MinStackFrameSize = 176;
163 static const int NumFixedOutgoingArgs = 6;
164 static const int SizeOfEachArgOnStack = 8;
165 static const int FirstIncomingArgOffsetFromFP = 128 + OFFSET;
166 static const int FirstOptionalIncomingArgOffsetFromFP = 176 + OFFSET;
167 static const int StaticAreaOffsetFromFP = 0 + OFFSET;
168 static const int FirstOutgoingArgOffsetFromSP = 128 + OFFSET;
169 static const int FirstOptionalOutgoingArgOffsetFromSP = 176 + OFFSET;
172 } // End llvm namespace