1 cananian 1.1.2.7 // RegFileInfo.java, created Tue Nov 2 2:07:04 1999 by andyb 2 andyb 1.1.2.1 // Copyright (C) 1999 Andrew Berkheimer <andyb@mit.edu> 3 andyb 1.1.2.1 // Licensed under the terms of the GNU GPL; see COPYING for details. 4 andyb 1.1.2.1 package harpoon.Backend.Sparc; 5 andyb 1.1.2.1 6 andyb 1.1.2.1 import harpoon.Backend.Generic.Frame; 7 andyb 1.1.2.1 import harpoon.Backend.Generic.LocationFactory.Location; 8 andyb 1.1.2.8 import harpoon.Backend.Generic.RegFileInfo.SpillException; 9 cananian 1.1.2.13 import harpoon.ClassFile.HCode.PrintCallback; 10 andyb 1.1.2.3 import harpoon.ClassFile.HCodeElement; 11 andyb 1.1.2.3 import harpoon.ClassFile.HClass; 12 andyb 1.1.2.1 import harpoon.ClassFile.HData; 13 andyb 1.1.2.3 import harpoon.ClassFile.HDataElement; 14 andyb 1.1.2.3 import harpoon.IR.Tree.Type; 15 andyb 1.1.2.3 import harpoon.IR.Tree.TreeFactory; 16 andyb 1.1.2.3 import harpoon.IR.Tree.TEMP; 17 andyb 1.1.2.3 import harpoon.IR.Tree.Data; 18 andyb 1.1.2.3 import harpoon.IR.Tree.Exp; 19 andyb 1.1.2.1 import harpoon.Temp.Temp; 20 andyb 1.1.2.1 import harpoon.Temp.TempFactory; 21 cananian 1.5 import net.cscott.jutil.LinearSet; 22 cananian 1.5 import net.cscott.jutil.ListFactory; 23 andyb 1.1.2.1 import harpoon.Util.Util; 24 andyb 1.1.2.1 25 andyb 1.1.2.3 import java.util.ArrayList; 26 andyb 1.1.2.3 import java.util.Arrays; 27 andyb 1.1.2.1 import java.util.Collections; 28 andyb 1.1.2.1 import java.util.Iterator; 29 andyb 1.1.2.1 import java.util.Map; 30 andyb 1.1.2.1 import java.util.Set; 31 andyb 1.1.2.1 32 andyb 1.1.2.1 /** 33 andyb 1.1.2.2 * <code>RegFileInfo</code> contains architecture specific information 34 andyb 1.1.2.2 * about the registers for the Sparc architecture. It also implements 35 andyb 1.1.2.2 * the LocationFactory interface for allocating and tracking registers 36 andyb 1.1.2.2 * which are used for tracking global data. 37 andyb 1.1.2.1 * 38 andyb 1.1.2.1 * @author Andrew Berkheimer <andyb@mit.edu> 39 cananian 1.5 * @version $Id: RegFileInfo.java,v 1.5 2004/02/08 01:57:50 cananian Exp $ 40 andyb 1.1.2.1 */ 41 andyb 1.1.2.1 public class RegFileInfo 42 andyb 1.1.2.1 extends harpoon.Backend.Generic.RegFileInfo 43 andyb 1.1.2.1 implements harpoon.Backend.Generic.LocationFactory 44 andyb 1.1.2.1 { 45 andyb 1.1.2.2 private final TempFactory regtf; 46 andyb 1.1.2.6 private final Temp[] integerRegs; 47 andyb 1.1.2.2 private final Temp[] generalRegs; 48 andyb 1.1.2.6 private final Temp[] floatingRegs; 49 andyb 1.1.2.6 private final Temp[] generalIntRegs; 50 andyb 1.1.2.6 private final Temp[] allRegs; 51 andyb 1.1.2.2 private final Set callerSaveRegs; 52 andyb 1.1.2.2 private final Set calleeSaveRegs; 53 andyb 1.1.2.2 private final Set liveOnExitRegs; 54 andyb 1.1.2.3 private final Temp SP, FP; 55 andyb 1.1.2.3 private final TempBuilder tb; 56 andyb 1.1.2.1 57 andyb 1.1.2.3 public RegFileInfo(TempBuilder tb) { 58 andyb 1.1.2.3 this.tb = tb; 59 andyb 1.1.2.2 60 andyb 1.1.2.3 /* Sparc registers: 61 andyb 1.1.2.3 * %g0 - %g7: global, general registers. %g0 is zero register. 62 andyb 1.1.2.3 * %o0 - %o7: registers for local data and arguments to called 63 andyb 1.1.2.3 * subroutines. %o6 is stack pointer, %o7 is called 64 andyb 1.1.2.3 * subroutine return address. 65 andyb 1.1.2.3 * %l0 - %l7: local variables 66 andyb 1.1.2.3 * %i0 - %i7: registers for incoming subroutine arguments. 67 andyb 1.1.2.3 * %i6 is frame pointer and %i7 is subroutine return 68 andyb 1.1.2.3 * address. 69 andyb 1.1.2.6 * %f0 - %f31: floating point registewrs. 70 andyb 1.1.2.3 */ 71 andyb 1.1.2.3 regtf = new TempFactory() { 72 andyb 1.1.2.3 private int i = 0; 73 andyb 1.1.2.3 private final String scope = "sparc-registers"; 74 andyb 1.1.2.3 private final String[] names = {"%g0", "%g1", "%g2", "%g3", 75 andyb 1.1.2.3 "%g4", "%g5", "%g6", "%g7", "%o0", "%o1", "%o2", "%o3", 76 andyb 1.1.2.3 "%o4", "%o5", "%sp", "%o7", "%l0", "%l1", "%l2", "%l3", 77 andyb 1.1.2.3 "%l4", "%l5", "%l6", "%l7", "%i0", "%i1", "%i2", "%i3", 78 andyb 1.1.2.6 "%i4", "%i5", "%fp", "%i7", "%f0", "%f1", "%f2", "%f3", 79 andyb 1.1.2.6 "%f4", "%f5", "%f6", "%f7", "%f8", "%f9", "%f10", "%f11", 80 andyb 1.1.2.6 "%f12", "%f13", "%f14", "%f15", "%f16", "%f17", "%f18", "%f19", 81 andyb 1.1.2.6 "%f20", "%f21", "%f22", "%f23", "%f24", "%f25", "%f26", "%f27", 82 andyb 1.1.2.6 "%f28", "%f29", "%f30", "%f31"}; 83 andyb 1.1.2.3 84 andyb 1.1.2.3 public String getScope() { return scope; } 85 andyb 1.1.2.3 public synchronized String getUniqueID(String suggestion) { 86 cananian 1.3.2.1 assert i < names.length : "Already created all of "+ 87 cananian 1.3.2.1 "the Register bound Temps!!!"; 88 andyb 1.1.2.3 i++; 89 andyb 1.1.2.3 return names[i-1]; 90 andyb 1.1.2.3 } 91 andyb 1.1.2.3 }; 92 andyb 1.1.2.3 93 andyb 1.1.2.6 integerRegs = new Temp[32]; 94 andyb 1.1.2.6 generalIntRegs = new Temp[27]; 95 andyb 1.1.2.6 floatingRegs = new Temp[32]; 96 andyb 1.1.2.6 generalRegs = new Temp[59]; 97 andyb 1.1.2.6 allRegs = new Temp[64]; 98 andyb 1.1.2.3 99 andyb 1.1.2.3 int j = 0; 100 andyb 1.1.2.3 for (int i = 0; i < 32; i++) { 101 andyb 1.1.2.6 integerRegs[i] = new Temp(regtf); 102 andyb 1.1.2.9 allRegs[i] = integerRegs[i]; 103 andyb 1.1.2.3 if ((i != 0) && (i != 14) && (i != 15) && (i != 30) && (i != 31)) { 104 andyb 1.1.2.6 generalIntRegs[j] = integerRegs[i]; 105 andyb 1.1.2.6 generalRegs[j] = integerRegs[i]; 106 andyb 1.1.2.3 j++; 107 andyb 1.1.2.3 } 108 andyb 1.1.2.3 } 109 andyb 1.1.2.6 for (int i = 0; i < 32; i++) { 110 andyb 1.1.2.6 floatingRegs[i] = new Temp(regtf); 111 andyb 1.1.2.6 generalRegs[i+27] = floatingRegs[i]; 112 andyb 1.1.2.6 allRegs[i+32] = floatingRegs[i]; 113 andyb 1.1.2.6 } 114 andyb 1.1.2.3 115 andyb 1.1.2.6 SP = allRegs[14]; 116 andyb 1.1.2.6 FP = allRegs[30]; 117 andyb 1.1.2.2 118 andyb 1.1.2.10 // live on exit: %fp, %sp, %o0: return value, %o7: return address 119 andyb 1.1.2.4 // %g0: zero, always live 120 andyb 1.1.2.4 liveOnExitRegs = new LinearSet(5); 121 andyb 1.1.2.4 liveOnExitRegs.add(FP); 122 andyb 1.1.2.4 liveOnExitRegs.add(SP); 123 andyb 1.1.2.6 liveOnExitRegs.add(allRegs[0]); 124 andyb 1.1.2.10 liveOnExitRegs.add(allRegs[8]); 125 andyb 1.1.2.10 liveOnExitRegs.add(allRegs[15]); 126 andyb 1.1.2.4 127 andyb 1.1.2.4 // caller saved: clobbered by callee 128 andyb 1.1.2.4 // %g0-%g7, %o0-%o5, %o7 129 andyb 1.1.2.4 callerSaveRegs = new LinearSet(15); 130 andyb 1.1.2.4 for (int i = 0; i < 16; i++) 131 andyb 1.1.2.6 if (i != 14) /* i = 14 -> allRegs[14] -> %sp */ 132 andyb 1.1.2.6 callerSaveRegs.add(allRegs[i]); 133 andyb 1.1.2.4 134 andyb 1.1.2.4 // callee needs to save these itself 135 andyb 1.1.2.4 // none - all callee saving is done by the magic save 136 andyb 1.1.2.4 // instruction, go sparc go woohoo 137 andyb 1.1.2.4 calleeSaveRegs = new LinearSet(0); 138 andyb 1.1.2.1 } 139 andyb 1.1.2.3 140 andyb 1.1.2.3 // Sparc backend specific helpers... 141 andyb 1.1.2.3 142 andyb 1.1.2.3 final Temp SP() { return SP; } 143 andyb 1.1.2.3 final Temp FP() { return FP; } 144 andyb 1.1.2.3 145 andyb 1.1.2.3 // And now for the implementation of Generic.RegFileInfo 146 andyb 1.1.2.3 147 andyb 1.1.2.1 public Set liveOnExit() { 148 andyb 1.1.2.1 return Collections.unmodifiableSet(liveOnExitRegs); 149 andyb 1.1.2.1 } 150 andyb 1.1.2.1 151 andyb 1.1.2.1 public Set callerSave() { 152 andyb 1.1.2.3 return Collections.unmodifiableSet(callerSaveRegs); 153 andyb 1.1.2.1 } 154 andyb 1.1.2.1 155 andyb 1.1.2.1 public Set calleeSave() { 156 andyb 1.1.2.3 return Collections.unmodifiableSet(calleeSaveRegs); 157 andyb 1.1.2.1 } 158 andyb 1.1.2.1 159 andyb 1.1.2.1 public TempFactory regTempFactory() { return regtf; } 160 pnkfelix 1.1.2.12 161 pnkfelix 1.1.2.12 public boolean isRegister(Temp t) { 162 pnkfelix 1.1.2.12 return t.tempFactory() == regTempFactory(); 163 pnkfelix 1.1.2.12 } 164 andyb 1.1.2.1 165 andyb 1.1.2.1 public Iterator suggestRegAssignment(Temp t, final Map regFile) 166 andyb 1.1.2.8 throws SpillException { 167 andyb 1.1.2.1 168 andyb 1.1.2.3 final ArrayList suggests = new ArrayList(); 169 andyb 1.1.2.3 final ArrayList spills = new ArrayList(); 170 andyb 1.1.2.6 Temp[] possibleRegs; 171 andyb 1.1.2.6 172 andyb 1.1.2.6 if (tb.isFloatingPoint(t)) { 173 andyb 1.1.2.6 possibleRegs = floatingRegs; 174 andyb 1.1.2.6 } else { 175 andyb 1.1.2.6 possibleRegs = generalIntRegs; 176 andyb 1.1.2.6 } 177 andyb 1.1.2.1 178 andyb 1.1.2.3 if (tb.isTwoWord(t)) { 179 andyb 1.1.2.6 /* sparc32 doubles must be aligned on adjacent registers, 180 andyb 1.1.2.6 either 0/1, 2/3, 4/5, etc... */ 181 andyb 1.1.2.6 for (int i = 0; i < possibleRegs.length - 1; i+=2) { 182 andyb 1.1.2.6 Temp[] assign = new Temp[] { possibleRegs[i], 183 andyb 1.1.2.6 possibleRegs[i+1] }; 184 andyb 1.1.2.3 if ((regFile.get(assign[0]) == null) && 185 andyb 1.1.2.3 (regFile.get(assign[1]) == null)) { 186 andyb 1.1.2.3 suggests.add(Arrays.asList(assign)); 187 andyb 1.1.2.3 } else { 188 andyb 1.1.2.3 Set s = new LinearSet(2); 189 andyb 1.1.2.3 s.add(assign[0]); 190 andyb 1.1.2.3 s.add(assign[1]); 191 andyb 1.1.2.3 spills.add(s); 192 andyb 1.1.2.3 } 193 andyb 1.1.2.3 } 194 andyb 1.1.2.3 } else { 195 andyb 1.1.2.6 for (int i = 0; i < possibleRegs.length; i++) { 196 andyb 1.1.2.6 if ((regFile.get(possibleRegs[i]) == null)) { 197 andyb 1.1.2.6 suggests.add(ListFactory.singleton(possibleRegs[i])); 198 andyb 1.1.2.3 } else { 199 andyb 1.1.2.3 Set s = new LinearSet(1); 200 andyb 1.1.2.6 s.add(possibleRegs[i]); 201 andyb 1.1.2.3 spills.add(s); 202 andyb 1.1.2.3 } 203 andyb 1.1.2.3 } 204 andyb 1.1.2.3 } 205 andyb 1.1.2.3 if (suggests.isEmpty()) { 206 andyb 1.1.2.8 throw new SpillException() { 207 andyb 1.1.2.3 public Iterator getPotentialSpills() { 208 andyb 1.1.2.3 return spills.iterator(); 209 andyb 1.1.2.3 } 210 andyb 1.1.2.3 }; 211 andyb 1.1.2.3 } 212 andyb 1.1.2.3 return suggests.iterator(); 213 andyb 1.1.2.3 } 214 andyb 1.1.2.1 215 andyb 1.1.2.1 public Temp[] getAllRegisters() { 216 andyb 1.1.2.6 return (Temp[]) Util.safeCopy(Temp.arrayFactory, allRegs); 217 andyb 1.1.2.1 } 218 andyb 1.1.2.1 219 andyb 1.1.2.6 public Temp getRegister(int index) { return allRegs[index]; } 220 andyb 1.1.2.1 221 andyb 1.1.2.1 public Temp[] getGeneralRegisters() { 222 andyb 1.1.2.3 return (Temp[]) Util.safeCopy(Temp.arrayFactory, generalRegs); 223 andyb 1.1.2.1 } 224 andyb 1.1.2.1 225 andyb 1.1.2.1 // implementing LocationFactory 226 andyb 1.1.2.1 227 andyb 1.1.2.3 // start allocating registers from %g7 down to %g1 228 andyb 1.1.2.3 private int regtop = 7; 229 andyb 1.1.2.3 private boolean makeLocationDataCalled = false; 230 andyb 1.1.2.3 231 andyb 1.1.2.1 public Location allocateLocation(final int type) { 232 cananian 1.3.2.1 assert Type.isValid(type) : "Invalid type"; 233 cananian 1.3.2.1 assert type != Type.LONG && type != Type.DOUBLE : "Doubleword global locations not implemented"; 234 cananian 1.3.2.1 assert !makeLocationDataCalled : "Cannot allocate location - already ran makeLocationData"; 235 andyb 1.1.2.3 236 andyb 1.1.2.3 // Currently just uses the %g registers - nothing fancy yet. 237 cananian 1.3.2.1 assert regtop > 0 : "Sorry, can't do any more global locations"; 238 andyb 1.1.2.3 239 andyb 1.1.2.6 final Temp allocreg = allRegs[regtop--]; 240 andyb 1.1.2.3 241 andyb 1.1.2.3 calleeSaveRegs.remove(allocreg); 242 andyb 1.1.2.3 callerSaveRegs.remove(allocreg); 243 andyb 1.1.2.3 liveOnExitRegs.remove(allocreg); 244 andyb 1.1.2.3 245 andyb 1.1.2.3 return new Location() { 246 andyb 1.1.2.3 public Exp makeAccessor(TreeFactory tf, HCodeElement source) { 247 andyb 1.1.2.3 return new TEMP(tf, source, type, allocreg); 248 andyb 1.1.2.3 } 249 andyb 1.1.2.3 }; 250 andyb 1.1.2.1 } 251 andyb 1.1.2.1 252 andyb 1.1.2.3 // not allocating memory for these yet, so just return an empty 253 andyb 1.1.2.3 // HData for now 254 andyb 1.1.2.1 public HData makeLocationData(final Frame f) { 255 andyb 1.1.2.3 makeLocationDataCalled = true; 256 andyb 1.1.2.3 return new Data("location-data", f) { 257 andyb 1.1.2.3 public HClass getHClass() { return null; } 258 andyb 1.1.2.3 public HDataElement getRootElement() { return null; } 259 cananian 1.1.2.13 public void print(java.io.PrintWriter pw, PrintCallback cb) { 260 andyb 1.1.2.3 pw.println("--- no data ---"); 261 andyb 1.1.2.3 } 262 andyb 1.1.2.3 }; 263 andyb 1.1.2.1 } 264 cananian 1.2 }