1 pnkfelix 1.1.2.1  // RegFileInfo.java, created Sat Sep 11 00:43:20 1999 by pnkfelix
  2 pnkfelix 1.1.2.1  // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
  3 pnkfelix 1.1.2.1  // Licensed under the terms of the GNU GPL; see COPYING for details.
  4 pnkfelix 1.1.2.1  package harpoon.Backend.StrongARM;
  5 pnkfelix 1.1.2.1  
  6 cananian 1.1.2.3  import harpoon.Backend.Generic.Frame;
  7 cananian 1.1.2.3  import harpoon.Backend.Generic.LocationFactory.Location;
  8 pnkfelix 1.1.2.14 import harpoon.Backend.Generic.RegFileInfo.SpillException;
  9 cananian 1.1.2.3  import harpoon.ClassFile.HClass;
 10 cananian 1.1.2.27 import harpoon.ClassFile.HCode.PrintCallback;
 11 cananian 1.1.2.3  import harpoon.ClassFile.HCodeElement;
 12 cananian 1.1.2.3  import harpoon.ClassFile.HData;
 13 cananian 1.1.2.3  import harpoon.ClassFile.HDataElement;
 14 cananian 1.1.2.3  import harpoon.IR.Tree.Data;
 15 cananian 1.1.2.3  import harpoon.IR.Tree.Exp;
 16 cananian 1.1.2.3  import harpoon.IR.Tree.TEMP;
 17 cananian 1.1.2.3  import harpoon.IR.Tree.TreeFactory;
 18 cananian 1.1.2.3  import harpoon.IR.Tree.Type;
 19 pnkfelix 1.1.2.1  import harpoon.Temp.Temp;
 20 pnkfelix 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 pnkfelix 1.1.2.1  import harpoon.Util.Util;
 24 pnkfelix 1.1.2.1  
 25 pnkfelix 1.1.2.1  import java.util.ArrayList;
 26 pnkfelix 1.1.2.1  import java.util.Arrays;
 27 pnkfelix 1.1.2.4  import java.util.Collections;
 28 pnkfelix 1.1.2.29 import java.util.Collection;
 29 pnkfelix 1.1.2.1  import java.util.Set;
 30 pnkfelix 1.1.2.20 import java.util.List;
 31 pnkfelix 1.1.2.1  import java.util.Iterator;
 32 pnkfelix 1.1.2.1  import java.util.Map;
 33 pnkfelix 1.1.2.15 import java.util.HashMap;
 34 pnkfelix 1.1.2.1  import java.util.HashSet;
 35 pnkfelix 1.1.2.1  
 36 pnkfelix 1.1.2.1  /**
 37 cananian 1.1.2.3   * <code>RegFileInfo</code> encapsulates information about the
 38 cananian 1.1.2.3   * StrongARM register set.  This object also implements
 39 cananian 1.1.2.3   * <code>Generic.LocationFactory</code>, allowing the creation of
 40 cananian 1.1.2.3   * global registers for the use of the runtime.
 41 pnkfelix 1.1.2.1   * 
 42 pnkfelix 1.1.2.1   * @author  Felix S. Klock II <pnkfelix@mit.edu>
 43 cananian 1.5       * @version $Id: RegFileInfo.java,v 1.5 2004/02/08 01:57:59 cananian Exp $
 44 pnkfelix 1.1.2.1   */
 45 cananian 1.1.2.3  public class RegFileInfo
 46 cananian 1.1.2.3      extends harpoon.Backend.Generic.RegFileInfo 
 47 cananian 1.1.2.3      implements harpoon.Backend.Generic.LocationFactory
 48 cananian 1.1.2.3  {
 49 pnkfelix 1.1.2.28     // FSK: experiment; expose all regs to allocator to try to
 50 pnkfelix 1.1.2.28     // match Scott's performance
 51 pnkfelix 1.1.2.28     private static final boolean EXPOSE_ALL_REGS = true;
 52 pnkfelix 1.1.2.28 
 53 pnkfelix 1.1.2.5      final Temp[] reg;
 54 pnkfelix 1.1.2.5      final Set callerSaveRegs;
 55 pnkfelix 1.1.2.5      final Set calleeSaveRegs;
 56 pnkfelix 1.1.2.5      final Set liveOnExitRegs;
 57 pnkfelix 1.1.2.5      final Temp[] regGeneral; 
 58 pnkfelix 1.1.2.4      final TempFactory regtf;
 59 pnkfelix 1.1.2.24     Set oneWordAssigns, twoWordAssigns;
 60 pnkfelix 1.1.2.4      
 61 pnkfelix 1.1.2.4      final Temp FP;  // Frame pointer
 62 pnkfelix 1.1.2.4      final Temp IP;  // Scratch register 
 63 pnkfelix 1.1.2.4      final Temp SP;  // Stack pointer
 64 pnkfelix 1.1.2.4      final Temp LR;  // Link register
 65 pnkfelix 1.1.2.4      final Temp PC;  // Program counter
 66 pnkfelix 1.1.2.18 
 67 pnkfelix 1.1.2.22     /** maxRegIndex returns an upper bound on the indexes that will be
 68 pnkfelix 1.1.2.22         returned by the <code>MachineRegLoc</code>s for this backend.
 69 pnkfelix 1.1.2.22         The indexes will fall in the range 
 70 pnkfelix 1.1.2.22         0 &lt;= index &lt; maxRegIndex().
 71 pnkfelix 1.1.2.22         This implementation returns 16, which includes system specific
 72 pnkfelix 1.1.2.22         registers such as PC and SP; this may be an over-conservative
 73 pnkfelix 1.1.2.22         value in need of revision!
 74 pnkfelix 1.1.2.22      */
 75 pnkfelix 1.1.2.22     public int maxRegIndex() { return 16; }
 76 pnkfelix 1.1.2.1  
 77 pnkfelix 1.1.2.4      /** Creates a <code>RegFileInfo</code>. 
 78 pnkfelix 1.1.2.4       */
 79 pnkfelix 1.1.2.4      public RegFileInfo() {
 80 pnkfelix 1.1.2.5          reg = new Temp[16];
 81 pnkfelix 1.1.2.5          regGeneral = new Temp[11];
 82 pnkfelix 1.1.2.5          callerSaveRegs = new LinearSet(4);
 83 pnkfelix 1.1.2.5          calleeSaveRegs = new LinearSet(9);
 84 pnkfelix 1.1.2.5          liveOnExitRegs = new LinearSet(5);
 85 pnkfelix 1.1.2.1          regtf = new TempFactory() {
 86 pnkfelix 1.1.2.1              private int i = 0;
 87 pnkfelix 1.1.2.1              private final String scope = "strongarm-registers";
 88 pnkfelix 1.1.2.4              
 89 pnkfelix 1.1.2.1              /* StrongARM has 16 general purpose registers.
 90 pnkfelix 1.1.2.1               * Special notes on ones we set aside:
 91 pnkfelix 1.1.2.1               *  r11 = fp
 92 pnkfelix 1.1.2.1               *  r12 = ip
 93 pnkfelix 1.1.2.1               *  r13 = sp
 94 pnkfelix 1.1.2.1               *  r14 = lr
 95 pnkfelix 1.1.2.1               *  r15 = pc (yes that's right. you can access the 
 96 pnkfelix 1.1.2.1               *              program counter like any other register)
 97 pnkfelix 1.1.2.1               */
 98 pnkfelix 1.1.2.1              private final String[] names = {"r0", "r1", "r2", "r3", "r4", "r5",
 99 pnkfelix 1.1.2.1                                              "r6", "r7", "r8", "r9", "r10", 
100 pnkfelix 1.1.2.1                                              "fp", "ip", "sp", "lr", "pc"};
101 pnkfelix 1.1.2.4              
102 pnkfelix 1.1.2.1              public String getScope() { return scope; }
103 pnkfelix 1.1.2.1              protected synchronized String getUniqueID(String suggestion) {
104 cananian 1.3.2.1                  assert i < names.length : "Don't use the "+
105 cananian 1.3.2.1                              "TempFactory of Register Temps";
106 pnkfelix 1.1.2.1                  i++;
107 pnkfelix 1.1.2.1                  return names[i-1];
108 pnkfelix 1.1.2.1              }
109 pnkfelix 1.1.2.1          };
110 pnkfelix 1.1.2.16 
111 pnkfelix 1.1.2.16         class RegTemp extends Temp implements MachineRegLoc {
112 pnkfelix 1.1.2.16             int offset;
113 pnkfelix 1.1.2.16             RegTemp(TempFactory tf, int offset) {
114 pnkfelix 1.1.2.16                 super(tf);
115 pnkfelix 1.1.2.16                 this.offset = offset;
116 pnkfelix 1.1.2.16             }
117 pnkfelix 1.1.2.16             public int kind() { return MachineRegLoc.KIND; }
118 pnkfelix 1.1.2.16             public int regIndex() { return offset; }
119 pnkfelix 1.1.2.16             
120 pnkfelix 1.1.2.16         }
121 pnkfelix 1.1.2.16 
122 pnkfelix 1.1.2.1          for (int i = 0; i < 16; i++) {
123 pnkfelix 1.1.2.16             reg[i] = new RegTemp(regtf, i);
124 pnkfelix 1.1.2.1              if (i < 11) regGeneral[i] = reg[i];
125 pnkfelix 1.1.2.1          }
126 pnkfelix 1.1.2.4          
127 pnkfelix 1.1.2.1          FP = reg[11];
128 pnkfelix 1.1.2.1          IP = reg[12];
129 pnkfelix 1.1.2.1          SP = reg[13];
130 pnkfelix 1.1.2.1          LR = reg[14];
131 pnkfelix 1.1.2.1          PC = reg[15];
132 pnkfelix 1.1.2.4          
133 pnkfelix 1.1.2.4          liveOnExitRegs.add(reg[0]);  // return value
134 cananian 1.1.2.6          liveOnExitRegs.add(reg[1]); // (possible) long word return value
135 pnkfelix 1.1.2.4          liveOnExitRegs.add(FP);
136 pnkfelix 1.1.2.4          liveOnExitRegs.add(SP);
137 pnkfelix 1.1.2.4          liveOnExitRegs.add(PC);
138 pnkfelix 1.1.2.1  
139 cananian 1.1.2.7          // callee clobbers r0,r1,r2,r3,ip,lr
140 pnkfelix 1.1.2.4          for(int i=0; i<4; i++) {
141 pnkfelix 1.1.2.4              callerSaveRegs.add(reg[i]);
142 pnkfelix 1.1.2.4          }
143 pnkfelix 1.1.2.25         callerSaveRegs.add(IP);
144 pnkfelix 1.1.2.25         callerSaveRegs.add(LR);
145 pnkfelix 1.1.2.4          
146 pnkfelix 1.1.2.25         // callee saves r4-r10,fp,sp
147 pnkfelix 1.1.2.25         for(int i=4; i<11; i++) {
148 pnkfelix 1.1.2.4              calleeSaveRegs.add(reg[i]);
149 pnkfelix 1.1.2.4          }
150 pnkfelix 1.1.2.25         calleeSaveRegs.add(FP);
151 pnkfelix 1.1.2.25         calleeSaveRegs.add(SP);
152 pnkfelix 1.1.2.21 
153 pnkfelix 1.1.2.28         Temp[] regs = EXPOSE_ALL_REGS ? reg : regGeneral;
154 pnkfelix 1.1.2.28 
155 pnkfelix 1.1.2.21         oneWordAssigns = new HashSet();
156 pnkfelix 1.1.2.28         for (int i=0; i<regs.length; i++) {
157 pnkfelix 1.1.2.28             Temp[] assign = new Temp[] { regs[i] };
158 pnkfelix 1.1.2.21             oneWordAssigns.add(Arrays.asList(assign));
159 pnkfelix 1.1.2.21         }
160 pnkfelix 1.1.2.21         oneWordAssigns = Collections.unmodifiableSet(oneWordAssigns);
161 pnkfelix 1.1.2.21         twoWordAssigns = new HashSet();
162 pnkfelix 1.1.2.28         for (int i=0; i<regs.length-1; i++) {
163 pnkfelix 1.1.2.28             Temp[] assign = new Temp[] { regs[i] ,
164 pnkfelix 1.1.2.28                                          regs[i+1] };
165 pnkfelix 1.1.2.21             twoWordAssigns.add(Arrays.asList(assign));
166 pnkfelix 1.1.2.21         }
167 pnkfelix 1.1.2.21         twoWordAssigns = Collections.unmodifiableSet(twoWordAssigns);
168 pnkfelix 1.1.2.1      }
169 pnkfelix 1.1.2.1      
170 pnkfelix 1.1.2.1      public Temp[] getAllRegisters() { 
171 pnkfelix 1.1.2.1          return (Temp[]) Util.safeCopy(Temp.arrayFactory, reg); 
172 pnkfelix 1.1.2.1      }
173 pnkfelix 1.1.2.4  
174 pnkfelix 1.1.2.1      public Temp getRegister(int index) {
175 pnkfelix 1.1.2.1          return reg[index];
176 pnkfelix 1.1.2.1      }
177 pnkfelix 1.1.2.1  
178 pnkfelix 1.1.2.1      public Temp[] getGeneralRegisters() { 
179 pnkfelix 1.1.2.28         return EXPOSE_ALL_REGS 
180 pnkfelix 1.1.2.28             ? getAllRegisters() 
181 pnkfelix 1.1.2.28             : (Temp[]) Util.safeCopy(Temp.arrayFactory, regGeneral)
182 pnkfelix 1.1.2.28             ; 
183 pnkfelix 1.1.2.1      }
184 pnkfelix 1.1.2.1  
185 pnkfelix 1.1.2.23     private TempFactory regTempFactory() { return regtf; }
186 pnkfelix 1.1.2.23 
187 pnkfelix 1.1.2.23     public boolean isRegister(Temp t) {
188 pnkfelix 1.1.2.23         return t.tempFactory() == regTempFactory();
189 pnkfelix 1.1.2.23     }
190 pnkfelix 1.1.2.1  
191 pnkfelix 1.1.2.20     public List expand(Temp temp) {
192 pnkfelix 1.1.2.1          if (temp instanceof TwoWordTemp) {
193 pnkfelix 1.1.2.20             TwoWordTemp tt = (TwoWordTemp) temp;
194 pnkfelix 1.1.2.20             return Arrays.asList(new Temp[]
195 pnkfelix 1.1.2.20                                  { tt.getLow(), tt.getHigh() });
196 pnkfelix 1.1.2.1          } else {
197 pnkfelix 1.1.2.20             return super.expand(temp);
198 pnkfelix 1.1.2.1          }
199 pnkfelix 1.1.2.1      }
200 pnkfelix 1.1.2.1  
201 pnkfelix 1.1.2.21     public Set getRegAssignments(Temp t) {
202 pnkfelix 1.1.2.21         if (t instanceof TwoWordTemp) {
203 pnkfelix 1.1.2.21             return twoWordAssigns;
204 pnkfelix 1.1.2.21         } else {
205 pnkfelix 1.1.2.21             return oneWordAssigns;
206 pnkfelix 1.1.2.21         }
207 pnkfelix 1.1.2.14     }
208 pnkfelix 1.1.2.14 
209 pnkfelix 1.1.2.29     public Iterator suggestRegAssignment(Temp t, final Map regFile, 
210 pnkfelix 1.1.2.29                                          Collection preassignedTemps) 
211 pnkfelix 1.1.2.14         throws SpillException {
212 pnkfelix 1.1.2.1          final ArrayList suggests = new ArrayList();
213 pnkfelix 1.1.2.1          final ArrayList spills = new ArrayList();
214 pnkfelix 1.1.2.8          
215 pnkfelix 1.1.2.28         Temp[] regs = EXPOSE_ALL_REGS ? reg : regGeneral;
216 pnkfelix 1.1.2.28 
217 pnkfelix 1.1.2.1          if (t instanceof TwoWordTemp) {
218 pnkfelix 1.1.2.8              // double word, find two registers ( the strongARM
219 pnkfelix 1.1.2.8              // doesn't require them to be in a row, but its 
220 pnkfelix 1.1.2.8              // simpler to search for adjacent registers )
221 pnkfelix 1.1.2.13             // FSK: forcing alignment to solve regalloc problem
222 pnkfelix 1.1.2.28 
223 pnkfelix 1.1.2.28             for (int i=0; i<regs.length-1; i+=2) {
224 pnkfelix 1.1.2.28                 Temp[] assign = new Temp[] { regs[i] ,
225 pnkfelix 1.1.2.28                                              regs[i+1] };
226 pnkfelix 1.1.2.1                  if ((regFile.get(assign[0]) == null) &&
227 pnkfelix 1.1.2.1                      (regFile.get(assign[1]) == null)) {
228 pnkfelix 1.1.2.1                      suggests.add(Arrays.asList(assign));
229 pnkfelix 1.1.2.1                  } else {
230 pnkfelix 1.1.2.19                     Set s = new LinearSet(2);
231 pnkfelix 1.1.2.19                     s.add(assign[0]);
232 pnkfelix 1.1.2.19                     s.add(assign[1]);
233 pnkfelix 1.1.2.19                     spills.add(s);
234 pnkfelix 1.1.2.1                  }
235 pnkfelix 1.1.2.1              }
236 pnkfelix 1.1.2.1  
237 pnkfelix 1.1.2.1          } else {
238 pnkfelix 1.1.2.1              // single word, find one register
239 pnkfelix 1.1.2.28             for (int i=0; i<regs.length; i++) {
240 pnkfelix 1.1.2.28                 if ((regFile.get(regs[i]) == null)) {
241 pnkfelix 1.1.2.28                     suggests.add(ListFactory.singleton(regs[i]));
242 pnkfelix 1.1.2.1                  } else {
243 pnkfelix 1.1.2.1                      Set s = new LinearSet(1);
244 pnkfelix 1.1.2.28                     s.add(regs[i]);
245 pnkfelix 1.1.2.19                     spills.add(s);
246 pnkfelix 1.1.2.1                  }
247 pnkfelix 1.1.2.1              }
248 pnkfelix 1.1.2.1          }
249 pnkfelix 1.1.2.1          if (suggests.isEmpty()) {
250 pnkfelix 1.1.2.14             throw new SpillException() {
251 pnkfelix 1.1.2.1                  public Iterator getPotentialSpills() {
252 pnkfelix 1.1.2.11                     // System.out.println("RFI: Spills.size() "+spills.size());
253 pnkfelix 1.1.2.1                      return spills.iterator();
254 pnkfelix 1.1.2.1                  }
255 pnkfelix 1.1.2.1              };
256 pnkfelix 1.1.2.1          }
257 pnkfelix 1.1.2.1          return suggests.iterator();
258 pnkfelix 1.1.2.1      }
259 pnkfelix 1.1.2.1  
260 pnkfelix 1.1.2.1      public Set liveOnExit() {
261 pnkfelix 1.1.2.4          return Collections.unmodifiableSet(liveOnExitRegs);
262 pnkfelix 1.1.2.4      }
263 pnkfelix 1.1.2.4      
264 pnkfelix 1.1.2.4      public Set callerSave() { 
265 pnkfelix 1.1.2.4          return Collections.unmodifiableSet(callerSaveRegs);
266 pnkfelix 1.1.2.4      }
267 pnkfelix 1.1.2.4      
268 pnkfelix 1.1.2.4      public Set calleeSave() { 
269 pnkfelix 1.1.2.4          return Collections.unmodifiableSet(calleeSaveRegs);
270 pnkfelix 1.1.2.1      }
271 pnkfelix 1.1.2.1      
272 cananian 1.1.2.3  
273 cananian 1.1.2.3      // LocationFactory interface.
274 pnkfelix 1.1.2.4  
275 cananian 1.1.2.3      /** Allocate a global register of the specified type and return a
276 cananian 1.1.2.3       *  handle to it.
277 cananian 1.1.2.3       *  @param type a <code>IR.Tree.Type</code> specifying the type
278 cananian 1.1.2.3       *              of the register.
279 cananian 1.1.2.3       */
280 cananian 1.1.2.3      public Location allocateLocation(final int type) {
281 cananian 1.3.2.1          assert Type.isValid(type) : "invalid type";
282 cananian 1.3.2.1          assert !makeLocationDataCalled : "allocateLocation() may not be called after "+
283 cananian 1.3.2.1                      "makeLocationData() has been called.";
284 cananian 1.3.2.1          assert type!=Type.LONG && type!=Type.DOUBLE : "doubleword locations not implemented by this "+
285 cananian 1.3.2.1                      "LocationFactory";
286 cananian 1.1.2.3          // all other types of locations need a single register.
287 pnkfelix 1.1.2.4  
288 pnkfelix 1.1.2.4          // FSK: in theory, we could support arbitrary numbers of 
289 pnkfelix 1.1.2.4          // allocations by switching to mem locations.  But I don't
290 pnkfelix 1.1.2.4          // want to try to implement that yet.  
291 cananian 1.3.2.1          assert regtop > 4 : "allocated WAY too many locations, something's wrong";
292 pnkfelix 1.1.2.4  
293 cananian 1.1.2.3          final Temp allocreg = reg[regtop--];
294 pnkfelix 1.1.2.4  
295 cananian 1.1.2.3          // take this out of callersave, calleesave, etc.
296 pnkfelix 1.1.2.4          calleeSaveRegs.remove(allocreg);
297 pnkfelix 1.1.2.4          callerSaveRegs.remove(allocreg);
298 pnkfelix 1.1.2.4          liveOnExitRegs.remove(allocreg);
299 pnkfelix 1.1.2.4  
300 cananian 1.1.2.3          return new Location() {
301 cananian 1.1.2.3              public Exp makeAccessor(TreeFactory tf, HCodeElement source) {
302 cananian 1.1.2.3                  return new TEMP(tf, source, type, allocreg);
303 cananian 1.1.2.3              }
304 cananian 1.1.2.3          };
305 cananian 1.1.2.3      }
306 pnkfelix 1.1.2.4  
307 cananian 1.1.2.3      /** The index of the next register to be allocated. */
308 cananian 1.1.2.3      private int regtop=10;
309 cananian 1.1.2.3  
310 cananian 1.1.2.3      // since we're just making global registers, we don't need to
311 cananian 1.1.2.3      // allocate the storage anywhere.
312 pnkfelix 1.1.2.4  
313 cananian 1.1.2.3      /** Create an <code>HData</code> which allocates static space for
314 cananian 1.1.2.3       *  any <code>LocationFactory.Location</code>s that have been created.
315 cananian 1.1.2.3       *  As this implementation only allocates global registers, the
316 cananian 1.1.2.3       *  <code>HData</code> returned is always empty. */
317 cananian 1.1.2.3      public HData makeLocationData(final Frame f) {
318 cananian 1.1.2.3          // make sure we don't call allocateLocation after this.
319 cananian 1.1.2.3          makeLocationDataCalled=true;
320 cananian 1.1.2.3          // return an empty HData.
321 cananian 1.1.2.3          return new Data("location-data",f) {
322 cananian 1.1.2.3              /** Global data, so <code>HClass</code> is <code>null</code>. */
323 cananian 1.1.2.3              public HClass getHClass() { return null; }
324 cananian 1.1.2.3              /** Empty tree, so root element is <code>null</code>. */
325 cananian 1.1.2.3              public HDataElement getRootElement() { return null; }
326 cananian 1.1.2.3              /** Tell a human reader that there is no data here. */
327 cananian 1.1.2.27             public void print(java.io.PrintWriter pw, PrintCallback cb) {
328 cananian 1.1.2.3                  pw.println("--- no data ---");
329 cananian 1.1.2.3              }
330 cananian 1.1.2.3          };
331 cananian 1.1.2.3      }
332 cananian 1.1.2.3      private boolean makeLocationDataCalled=false;
333 pnkfelix 1.1.2.30 
334 pnkfelix 1.1.2.30     public int occupancy(Temp t) {
335 pnkfelix 1.1.2.30         if (t instanceof TwoWordTemp) {
336 pnkfelix 1.1.2.30             return 2;
337 pnkfelix 1.1.2.30         } else {
338 pnkfelix 1.1.2.30             return 1;
339 pnkfelix 1.1.2.30         }
340 pnkfelix 1.1.2.30     }
341 pnkfelix 1.1.2.30 
342 pnkfelix 1.1.2.30     public int pressure(Temp a, Temp b) {
343 pnkfelix 1.1.2.30         if (b instanceof TwoWordTemp ) { // FSK unconstrained ==> ASYMMETRIC!
344 pnkfelix 1.1.2.30             return 2;
345 pnkfelix 1.1.2.30         } else {
346 pnkfelix 1.1.2.30             return 1;
347 pnkfelix 1.1.2.30         }
348 pnkfelix 1.1.2.30     }
349 pnkfelix 1.1.2.30     
350 pnkfelix 1.1.2.30     public List assignment(Temp needy, Collection occupied) {
351 pnkfelix 1.1.2.30         Set s = new HashSet( allRegs() );
352 pnkfelix 1.1.2.30         s.removeAll( occupied );
353 pnkfelix 1.1.2.30         Iterator t = s.iterator();
354 pnkfelix 1.1.2.30         if (needy instanceof TwoWordTemp) {
355 pnkfelix 1.1.2.30             if (s.size() < 2) return null;
356 pnkfelix 1.1.2.30             return Arrays.asList( new Temp[] { (Temp) t.next(),
357 pnkfelix 1.1.2.30                                                (Temp) t.next() });
358 pnkfelix 1.1.2.30         } else {
359 pnkfelix 1.1.2.30             if (s.size() < 1) return null;
360 pnkfelix 1.1.2.30             return Arrays.asList( new Temp[] { (Temp) t.next() } );
361 pnkfelix 1.1.2.30         }
362 pnkfelix 1.1.2.30     }
363 pnkfelix 1.1.2.30     
364 pnkfelix 1.1.2.30     public Collection illegal(Temp t) {
365 pnkfelix 1.1.2.30         return Collections.EMPTY_SET;
366 pnkfelix 1.1.2.30     }
367 cananian 1.2      }