When we want a constant, just use it, instead of calling through layers of
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9FrameInfo.h
1 //===-- SparcV9FrameInfo.h - Define TargetFrameInfo for SparcV9 -*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
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.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
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().
13 //
14 //----------------------------------------------------------------------------
15
16 #ifndef SPARC_FRAMEINFO_H
17 #define SPARC_FRAMEINFO_H
18
19 #include "llvm/Target/TargetFrameInfo.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "SparcV9RegInfo.h"
22
23 namespace llvm {
24
25 class SparcV9FrameInfo: public TargetFrameInfo {
26   const TargetMachine ⌖
27 public:
28   SparcV9FrameInfo(const TargetMachine &TM)
29     : TargetFrameInfo(StackGrowsDown, StackFrameSizeAlignment, 0), target(TM) {}
30   
31 public:
32   // These methods provide constant parameters of the frame layout.
33   // 
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; }
39
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);
45   }
46
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.
50   // 
51   int getFirstIncomingArgOffset(MachineFunction& mcInfo, bool& growUp) const {
52     growUp = true;                         // arguments area grows upwards
53     return FirstIncomingArgOffsetFromFP;
54   }
55   int getFirstOutgoingArgOffset(MachineFunction& mcInfo, bool& growUp) const {
56     growUp = true;                         // arguments area grows upwards
57     return FirstOutgoingArgOffsetFromSP;
58   }
59   int getFirstOptionalOutgoingArgOffset(MachineFunction& mcInfo,
60                                         bool& growUp) const {
61     growUp = true;                         // arguments area grows upwards
62     return FirstOptionalOutgoingArgOffsetFromSP;
63   }
64   
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;
69
70   //
71   // These methods specify the base register used for each stack area
72   // (generally FP or SP)
73   // 
74   virtual int getIncomingArgBaseRegNum() const {
75     return (int) target.getRegInfo()->getFramePointer();
76   }
77   virtual int getOutgoingArgBaseRegNum() const {
78     return (int) target.getRegInfo()->getStackPointer();
79   }
80   virtual int getOptionalOutgoingArgBaseRegNum() const {
81     return (int) target.getRegInfo()->getStackPointer();
82   }
83   virtual int getAutomaticVarBaseRegNum() const {
84     return (int) target.getRegInfo()->getFramePointer();
85   }
86   virtual int getRegSpillAreaBaseRegNum() const {
87     return (int) target.getRegInfo()->getFramePointer();
88   }
89   virtual int getDynamicAreaBaseRegNum() const {
90     return (int) target.getRegInfo()->getStackPointer();
91   }
92
93   virtual int getIncomingArgOffset(MachineFunction& mcInfo, 
94                                    unsigned argNum) const {
95     assert(argsOnStackHaveFixedSize()); 
96   
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; 
101   }
102
103   virtual int getOutgoingArgOffset(MachineFunction& mcInfo,
104                                    unsigned argNum) const {
105     assert(argsOnStackHaveFixedSize()); 
106     //assert(((int) argNum - this->getNumFixedOutgoingArgs())
107     //     <= (int) mcInfo.getInfo()->getMaxOptionalNumArgs());
108     
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; 
113   }
114   
115   /*----------------------------------------------------------------------
116     This diagram shows the stack frame layout used by llc on SparcV9 V9.
117     Note that only the location of automatic variables, spill area,
118     temporary storage, and dynamically allocated stack area are chosen
119     by us.  The rest conform to the SparcV9 V9 ABI.
120     All stack addresses are offset by OFFSET = 0x7ff (2047).
121
122     Alignment assumptions and other invariants:
123     (1) %sp+OFFSET and %fp+OFFSET are always aligned on 16-byte boundary
124     (2) Variables in automatic, spill, temporary, or dynamic regions
125         are aligned according to their size as in all memory accesses.
126     (3) Everything below the dynamically allocated stack area is only used
127         during a call to another function, so it is never needed when
128         the current function is active.  This is why space can be allocated
129         dynamically by incrementing %sp any time within the function.
130     
131     STACK FRAME LAYOUT:
132
133        ...
134        %fp+OFFSET+176      Optional extra incoming arguments# 1..N
135        %fp+OFFSET+168      Incoming argument #6
136        ...                 ...
137        %fp+OFFSET+128      Incoming argument #1
138        ...                 ...
139     ---%fp+OFFSET-0--------Bottom of caller's stack frame--------------------
140        %fp+OFFSET-8        Automatic variables <-- ****TOP OF STACK FRAME****
141                            Spill area
142                            Temporary storage
143        ...
144
145        %sp+OFFSET+176+8N   Bottom of dynamically allocated stack area
146        %sp+OFFSET+168+8N   Optional extra outgoing argument# N
147        ...                 ...
148        %sp+OFFSET+176      Optional extra outgoing argument# 1
149        %sp+OFFSET+168      Outgoing argument #6
150        ...                 ...
151        %sp+OFFSET+128      Outgoing argument #1
152        %sp+OFFSET+120      Save area for %i7
153        ...                 ...
154        %sp+OFFSET+0        Save area for %l0 <-- ****BOTTOM OF STACK FRAME****
155
156    *----------------------------------------------------------------------*/
157
158   // All stack addresses must be offset by 0x7ff (2047) on SparcV9 V9.
159   static const int OFFSET                                  = (int) 0x7ff;
160   static const int StackFrameSizeAlignment                 =  16;
161   static const int MinStackFrameSize                       = 176;
162   static const int NumFixedOutgoingArgs                    =   6;
163   static const int SizeOfEachArgOnStack                    =   8;
164   static const int FirstIncomingArgOffsetFromFP            = 128 + OFFSET;
165   static const int FirstOptionalIncomingArgOffsetFromFP    = 176 + OFFSET;
166   static const int StaticAreaOffsetFromFP                  =   0 + OFFSET;
167   static const int FirstOutgoingArgOffsetFromSP            = 128 + OFFSET;
168   static const int FirstOptionalOutgoingArgOffsetFromSP    = 176 + OFFSET;
169 };
170
171 } // End llvm namespace
172
173 #endif