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 <= index < 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 }