Added code to support correct saving of %ccr across calls
[oota-llvm.git] / lib / Target / SparcV9 / SparcV9RegClassInfo.h
1 /* Title:   SparcRegClassInfo.h    -*- C++ -*-
2    Author:  Ruchira Sasanka
3    Date:    Aug 20, 01
4    Purpose: Contains the description of integer register class of Sparc
5 */
6
7
8 #ifndef SPARC_REG_INFO_CLASS_H
9 #define SPARC_REG_INFO_CLASS_H
10
11 #include "llvm/Target/MachineRegInfo.h"
12 #include "llvm/CodeGen/IGNode.h"
13
14 //-----------------------------------------------------------------------------
15 // Integer Register Class
16 //-----------------------------------------------------------------------------
17
18
19 // Int register names in same order as enum in class SparcIntRegOrder
20
21 static string const IntRegNames[] = 
22   {  
23     "o0", "o1", "o2", "o3", "o4", "o5",       "o7",
24     "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7",
25     "i0", "i1", "i2", "i3", "i4", "i5",  
26     "i6", "i7",
27     "g0", "g1", "g2", "g3", "g4", "g5",  "g6", "g7", 
28     "o6" }; 
29
30
31
32 class SparcIntRegOrder{ 
33
34  public:
35
36   enum RegsInPrefOrder   // colors possible for a LR (in preferred order)
37    { 
38      // --- following colors are volatile across function calls
39      // %g0 can't be used for coloring - always 0
40                      
41      //%g1-%g5  (g6-7 are reserved for system)  
42      o0, o1, o2, o3, o4, o5, o7,  // %o0-%o5, 
43
44      // %o6 is sp, 
45      // all %0's can get modified by a call
46
47      // --- following colors are NON-volatile across function calls
48       
49      l0, l1, l2, l3, l4, l5, l6, l7,    //  %l0-%l7
50      i0, i1, i2, i3, i4, i5,         // %i0-%i5: i's need not be preserved 
51       
52      // %i6 is the fp - so not allocated
53      // %i7 is the ret address by convention - can be used for others
54
55      // max # of colors reg coloring  can allocate (NumOfAvailRegs)
56
57      // --- following colors are not available for allocation within this phase
58      // --- but can appear for pre-colored ranges 
59
60      i6, i7, g0,  g1, g2, g3, g4, g5, g6, g7, o6
61      
62      //*** NOTE: If we decide to use globals, some of them are volatile 
63      //**** see sparc64ABI (change isRegVloatile method below)
64  
65
66    };
67
68   // max # of colors reg coloring  can allocate
69   static unsigned int const NumOfAvailRegs = i6;
70
71   static unsigned int const StartOfNonVolatileRegs = l0;
72   static unsigned int const StartOfAllRegs = o0;
73   static unsigned int const NumOfAllRegs = o6 + 1; 
74
75
76   static const string  getRegName(const unsigned reg) {
77     assert( reg < NumOfAllRegs );
78     return IntRegNames[reg];
79   }
80
81   static unsigned int getRegNumInCallersWindow(const unsigned reg) {
82     if (reg <= l7 || reg == o6) {
83       assert(0 && "registers o0-o7 and l0-l7 are not visible in caller");
84       return reg;
85     }
86     if (reg <= i7)
87       return reg - (i0 - o0);
88     assert((reg >= g0 || reg <= g7) && "Unrecognized integer register number");
89       return reg;
90   }
91 };
92
93
94
95 class SparcIntRegClass : public MachineRegClassInfo
96 {
97  public:
98
99   SparcIntRegClass(unsigned ID) 
100     : MachineRegClassInfo(ID, 
101                           SparcIntRegOrder::NumOfAvailRegs,
102                           SparcIntRegOrder::NumOfAllRegs)
103     {  }
104
105   void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
106
107   inline bool isRegVolatile(const int Reg) const {
108     return (Reg < (int) SparcIntRegOrder::StartOfNonVolatileRegs); 
109   }
110
111 };
112
113 //-----------------------------------------------------------------------------
114 // Float Register Class
115 //-----------------------------------------------------------------------------
116
117 static string const FloatRegNames[] = 
118   {    
119     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",  "f8",  "f9", 
120     "f10", "f11", "f12", "f13", "f14", "f15", "f16", "f17", "f18", "f19",
121     "f20", "f21", "f22", "f23", "f24", "f25", "f26", "f27", "f28", "f29",
122     "f30", "f31", "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39",
123     "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", "f48", "f49",
124     "f50", "f51", "f52", "f53", "f54", "f55", "f56", "f57", "f58", "f59",
125     "f60", "f61", "f62", "f63"
126   };
127
128
129 class SparcFloatRegOrder{ 
130
131  public:
132
133   enum RegsInPrefOrder {
134
135     f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, 
136     f10, f11, f12, f13, f14, f15, f16, f17, f18, f19,
137     f20, f21, f22, f23, f24, f25, f26, f27, f28, f29,
138     f30, f31, f32, f33, f34, f35, f36, f37, f38, f39,
139     f40, f41, f42, f43, f44, f45, f46, f47, f48, f49,
140     f50, f51, f52, f53, f54, f55, f56, f57, f58, f59,
141     f60, f61, f62, f63
142
143   };
144
145   // there are 64 regs alltogether but only 32 regs can be allocated at
146   // a time.
147
148   static unsigned int const NumOfAvailRegs = 32;
149   static unsigned int const NumOfAllRegs = 64;
150
151   static unsigned int const StartOfNonVolatileRegs = f32;
152   static unsigned int const StartOfAllRegs = f0;
153
154
155   static const string  getRegName(const unsigned reg) {
156     assert( reg < NumOfAllRegs );
157     return FloatRegNames[reg];
158   }
159
160
161
162 };
163
164
165
166 class SparcFloatRegClass : public MachineRegClassInfo
167 {
168  private:
169
170   int findFloatColor(const LiveRange *const LR, unsigned Start,
171                      unsigned End, bool IsColorUsedArr[] ) const;
172
173  public:
174
175   SparcFloatRegClass(unsigned ID) 
176     : MachineRegClassInfo(ID, 
177                           SparcFloatRegOrder::NumOfAvailRegs,
178                           SparcFloatRegOrder::NumOfAllRegs)
179     {  }
180
181   void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const;
182
183   // according to  Sparc 64 ABI, all %fp regs are volatile
184   inline bool isRegVolatile(const int Reg) const { return true; }
185
186
187 };
188
189
190
191
192 //-----------------------------------------------------------------------------
193 // Int CC Register Class
194 // Only one integer cc register is available. However, this register is
195 // referred to as %xcc when instructions like subcc are executed but 
196 // referred to as %ccr (i.e., %xcc + %icc") when this register is moved
197 // into an integer register using RD or WR instrcutions. So, two ids are
198 // allocated for two names.
199 //-----------------------------------------------------------------------------
200
201
202 static string const IntCCRegNames[] = 
203   {    
204     "xcc",  "ccr"
205   };
206
207
208 class SparcIntCCRegOrder{ 
209
210  public:
211
212   enum RegsInPrefOrder {
213
214     xcc, ccr   // only one is available - see the note above
215   };
216
217   static const string  getRegName(const unsigned reg) {
218     assert( reg < 2 );
219     return IntCCRegNames[reg];
220   }
221
222   // according to  Sparc 64 ABI,  %ccr is volatile
223   inline bool isRegVolatile(const int Reg) const { return true; }
224
225
226 };
227
228
229
230 class SparcIntCCRegClass : public MachineRegClassInfo
231 {
232 public:
233
234   SparcIntCCRegClass(unsigned ID) 
235     : MachineRegClassInfo(ID, 1, 2) {  }
236
237   inline void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
238     Node->setColor(0);    // only one int cc reg is available
239   }
240
241
242   inline bool isRegVolatile(const int Reg) const { return true; }
243
244 };
245
246
247
248 //-----------------------------------------------------------------------------
249 // Float CC Register Class
250 // Only 4 Float CC registers are available
251 //-----------------------------------------------------------------------------
252
253
254 static string const FloatCCRegNames[] = 
255   {    
256     "fcc0",  "fcc1",  "fcc2",  "fcc3"
257   };
258
259
260 class SparcFloatCCRegOrder{ 
261
262  public:
263
264   enum RegsInPrefOrder {
265
266     fcc0, fcc1, fcc2, fcc3
267   };
268
269   static const string  getRegName(const unsigned reg) {
270     assert( reg < 4 );
271     return FloatCCRegNames[reg];
272   }
273
274   // according to  Sparc 64 ABI, all %fp regs are volatile
275   inline bool isRegVolatile(const int Reg) const { return true; }
276
277
278 };
279
280
281
282 class SparcFloatCCRegClass : public MachineRegClassInfo
283 {
284 public:
285
286   SparcFloatCCRegClass(unsigned ID) 
287     : MachineRegClassInfo(ID, 4, 4) {  }
288
289   void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const {
290     int c;
291     for(c=0; c < 4  && IsColorUsedArr[c] ; ++c) ; // find color
292     assert( (c < 4)  && "Can allocate only 4 float cc registers");
293     Node->setColor(c);   
294   }
295
296   // *** TODO: Check this
297   inline bool isRegVolatile(const int Reg) const { return true; }
298
299
300 };
301
302
303
304
305 #endif