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 }