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