1   // Copyright 2012- Bill Campbell, Swami Iyer and Bahar Akbal-Delibas
2   
3   package jminusminus;
4   
5   /**
6    * An abstract representation for a (physical and virtual) register.
7    */
8   abstract class NRegister {
9       /**
10       * Register number.
11       */
12      protected int number;
13  
14      /**
15       * Register name.
16       */
17      protected String name;
18  
19      /**
20       * Constructs an NRegister.
21       *
22       * @param number register number.
23       * @param name   register name.
24       */
25      protected NRegister(int number, String name) {
26          this.number = number;
27          this.name = name;
28      }
29  
30      /**
31       * Returns the number of this register.
32       *
33       * @return the number of this register.
34       */
35      public int number() {
36          return number;
37      }
38  
39      /**
40       * Returns the name of this register.
41       *
42       * @return the name of this register.
43       */
44      public String name() {
45          return name;
46      }
47  }
48  
49  /**
50   * Representation for a virtual register.
51   */
52  class NVirtualRegister extends NRegister {
53      // Type (short name) of value in register.
54      private String sType;
55  
56      // Type (long name) of value in register.
57      private String lType;
58  
59      /**
60       * Constructs an NVirutalRegister..
61       *
62       * @param number register number.
63       * @param sType  type (short name) of value in register.
64       * @param lType  type (long name) of value in register.
65       */
66      public NVirtualRegister(int number, String sType, String lType) {
67          super(number, "V" + number);
68          this.sType = sType;
69          this.lType = lType;
70      }
71  
72      /**
73       * Returns a string representation of this virtual register.
74       *
75       * @return a string representation of this virtual register.
76       */
77      public String toString() {
78          return "[" + name + "|" + sType + "]";
79      }
80  }
81  
82  /**
83   * Representation for a physical register.
84   */
85  class NPhysicalRegister extends NRegister {
86      /**
87       * Maximum number of physical registers used for allocation, starting at T0.
88       */
89      public static int MAX_COUNT = 8;
90  
91      // Constants identifying the physical registers. These can be used as indices into the static
92      // regInfo array to access the representations of the corresponding registers.
93  
94      /**
95       * Constant 0.
96       */
97      public static final int ZERO = 0;
98  
99      /**
100      * Reserved for assembler.
101      */
102     public static final int AT = 1;
103 
104     /**
105      * Expression evaluation and results of a function.
106      */
107     public static final int V0 = 2;
108 
109     /**
110      * Expression evaluation and results of a function.
111      */
112     public static final int V1 = 3;
113 
114     /**
115      * Argument 1.
116      */
117     public static final int A0 = 4;
118 
119     /**
120      * Argument 2.
121      */
122     public static final int A1 = 5;
123 
124     /**
125      * Argument 3.
126      */
127     public static final int A2 = 6;
128 
129     /**
130      * Argument 4.
131      */
132     public static final int A3 = 7;
133 
134     /**
135      * Temporary (not preserved across call).
136      */
137     public static final int T0 = 8;
138 
139     /**
140      * Temporary (not preserved across call).
141      */
142     public static final int T1 = 9;
143 
144     /**
145      * Temporary (not preserved across call).
146      */
147     public static final int T2 = 10;
148 
149     /**
150      * Temporary (not preserved across call).
151      */
152     public static final int T3 = 11;
153 
154     /**
155      * Temporary (not preserved across call).
156      */
157     public static final int T4 = 12;
158 
159     /**
160      * Temporary (not preserved across call).
161      */
162     public static final int T5 = 13;
163 
164     /**
165      * Temporary (not preserved across call).
166      */
167     public static final int T6 = 14;
168 
169     /**
170      * Temporary (not preserved across call).
171      */
172     public static final int T7 = 15;
173 
174     /**
175      * Temporary (preserved across call).
176      */
177     public static final int S0 = 16;
178 
179     /**
180      * Temporary (preserved across call).
181      */
182     public static final int S1 = 17;
183 
184     /**
185      * Temporary (preserved across call).
186      */
187     public static final int S2 = 18;
188 
189     /**
190      * Temporary (preserved across call).
191      */
192     public static final int S3 = 19;
193 
194     /**
195      * Temporary (preserved across call).
196      */
197     public static final int S4 = 20;
198 
199     /**
200      * Temporary (preserved across call).
201      */
202     public static final int S5 = 21;
203 
204     /**
205      * Temporary (preserved across call).
206      */
207     public static final int S6 = 22;
208 
209     /**
210      * Temporary (preserved across call).
211      */
212     public static final int S7 = 23;
213 
214     /**
215      * Temporary (not preserved across call).
216      */
217     public static final int T8 = 24;
218 
219     /**
220      * Temporary (not preserved across call).
221      */
222     public static final int T9 = 25;
223 
224     /**
225      * Reserved for OS kernel.
226      */
227     public static final int K0 = 26;
228 
229     /**
230      * Reserved for OS kernel.
231      */
232     public static final int K1 = 27;
233 
234     /**
235      * Pointer to global area.
236      */
237     public static final int GP = 28;
238 
239     /**
240      * Stack pointer.
241      */
242     public static final int SP = 29;
243 
244     /**
245      * Frame pointer.
246      */
247     public static final int FP = 30;
248 
249     /**
250      * Return address (used by function call).
251      */
252     public static final int RA = 31;
253 
254     /**
255      * Maps register number to the register's representation.
256      */
257     public static final NPhysicalRegister[] regInfo = {
258             new NPhysicalRegister(0, "zero"), new NPhysicalRegister(1, "at"),
259             new NPhysicalRegister(2, "v0"), new NPhysicalRegister(3, "v1"),
260             new NPhysicalRegister(4, "a0"), new NPhysicalRegister(5, "a1"),
261             new NPhysicalRegister(6, "a2"), new NPhysicalRegister(7, "a3"),
262             new NPhysicalRegister(8, "t0"), new NPhysicalRegister(9, "t1"),
263             new NPhysicalRegister(10, "t2"), new NPhysicalRegister(11, "t3"),
264             new NPhysicalRegister(12, "t4"), new NPhysicalRegister(13, "t5"),
265             new NPhysicalRegister(14, "t6"), new NPhysicalRegister(15, "t7"),
266             new NPhysicalRegister(16, "s0"), new NPhysicalRegister(17, "s1"),
267             new NPhysicalRegister(18, "s2"), new NPhysicalRegister(19, "s3"),
268             new NPhysicalRegister(20, "s4"), new NPhysicalRegister(21, "s5"),
269             new NPhysicalRegister(22, "s6"), new NPhysicalRegister(23, "s7"),
270             new NPhysicalRegister(24, "t8"), new NPhysicalRegister(25, "t9"),
271             new NPhysicalRegister(26, "k0"), new NPhysicalRegister(27, "k1"),
272             new NPhysicalRegister(28, "gp"), new NPhysicalRegister(29, "sp"),
273             new NPhysicalRegister(30, "fp"), new NPhysicalRegister(31, "ra")};
274 
275     /**
276      * Constructs an NPhysicalRegister.
277      *
278      * @param number number of the register.
279      * @param name   name of the register.
280      */
281     public NPhysicalRegister(int number, String name) {
282         super(number, name);
283     }
284 
285     /**
286      * Returns a string representation of this physical register.
287      *
288      * @return a string representation of this physical register.
289      */
290     public String toString() {
291         return "$" + name();
292     }
293 }
294