1 witchel  1.1.2.1  // RegFileInfo.java, created Sat Sep 11 00:43:20 1999 by pnkfelix
  2 witchel  1.1.2.1  // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
  3 witchel  1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 witchel  1.1.2.1  package harpoon.Backend.MIPS;
  5 witchel  1.1.2.1  
  6 witchel  1.1.2.1  import harpoon.Backend.Generic.Frame;
  7 witchel  1.1.2.1  import harpoon.Backend.Generic.LocationFactory.Location;
  8 witchel  1.1.2.1  import harpoon.Backend.Generic.RegFileInfo.SpillException;
  9 cananian 1.1.2.2  import harpoon.Backend.StrongARM.TwoWordTemp;
 10 witchel  1.1.2.1  import harpoon.ClassFile.HClass;
 11 cananian 1.1.2.8  import harpoon.ClassFile.HCode.PrintCallback;
 12 witchel  1.1.2.1  import harpoon.ClassFile.HCodeElement;
 13 witchel  1.1.2.1  import harpoon.ClassFile.HData;
 14 witchel  1.1.2.1  import harpoon.ClassFile.HDataElement;
 15 witchel  1.1.2.1  import harpoon.IR.Tree.Data;
 16 witchel  1.1.2.1  import harpoon.IR.Tree.Exp;
 17 witchel  1.1.2.1  import harpoon.IR.Tree.TEMP;
 18 witchel  1.1.2.1  import harpoon.IR.Tree.TreeFactory;
 19 witchel  1.1.2.1  import harpoon.IR.Tree.Type;
 20 witchel  1.1.2.1  import harpoon.Temp.Temp;
 21 witchel  1.1.2.1  import harpoon.Temp.TempFactory;
 22 cananian 1.5      import net.cscott.jutil.LinearSet;
 23 cananian 1.5      import net.cscott.jutil.ListFactory;
 24 witchel  1.1.2.1  import harpoon.Util.Util;
 25 witchel  1.1.2.1  
 26 witchel  1.1.2.1  import java.util.ArrayList;
 27 witchel  1.1.2.1  import java.util.Arrays;
 28 witchel  1.1.2.1  import java.util.Collections;
 29 pnkfelix 1.1.2.10 import java.util.Collection;
 30 witchel  1.1.2.1  import java.util.Set;
 31 witchel  1.1.2.1  import java.util.Iterator;
 32 witchel  1.1.2.1  import java.util.Map;
 33 witchel  1.1.2.1  import java.util.HashMap;
 34 witchel  1.1.2.1  import java.util.HashSet;
 35 witchel  1.1.2.1  
 36 witchel  1.1.2.1  /**
 37 witchel  1.1.2.1   * <code>RegFileInfo</code> encapsulates information about the
 38 witchel  1.1.2.1   * MIPS register set.  This object also implements
 39 witchel  1.1.2.1   * <code>Generic.LocationFactory</code>, allowing the creation of
 40 witchel  1.1.2.1   * global registers for the use of the runtime.
 41 witchel  1.1.2.1   * 
 42 cananian 1.1.2.9   * @author  Emmett Witchel <witchel@mit.edu>
 43 cananian 1.5       * @version $Id: RegFileInfo.java,v 1.5 2004/02/08 01:57:34 cananian Exp $
 44 witchel  1.1.2.1   */
 45 witchel  1.1.2.1  public class RegFileInfo
 46 witchel  1.1.2.1  extends harpoon.Backend.Generic.RegFileInfo 
 47 witchel  1.1.2.1  implements harpoon.Backend.Generic.LocationFactory
 48 witchel  1.1.2.1  {
 49 witchel  1.1.2.1     // FSK wants to relinquish author ship of the first half of this
 50 witchel  1.1.2.1     // file, since it was just cut-and-pasted out of the
 51 witchel  1.1.2.1     // hack-once-known-as-SAFrame
 52 witchel  1.1.2.1  
 53 witchel  1.1.2.1     final Temp[] reg;
 54 witchel  1.1.2.1     final Set callerSaveRegs;
 55 witchel  1.1.2.1     final Set calleeSaveRegs;
 56 witchel  1.1.2.1     final Set liveOnExitRegs;
 57 witchel  1.1.2.1     final Temp[] regGeneral; 
 58 witchel  1.1.2.1     final TempFactory regtf;
 59 witchel  1.1.2.5     Set oneWordAssigns, twoWordAssigns;
 60 witchel  1.1.2.1  
 61 witchel  1.1.2.1     // Use symbolic names
 62 witchel  1.1.2.1     
 63 witchel  1.1.2.1     final Temp ZERO; // Frame pointer
 64 witchel  1.1.2.1     final Temp AT;   // Assembler Register
 65 witchel  1.1.2.1     final Temp V0;   // return
 66 witchel  1.1.2.1     final Temp V1;   // return
 67 witchel  1.1.2.1     final Temp A0;   // arg 0
 68 witchel  1.1.2.1     final Temp A1;   // arg 1
 69 witchel  1.1.2.1     final Temp A2;   // arg 2
 70 witchel  1.1.2.1     final Temp A3;   // arg 3
 71 witchel  1.1.2.1     final Temp T0;   // temps
 72 witchel  1.1.2.1     final Temp T1; 
 73 witchel  1.1.2.1     final Temp T2;
 74 witchel  1.1.2.1     final Temp T3;
 75 witchel  1.1.2.1     final Temp T4;
 76 witchel  1.1.2.1     final Temp T5;
 77 witchel  1.1.2.1     final Temp T6;
 78 witchel  1.1.2.1     final Temp T7;
 79 witchel  1.1.2.1     final Temp T8;
 80 witchel  1.1.2.1     final Temp T9;
 81 witchel  1.1.2.1     final Temp S0;  // Caller saved
 82 witchel  1.1.2.1     final Temp S1;
 83 witchel  1.1.2.1     final Temp S2;
 84 witchel  1.1.2.1     final Temp S3;
 85 witchel  1.1.2.1     final Temp S4;
 86 witchel  1.1.2.1     final Temp S5;
 87 witchel  1.1.2.1     final Temp S6;
 88 witchel  1.1.2.1     final Temp S7;
 89 witchel  1.1.2.1     final Temp K0;  // Reserved for the kernel
 90 witchel  1.1.2.1     final Temp K1;
 91 witchel  1.1.2.1     final Temp GP;  // pointer to take of immediates, for assembler
 92 witchel  1.1.2.1     final Temp FP;  // Frame pointer
 93 witchel  1.1.2.1     final Temp SP;  // Stack pointer
 94 witchel  1.1.2.1     final Temp LR;  // Link register
 95 witchel  1.1.2.1  
 96 witchel  1.1.2.1     /** Creates a <code>RegFileInfo</code>. 
 97 witchel  1.1.2.1       */
 98 witchel  1.1.2.1     public RegFileInfo() {
 99 witchel  1.1.2.1        // On MIPS, $0 = zero $1 = assembler reg, 26 & 27 are for the kernel
100 witchel  1.1.2.7        // We exclude 28 (gp) since C code asssumes it has a useful value
101 witchel  1.1.2.1        reg = new Temp[32];
102 witchel  1.1.2.1        regGeneral = new Temp[32];
103 witchel  1.1.2.7        callerSaveRegs = new LinearSet(18);
104 witchel  1.1.2.1        calleeSaveRegs = new LinearSet(10);
105 witchel  1.1.2.1        liveOnExitRegs = new LinearSet(4);
106 witchel  1.1.2.1        regtf = new TempFactory() {
107 witchel  1.1.2.1              private int i = 0;
108 witchel  1.1.2.1              private final String scope = "mips-registers";
109 witchel  1.1.2.1              
110 witchel  1.1.2.1              // 
111 witchel  1.1.2.1              /* r0 = 0
112 witchel  1.1.2.1               * r29 is sp
113 witchel  1.1.2.1               * r30 is our choice for an fp
114 witchel  1.1.2.1               * r28 is global pointer which we don't deal with right now
115 witchel  1.1.2.1               * see Kane for more details
116 witchel  1.1.2.1               */
117 witchel  1.1.2.1              private final String[] names = 
118 witchel  1.1.2.1              {"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
119 witchel  1.1.2.1               "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
120 witchel  1.1.2.1               "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23", 
121 witchel  1.1.2.1               "$24", "$25", "$26", "$27", "$28", "$sp", "$30", "$31" };
122 witchel  1.1.2.1              
123 witchel  1.1.2.1              public String getScope() { return scope; }
124 witchel  1.1.2.1              protected synchronized String getUniqueID(String suggestion) {
125 cananian 1.3.2.1                 assert i < names.length : "Don't use the "+
126 cananian 1.3.2.1                             "TempFactory of Register Temps";
127 witchel  1.1.2.1                 i++;
128 witchel  1.1.2.1                 return names[i-1];
129 witchel  1.1.2.1              }
130 witchel  1.1.2.1           };
131 witchel  1.1.2.1  
132 witchel  1.1.2.1        class RegTemp extends Temp implements MachineRegLoc {
133 witchel  1.1.2.1           int offset;
134 witchel  1.1.2.1           RegTemp(TempFactory tf, int offset) {
135 witchel  1.1.2.1              super(tf);
136 witchel  1.1.2.1              this.offset = offset;
137 witchel  1.1.2.1           }
138 witchel  1.1.2.1           public int kind() { return MachineRegLoc.KIND; }
139 witchel  1.1.2.1           public int regIndex() { return offset; }
140 witchel  1.1.2.1              
141 witchel  1.1.2.1        }
142 witchel  1.1.2.1  
143 witchel  1.1.2.1        for(int i = 0; i < reg.length; ++i) {
144 witchel  1.1.2.1           regGeneral[i] = reg[i] = new RegTemp(regtf, i);
145 witchel  1.1.2.1        }
146 witchel  1.1.2.1  
147 witchel  1.1.2.1        ZERO = reg[0];
148 witchel  1.1.2.1        AT   = reg[1];
149 witchel  1.1.2.1        V0   = reg[2];
150 witchel  1.1.2.1        V1   = reg[3];
151 witchel  1.1.2.1        A0   = reg[4];
152 witchel  1.1.2.1        A1   = reg[5];
153 witchel  1.1.2.1        A2   = reg[6];
154 witchel  1.1.2.1        A3   = reg[7];
155 witchel  1.1.2.1        T0   = reg[8];
156 witchel  1.1.2.1        T1   = reg[9];
157 witchel  1.1.2.1        T2   = reg[10];
158 witchel  1.1.2.1        T3   = reg[11];
159 witchel  1.1.2.1        T4   = reg[12];
160 witchel  1.1.2.1        T5   = reg[13];
161 witchel  1.1.2.1        T6   = reg[14];
162 witchel  1.1.2.1        T7   = reg[15];
163 witchel  1.1.2.1        S0   = reg[16];
164 witchel  1.1.2.1        S1   = reg[17];
165 witchel  1.1.2.1        S2   = reg[18];
166 witchel  1.1.2.1        S3   = reg[19];
167 witchel  1.1.2.1        S4   = reg[20];
168 witchel  1.1.2.1        S5   = reg[21];
169 witchel  1.1.2.1        S6   = reg[22];
170 witchel  1.1.2.1        S7   = reg[23];
171 witchel  1.1.2.1        T8   = reg[24];
172 witchel  1.1.2.1        T9   = reg[25];
173 witchel  1.1.2.1        K0   = reg[26];
174 witchel  1.1.2.1        K1   = reg[27];
175 witchel  1.1.2.1        GP   = reg[28];
176 witchel  1.1.2.1        SP   = reg[29];
177 witchel  1.1.2.1        FP   = reg[30];
178 witchel  1.1.2.1        LR   = reg[31];
179 witchel  1.1.2.1          
180 witchel  1.1.2.1        liveOnExitRegs.add(V0);  // return value
181 witchel  1.1.2.1        liveOnExitRegs.add(V1); // (possible) long word return value
182 witchel  1.1.2.1        liveOnExitRegs.add(FP);
183 witchel  1.1.2.1        liveOnExitRegs.add(SP);
184 witchel  1.1.2.1  
185 witchel  1.1.2.1        // callee clobbers v0, v1, a0-a3, t0-t9, gp, ra
186 witchel  1.1.2.1        callerSaveRegs.add(V0);
187 witchel  1.1.2.1        callerSaveRegs.add(V1);
188 witchel  1.1.2.1        callerSaveRegs.add(A0);
189 witchel  1.1.2.1        callerSaveRegs.add(A1);
190 witchel  1.1.2.1        callerSaveRegs.add(A2);
191 witchel  1.1.2.1        callerSaveRegs.add(A3);
192 witchel  1.1.2.1        callerSaveRegs.add(T0);
193 witchel  1.1.2.1        callerSaveRegs.add(T1);
194 witchel  1.1.2.1        callerSaveRegs.add(T2);
195 witchel  1.1.2.1        callerSaveRegs.add(T3);
196 witchel  1.1.2.1        callerSaveRegs.add(T4);
197 witchel  1.1.2.1        callerSaveRegs.add(T5);
198 witchel  1.1.2.1        callerSaveRegs.add(T6);
199 witchel  1.1.2.1        callerSaveRegs.add(T7);
200 witchel  1.1.2.1        callerSaveRegs.add(T8);
201 witchel  1.1.2.1        callerSaveRegs.add(T9);
202 witchel  1.1.2.7        callerSaveRegs.add(GP);
203 witchel  1.1.2.1        callerSaveRegs.add(LR);  // lr
204 witchel  1.1.2.1          
205 witchel  1.1.2.1        // callee saves s0-s8, sp
206 witchel  1.1.2.1        calleeSaveRegs.add(S0);
207 witchel  1.1.2.1        calleeSaveRegs.add(S1);
208 witchel  1.1.2.1        calleeSaveRegs.add(S2);
209 witchel  1.1.2.1        calleeSaveRegs.add(S3);
210 witchel  1.1.2.1        calleeSaveRegs.add(S4);
211 witchel  1.1.2.1        calleeSaveRegs.add(S5);
212 witchel  1.1.2.1        calleeSaveRegs.add(S6);
213 witchel  1.1.2.1        calleeSaveRegs.add(S7);
214 witchel  1.1.2.1        calleeSaveRegs.add(SP);  // SP
215 witchel  1.1.2.1        calleeSaveRegs.add(FP);  // s8
216 witchel  1.1.2.5  
217 witchel  1.1.2.5        oneWordAssigns = new HashSet();
218 witchel  1.1.2.5        // Start at 2 because R0 == 0 and R1 is the assembler register.
219 witchel  1.1.2.5        for (int i=2; i<regGeneral.length; i++) {
220 witchel  1.1.2.7           if(excludeReg(i) == false) {
221 witchel  1.1.2.7              Temp[] assign = new Temp[] { regGeneral[i] };
222 witchel  1.1.2.7              oneWordAssigns.add(Arrays.asList(assign));
223 witchel  1.1.2.7           }
224 witchel  1.1.2.5        }
225 witchel  1.1.2.5        oneWordAssigns = Collections.unmodifiableSet(oneWordAssigns);
226 witchel  1.1.2.5        twoWordAssigns = new HashSet();
227 witchel  1.1.2.5        // Start at 2 because R0 == 0 and R1 is the assembler register.
228 witchel  1.1.2.5        for (int i=2; i<regGeneral.length-1; i++) {
229 witchel  1.1.2.7           if(excludeReg(i) == false && excludeReg(i+1) == false) {
230 witchel  1.1.2.7              Temp[] assign = new Temp[] { regGeneral[i] ,
231 witchel  1.1.2.7                                           regGeneral[i+1] };
232 witchel  1.1.2.7              twoWordAssigns.add(Arrays.asList(assign));
233 witchel  1.1.2.7           }
234 witchel  1.1.2.5        }
235 witchel  1.1.2.5        twoWordAssigns = Collections.unmodifiableSet(twoWordAssigns);
236 witchel  1.1.2.5  
237 witchel  1.1.2.1     }
238 witchel  1.1.2.1      
239 witchel  1.1.2.1     public Temp[] getAllRegisters() { 
240 witchel  1.1.2.1        return (Temp[]) Util.safeCopy(Temp.arrayFactory, reg); 
241 witchel  1.1.2.1     }
242 witchel  1.1.2.1  
243 witchel  1.1.2.1     public Temp getRegister(int index) {
244 witchel  1.1.2.1        return reg[index];
245 witchel  1.1.2.1     }
246 witchel  1.1.2.1  
247 witchel  1.1.2.1     public Temp[] getGeneralRegisters() { 
248 witchel  1.1.2.1        return (Temp[]) Util.safeCopy(Temp.arrayFactory, regGeneral); 
249 witchel  1.1.2.1     }
250 witchel  1.1.2.1  
251 witchel  1.1.2.1     public TempFactory regTempFactory() { return regtf; }
252 pnkfelix 1.1.2.3  
253 pnkfelix 1.1.2.3     public boolean isRegister(Temp t) {
254 pnkfelix 1.1.2.3        return t.tempFactory() == regTempFactory();
255 pnkfelix 1.1.2.3     }
256 witchel  1.1.2.1  
257 witchel  1.1.2.1     public int getSize(Temp temp) {
258 witchel  1.1.2.1        if (temp instanceof TwoWordTemp) {
259 witchel  1.1.2.1           return 2;
260 witchel  1.1.2.1        } else {
261 witchel  1.1.2.1           return 1;
262 witchel  1.1.2.1        }
263 witchel  1.1.2.1     }
264 witchel  1.1.2.1  
265 witchel  1.1.2.5      public Set getRegAssignments(Temp t) {
266 witchel  1.1.2.5          if (t instanceof TwoWordTemp) {
267 witchel  1.1.2.5              return twoWordAssigns;
268 witchel  1.1.2.5          } else {
269 witchel  1.1.2.5              return oneWordAssigns;
270 witchel  1.1.2.5          }
271 witchel  1.1.2.5      }
272 witchel  1.1.2.5  
273 witchel  1.1.2.6     /** Return true for any registers we want to keep out of register
274 witchel  1.1.2.6      * allocation */ 
275 witchel  1.1.2.6     private boolean excludeReg(int reg) {
276 witchel  1.1.2.6        // These registers are used by the yellow pekoe assembler
277 witchel  1.1.2.6        if(reg == 14) return true;
278 witchel  1.1.2.6        if(reg == 15) return true;
279 witchel  1.1.2.6        if(reg == 24) return true;
280 witchel  1.1.2.7        if(reg == 25) return true;
281 witchel  1.1.2.7  
282 witchel  1.1.2.7        // These are the kernel registers
283 witchel  1.1.2.7        if(reg == 26) return true;
284 witchel  1.1.2.7        if(reg == 27) return true;
285 witchel  1.1.2.7  
286 witchel  1.1.2.7        // We exlude the GP since the C code we call into assumes GP has
287 witchel  1.1.2.7        // a proper value
288 witchel  1.1.2.7        // GP, SP, FP, LR
289 witchel  1.1.2.7        if(reg == 28) return true;
290 witchel  1.1.2.7        if(reg == 29) return true;
291 witchel  1.1.2.7        if(reg == 30) return true;
292 witchel  1.1.2.7        if(reg == 31) return true;
293 witchel  1.1.2.6        return false;
294 witchel  1.1.2.6     }
295 witchel  1.1.2.1  
296 pnkfelix 1.1.2.10    public Iterator suggestRegAssignment(Temp t, final Map regFile, final Collection preassigned) 
297 witchel  1.1.2.1        throws SpillException {
298 witchel  1.1.2.1        final ArrayList suggests = new ArrayList();
299 witchel  1.1.2.1        final ArrayList spills = new ArrayList();
300 witchel  1.1.2.1          
301 witchel  1.1.2.1        if (t instanceof TwoWordTemp) {
302 witchel  1.1.2.1           // double word, find two registers ( the strongARM
303 witchel  1.1.2.1           // doesn't require them to be in a row, but its 
304 witchel  1.1.2.1           // simpler to search for adjacent registers )
305 witchel  1.1.2.1           // FSK: forcing alignment to solve regalloc problem
306 witchel  1.1.2.1           for (int i=2; i<regtop; i+=2) {
307 witchel  1.1.2.6              if(excludeReg(i) == false && excludeReg(i + 1) == false) {
308 witchel  1.1.2.6                 Temp[] assign = new Temp[] { regGeneral[i+1] ,
309 witchel  1.1.2.6                                              regGeneral[i] };
310 witchel  1.1.2.6                 if ((regFile.get(assign[0]) == null) &&
311 witchel  1.1.2.6                     (regFile.get(assign[1]) == null)) {
312 witchel  1.1.2.6                    suggests.add(Arrays.asList(assign));
313 witchel  1.1.2.6                 } else {
314 witchel  1.1.2.6                    // don't add precolored registers to potential
315 witchel  1.1.2.6                    // spills. 
316 pnkfelix 1.1.2.10                    if ( !(preassigned.contains(regFile.get(assign[0]))) &&
317 pnkfelix 1.1.2.10                         !(preassigned.contains(regFile.get(assign[1])))){
318 witchel  1.1.2.6  
319 witchel  1.1.2.6                       Set s = new LinearSet(2);
320 witchel  1.1.2.6                       s.add(assign[1]);
321 witchel  1.1.2.6                       s.add(assign[0]);
322 witchel  1.1.2.6                       spills.add(s);
323 witchel  1.1.2.6                    }
324 witchel  1.1.2.1                 }
325 witchel  1.1.2.1              }
326 witchel  1.1.2.1           }
327 witchel  1.1.2.1  
328 witchel  1.1.2.1        } else {
329 witchel  1.1.2.1           // single word, find one register
330 witchel  1.1.2.1           for (int i=2; i<=regtop; i++) {
331 witchel  1.1.2.6              if(excludeReg(i) == false) {
332 witchel  1.1.2.6                 if ((regFile.get(regGeneral[i]) == null)) {
333 witchel  1.1.2.6                    suggests.add(ListFactory.singleton(regGeneral[i]));
334 witchel  1.1.2.6                 } else {
335 witchel  1.1.2.6                    Set s = new LinearSet(1);
336 witchel  1.1.2.6                    // don't add precolored registers to potential
337 witchel  1.1.2.6                    // spills. 
338 pnkfelix 1.1.2.10                   if (!( preassigned.contains(regFile.get(regGeneral[i])))){
339 witchel  1.1.2.6                       s.add(regGeneral[i]);
340 witchel  1.1.2.6                       spills.add(s);
341 witchel  1.1.2.6                    }
342 witchel  1.1.2.1                 }
343 witchel  1.1.2.1              }
344 witchel  1.1.2.1           }
345 witchel  1.1.2.1        }
346 witchel  1.1.2.1        if (suggests.isEmpty()) {
347 witchel  1.1.2.1           throw new SpillException() {
348 witchel  1.1.2.1                 public Iterator getPotentialSpills() {
349 witchel  1.1.2.1                    // System.out.println("RFI: Spills.size() "+spills.size());
350 witchel  1.1.2.1                    return spills.iterator();
351 witchel  1.1.2.1                 }
352 witchel  1.1.2.1              };
353 witchel  1.1.2.1        }
354 witchel  1.1.2.1        return suggests.iterator();
355 witchel  1.1.2.1     }
356 witchel  1.1.2.1  
357 witchel  1.1.2.1     public Set liveOnExit() {
358 witchel  1.1.2.1        return Collections.unmodifiableSet(liveOnExitRegs);
359 witchel  1.1.2.1     }
360 witchel  1.1.2.1      
361 witchel  1.1.2.1     public Set callerSave() { 
362 witchel  1.1.2.1        return Collections.unmodifiableSet(callerSaveRegs);
363 witchel  1.1.2.1     }
364 witchel  1.1.2.1      
365 witchel  1.1.2.1     public Set calleeSave() { 
366 witchel  1.1.2.1        return Collections.unmodifiableSet(calleeSaveRegs);
367 witchel  1.1.2.1     }
368 witchel  1.1.2.1      
369 witchel  1.1.2.1  
370 witchel  1.1.2.1     // LocationFactory interface.
371 witchel  1.1.2.1  
372 witchel  1.1.2.1      /** Allocate a global register of the specified type and return a
373 witchel  1.1.2.1       *  handle to it.
374 witchel  1.1.2.1       *  @param type a <code>IR.Tree.Type</code> specifying the type
375 witchel  1.1.2.1       *              of the register.
376 witchel  1.1.2.1       */
377 witchel  1.1.2.1     public Location allocateLocation(final int type) {
378 cananian 1.3.2.1        assert Type.isValid(type) : "invalid type";
379 cananian 1.3.2.1        assert !makeLocationDataCalled : "allocateLocation() may not be called after "+
380 cananian 1.3.2.1                    "makeLocationData() has been called.";
381 cananian 1.3.2.1        assert type!=Type.LONG && type!=Type.DOUBLE : "doubleword locations not implemented by this "+
382 cananian 1.3.2.1                    "LocationFactory";
383 witchel  1.1.2.1        // all other types of locations need a single register.
384 witchel  1.1.2.1  
385 witchel  1.1.2.1        // FSK: in theory, we could support arbitrary numbers of 
386 witchel  1.1.2.1        // allocations by switching to mem locations.  But I don't
387 witchel  1.1.2.1        // want to try to implement that yet.  
388 cananian 1.3.2.1        assert regtop > 4 : "allocated WAY too many locations, something's wrong";
389 witchel  1.1.2.1  
390 witchel  1.1.2.1        final Temp allocreg = reg[regtop--];
391 witchel  1.1.2.1  
392 witchel  1.1.2.1        // take this out of callersave, calleesave, etc.
393 witchel  1.1.2.1        calleeSaveRegs.remove(allocreg);
394 witchel  1.1.2.1        callerSaveRegs.remove(allocreg);
395 witchel  1.1.2.1        liveOnExitRegs.remove(allocreg);
396 witchel  1.1.2.1  
397 witchel  1.1.2.1        return new Location() {
398 witchel  1.1.2.1              public Exp makeAccessor(TreeFactory tf, HCodeElement source) {
399 witchel  1.1.2.1                 return new TEMP(tf, source, type, allocreg);
400 witchel  1.1.2.1              }
401 witchel  1.1.2.1           };
402 witchel  1.1.2.1     }
403 witchel  1.1.2.1  
404 witchel  1.1.2.1     /** The index of the next register to be allocated. */
405 witchel  1.1.2.1     private int regtop=25;
406 witchel  1.1.2.1  
407 witchel  1.1.2.1     // since we're just making global registers, we don't need to
408 witchel  1.1.2.1     // allocate the storage anywhere.
409 witchel  1.1.2.1  
410 witchel  1.1.2.1     /** Create an <code>HData</code> which allocates static space for
411 witchel  1.1.2.1       *  any <code>LocationFactory.Location</code>s that have been created.
412 witchel  1.1.2.1       *  As this implementation only allocates global registers, the
413 witchel  1.1.2.1       *  <code>HData</code> returned is always empty. */
414 witchel  1.1.2.1     public HData makeLocationData(final Frame f) {
415 witchel  1.1.2.1        // make sure we don't call allocateLocation after this.
416 witchel  1.1.2.1        makeLocationDataCalled=true;
417 witchel  1.1.2.1        // return an empty HData.
418 witchel  1.1.2.1        return new Data("location-data",f) {
419 witchel  1.1.2.1              /** Global data, so <code>HClass</code> is <code>null</code>. */
420 witchel  1.1.2.1              public HClass getHClass() { return null; }
421 witchel  1.1.2.1              /** Empty tree, so root element is <code>null</code>. */
422 witchel  1.1.2.1              public HDataElement getRootElement() { return null; }
423 witchel  1.1.2.1              /** Tell a human reader that there is no data here. */
424 cananian 1.1.2.8              public void print(java.io.PrintWriter pw, PrintCallback cb) {
425 witchel  1.1.2.1                 pw.println("--- no data ---");
426 witchel  1.1.2.1              }
427 witchel  1.1.2.1           };
428 witchel  1.1.2.1     }
429 witchel  1.1.2.1     private boolean makeLocationDataCalled=false;
430 cananian 1.2      }