1 witchel  1.1.2.1 // StackInfo.java, created Mon Aug 21 21:02:54 EDT 2000 by witchel
  2 cananian 1.1.2.6 // Copyright (C) 2000 Emmett Witchel <witchel@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.Util.Util;
  7 witchel  1.1.2.1 import harpoon.Temp.TempList;
  8 witchel  1.1.2.1 import harpoon.Temp.Temp;
  9 witchel  1.1.2.1 import harpoon.Temp.LabelList;
 10 witchel  1.1.2.1 import harpoon.Temp.Label;
 11 witchel  1.1.2.1 import harpoon.IR.Tree.INVOCATION;
 12 witchel  1.1.2.2 import harpoon.IR.Tree.METHOD;
 13 witchel  1.1.2.1 import harpoon.IR.Tree.Type;
 14 witchel  1.1.2.1 import harpoon.IR.Tree.Typed;
 15 witchel  1.1.2.1 import harpoon.IR.Tree.PreciselyTyped;
 16 witchel  1.1.2.1 import harpoon.IR.Tree.MEM;
 17 witchel  1.1.2.1 import harpoon.IR.Tree.NAME;
 18 witchel  1.1.2.2 import harpoon.IR.Tree.TEMP;
 19 witchel  1.1.2.1 import harpoon.IR.Tree.ExpList;
 20 witchel  1.1.2.1 
 21 witchel  1.1.2.1 import java.util.ArrayList;
 22 witchel  1.1.2.1 import java.util.HashMap;
 23 witchel  1.1.2.1 import java.io.PrintStream;
 24 witchel  1.1.2.1 
 25 witchel  1.1.2.1 /** 
 26 witchel  1.1.2.1  * This class encapsulates information about a given stack frame,
 27 witchel  1.1.2.1  * e.g., does it grow up or down, where is the return address stored,
 28 witchel  1.1.2.1  * that sort of thing.
 29 witchel  1.1.2.1  * <p>
 30 witchel  1.1.2.1  * INPUT
 31 witchel  1.1.2.1  * <p>
 32 witchel  1.1.2.1  * <code>callInfo</code> is called up front for every call made by
 33 witchel  1.1.2.1  * this frame.  This information is necessary for construction of the
 34 witchel  1.1.2.1  * MIPS stack frame, but it is not necessary for conventions that use a
 35 witchel  1.1.2.1  * non-virtual frame pointer.
 36 witchel  1.1.2.1  * <code>regAllocUsedRegs</code> is called after register allocation
 37 witchel  1.1.2.1  * to give the stackinfo object knowledge of which callee saved
 38 witchel  1.1.2.1  * registers were used.
 39 witchel  1.1.2.1  * <code>regAllocLocalWords</code> is called after the register
 40 witchel  1.1.2.1  * allocation to give the stackinfo object knowledge of how many temps
 41 witchel  1.1.2.1  * the spill code needs.  It would be nice to give the types of the
 42 witchel  1.1.2.1  * temps to the stackinfo object and let it map temp index to registers
 43 witchel  1.1.2.1  * and stack offset, but that is not the current interface to the spill
 44 witchel  1.1.2.1  * information. 
 45 witchel  1.1.2.1  * <p>
 46 witchel  1.1.2.1  * OUTPUT
 47 witchel  1.1.2.1  * <P>
 48 witchel  1.1.2.1  * Lots of useful offsets.
 49 witchel  1.1.2.1  * The multi-word (or multi-stack slot) temp support is currently
 50 witchel  1.1.2.1  * limited to two word temps.  It is ugly, but its not clear that
 51 witchel  1.1.2.1  * generalizing the solution is a good thing at this stage.
 52 witchel  1.1.2.1  */
 53 witchel  1.1.2.1 
 54 witchel  1.1.2.1 public class StackInfo {
 55 witchel  1.1.2.1    // Values so the stack object can tell the argument loading code
 56 witchel  1.1.2.1    // where to load arguments
 57 witchel  1.1.2.1    public static final int REGISTER      = 0;
 58 witchel  1.1.2.1    public static final int STACK         = 1;
 59 witchel  1.1.2.1    public static final int REGSTACKSPLIT = 2;
 60 witchel  1.1.2.5    // Every stack frame is aligned on a 32 byte boundary to facilitate
 61 witchel  1.1.2.5    // the tag unchecked load/store optimization
 62 witchel  1.1.2.5    public static final int BYTEALIGNMENT = 32;
 63 witchel  1.1.2.1 
 64 witchel  1.1.2.1    private class CallInfo {
 65 witchel  1.1.2.1       public CallInfo() {
 66 witchel  1.1.2.1          // 8 entries should be sufficient for most calls.
 67 witchel  1.1.2.1          arg2word = new ArrayList(8);
 68 witchel  1.1.2.1       }
 69 witchel  1.1.2.1       public void setArg2Word(int arg, int word) {
 70 witchel  1.1.2.1          arg2word.add(new Integer(word));
 71 cananian 1.3.2.1          assert arg == arg2word.size() - 1;
 72 witchel  1.1.2.1       }
 73 witchel  1.1.2.1       public int getArg2Word(int arg) {
 74 cananian 1.3.2.1          assert arg >= 0 && arg < arg2word.size();
 75 witchel  1.1.2.1          Integer i = (Integer)arg2word.get(arg);
 76 witchel  1.1.2.1          return i.intValue();
 77 witchel  1.1.2.1       }
 78 witchel  1.1.2.1       public int getArg2StackSlot(int arg) {
 79 witchel  1.1.2.1          Integer i = (Integer)arg2word.get(arg);
 80 witchel  1.1.2.1          return word2StackWords(i.intValue());
 81 witchel  1.1.2.1       }
 82 witchel  1.1.2.1       public int nArgs() {
 83 witchel  1.1.2.1          // Array has extra entry at the end so we know how big the
 84 witchel  1.1.2.1          // last arg is
 85 witchel  1.1.2.1          return arg2word.size() - 1;
 86 witchel  1.1.2.1       }
 87 witchel  1.1.2.1       public void print(PrintStream ps) {
 88 witchel  1.1.2.1          ps.print(" len=" + arg2word.size());
 89 witchel  1.1.2.1          for(int i = 0; i < arg2word.size(); ++i) {
 90 witchel  1.1.2.1             ps.print(" a" + i + "=" + ((Integer)arg2word.get(i)).intValue());
 91 witchel  1.1.2.1          }
 92 witchel  1.1.2.1          ps.println("");
 93 witchel  1.1.2.1       }
 94 witchel  1.1.2.1 
 95 witchel  1.1.2.1       private ArrayList arg2word;
 96 witchel  1.1.2.1       private int word2StackWords(int w) {
 97 cananian 1.3.2.1          assert w >= 0;
 98 witchel  1.1.2.1          if(w < NARGREGS) return 0;
 99 witchel  1.1.2.1          return w - NARGREGS;
100 witchel  1.1.2.1       }
101 witchel  1.1.2.1    }
102 witchel  1.1.2.1 
103 witchel  1.1.2.1    /**
104 witchel  1.1.2.1     * Each new frame should create a new stack info object.
105 witchel  1.1.2.1     */
106 witchel  1.1.2.1    public StackInfo(RegFileInfo _regfile) {
107 witchel  1.1.2.1       max_arg_words = 0;
108 witchel  1.1.2.1       locals_done = callee_done = false;
109 witchel  1.1.2.1       regfile = _regfile;
110 witchel  1.1.2.1       fixed_words = 2;           // fp and ra
111 witchel  1.1.2.1       inv2info = new HashMap(5);
112 witchel  1.1.2.1    }
113 witchel  1.1.2.1 
114 witchel  1.1.2.1    /**
115 witchel  1.1.2.1     * Argument build are is the lowest region on the mips stack,
116 witchel  1.1.2.1     * starting at 0(sp)
117 witchel  1.1.2.1     */
118 witchel  1.1.2.2    public int argOffset(Object inv, int arg_idx) {
119 witchel  1.1.2.1       CallInfo ci = (CallInfo)inv2info.get(inv);
120 witchel  1.1.2.4       if(trace >= TRACE_FUNCTION) {
121 witchel  1.1.2.4          psout.print("a" + arg_idx + " " 
122 witchel  1.1.2.4                      + (REGSIZE*ci.getArg2Word(arg_idx)) + "(sp)");
123 witchel  1.1.2.4       }
124 witchel  1.1.2.1       return REGSIZE * ci.getArg2Word(arg_idx);
125 witchel  1.1.2.1    }
126 witchel  1.1.2.1    /**
127 witchel  1.1.2.1     * Give a higher offset.  If you are big endian, this is the least
128 witchel  1.1.2.1     * signifigant word.
129 witchel  1.1.2.1     */
130 witchel  1.1.2.2    public int argSecondOffset(Object inv, int arg_idx) {
131 witchel  1.1.2.1       CallInfo ci = (CallInfo)inv2info.get(inv);
132 witchel  1.1.2.4       if(trace >= TRACE_FUNCTION) {
133 witchel  1.1.2.4          psout.print("alow" + arg_idx + " " 
134 witchel  1.1.2.4                      + (REGSIZE*(ci.getArg2Word(arg_idx)+1)) + "(sp)");
135 witchel  1.1.2.4       }
136 cananian 1.3.2.1       assert ci.getArg2Word(arg_idx) + 1 < ci.getArg2Word(arg_idx + 1);
137 witchel  1.1.2.1       return REGSIZE * (ci.getArg2Word(arg_idx) + 1);
138 witchel  1.1.2.1    }
139 witchel  1.1.2.1    /**
140 witchel  1.1.2.1     * Call this to find out if a given argument is to be passed in a
141 witchel  1.1.2.1     * register, on the stack, or (for multi-word temporaries) split
142 witchel  1.1.2.1     * between register and stack.
143 witchel  1.1.2.1     */
144 witchel  1.1.2.2    public int argWhere(Object inv, int arg_idx) {
145 witchel  1.1.2.1       CallInfo ci = (CallInfo)inv2info.get(inv);
146 witchel  1.1.2.4       if(trace >= TRACE_FUNCTION) {
147 witchel  1.1.2.4          psout.print("WHERE ");
148 witchel  1.1.2.2          if(inv instanceof INVOCATION) {
149 witchel  1.1.2.2             print(psout, (INVOCATION)inv);
150 witchel  1.1.2.2          } else {
151 cananian 1.3.2.1             assert inv instanceof METHOD;
152 witchel  1.1.2.2             print(psout, (METHOD)inv);
153 witchel  1.1.2.2          }
154 witchel  1.1.2.1          ci.print(psout);
155 witchel  1.1.2.1          psout.print("a" + arg_idx);
156 witchel  1.1.2.1       }
157 witchel  1.1.2.1       if(ci.getArg2Word(arg_idx) < NARGREGS) {
158 witchel  1.1.2.4          if(trace >= TRACE_FUNCTION) psout.println(" REG");
159 witchel  1.1.2.1          return REGISTER;
160 witchel  1.1.2.1       }
161 witchel  1.1.2.4       if(trace >= TRACE_FUNCTION) psout.println(" STK");
162 witchel  1.1.2.1       return STACK;
163 witchel  1.1.2.1    }
164 witchel  1.1.2.4    private int argWhereInternal(Object inv, int arg_idx) {
165 witchel  1.1.2.4       int old_trace = trace;
166 witchel  1.1.2.4       int ret;
167 witchel  1.1.2.4       trace = TRACE_NONE;
168 witchel  1.1.2.4       ret = argWhere(inv, arg_idx);
169 witchel  1.1.2.4       trace = old_trace;
170 witchel  1.1.2.4       return ret;
171 witchel  1.1.2.4    }
172 witchel  1.1.2.2 
173 witchel  1.1.2.1    /**
174 witchel  1.1.2.1     * Return which argument register this argument goes in
175 witchel  1.1.2.1     */
176 witchel  1.1.2.2    public Temp argReg(Object inv, int arg_idx) {
177 cananian 1.3.2.1       assert argWhereInternal(inv, arg_idx) == REGISTER;
178 witchel  1.1.2.1       CallInfo ci = (CallInfo)inv2info.get(inv);
179 witchel  1.1.2.1       return idx2ArgReg(ci.getArg2Word(arg_idx));
180 witchel  1.1.2.1    }
181 witchel  1.1.2.1    /**
182 witchel  1.1.2.1     * Return the second argument register for a two word temporary.
183 witchel  1.1.2.1     */
184 witchel  1.1.2.2    public Temp argSecondReg(Object inv, int arg_idx) {
185 cananian 1.3.2.1       assert argWhereInternal(inv, arg_idx) == REGISTER;
186 witchel  1.1.2.1       CallInfo ci = (CallInfo)inv2info.get(inv);
187 cananian 1.3.2.1       assert ci.getArg2Word(arg_idx) + 1 < ci.getArg2Word(arg_idx + 1);
188 witchel  1.1.2.1       return idx2ArgReg(ci.getArg2Word(arg_idx) + 1);
189 witchel  1.1.2.1    }
190 witchel  1.1.2.1 
191 witchel  1.1.2.1    /**
192 witchel  1.1.2.1     * Functions with the <code>regAlloc</code> prefix are functions
193 witchel  1.1.2.1     * that take information  about register allocation to fill out our
194 witchel  1.1.2.1     * model of the stack 
195 witchel  1.1.2.1     */
196 witchel  1.1.2.1 
197 witchel  1.1.2.1    /**
198 witchel  1.1.2.1     * Give the stack frame model the array of used callee saved
199 witchel  1.1.2.1     * registers.  There should be no duplicates, and you probably want
200 witchel  1.1.2.1     * to sort the list (it probably should be a LinearSet)
201 witchel  1.1.2.1     */
202 witchel  1.1.2.1    public void regAllocUsedRegs(ArrayList used) {
203 witchel  1.1.2.1       callee_regs = new ArrayList(used);
204 witchel  1.1.2.1       callee_regs.retainAll(regfile.calleeSave());
205 witchel  1.1.2.1       // These are always dealt with, we don't need extra stack space
206 witchel  1.1.2.1       // for them
207 witchel  1.1.2.1       callee_regs.remove(regfile.SP);
208 witchel  1.1.2.1       callee_regs.remove(regfile.FP);
209 witchel  1.1.2.1       callee_done = true;
210 witchel  1.1.2.1    }
211 witchel  1.1.2.1    /**
212 witchel  1.1.2.1     * Return how many callee saved registers there are for this frame
213 witchel  1.1.2.1     */
214 witchel  1.1.2.1    public int calleeSaveTotal() {
215 cananian 1.3.2.1       assert callee_done;
216 witchel  1.1.2.1       return callee_regs.size();
217 witchel  1.1.2.1    }
218 witchel  1.1.2.1    /**
219 witchel  1.1.2.1     * Return the register for this callee saved register index
220 witchel  1.1.2.1     */
221 witchel  1.1.2.1    public Temp calleeReg(int callee_idx) {
222 cananian 1.3.2.1       assert callee_done;
223 cananian 1.3.2.1       assert callee_idx < callee_regs.size() && callee_idx >= 0 : "Callee idx=" + callee_idx + " Size=" + callee_regs.size();
224 witchel  1.1.2.1       return (Temp)callee_regs.get(callee_idx);
225 witchel  1.1.2.1    }
226 witchel  1.1.2.1    /**
227 witchel  1.1.2.1     * Return the offset for a given callee saved register index.
228 witchel  1.1.2.1     */
229 witchel  1.1.2.1    public int calleeSaveOffset(int callee_idx) {
230 cananian 1.3.2.1       assert callee_done;
231 cananian 1.3.2.1       assert callee_idx < callee_regs.size() && callee_idx >= 0;
232 witchel  1.1.2.5       return frameSize() + fp_off - (REGSIZE * (callee_idx + 1));
233 witchel  1.1.2.1    }
234 witchel  1.1.2.1    /**
235 witchel  1.1.2.1     * On top (highest address) of the MIPS stack frame are the
236 witchel  1.1.2.1     * locals/temporaries This isn't a 
237 witchel  1.1.2.1     * great interface, but it is the info we get from RegAlloc.  I
238 witchel  1.1.2.1     * would have expected somethine like  an ExpList, just like arguments.
239 witchel  1.1.2.1     */
240 witchel  1.1.2.1    public void regAllocLocalWords(int w) {
241 witchel  1.1.2.1       locals_done = true;
242 witchel  1.1.2.1       local_words = w;
243 witchel  1.1.2.1    }
244 witchel  1.1.2.1    /**
245 witchel  1.1.2.1     * Return the offset for a given local index
246 witchel  1.1.2.1     */
247 witchel  1.1.2.1    public int localSaveOffset(int local_idx) {
248 cananian 1.3.2.1       assert callee_done && locals_done;
249 cananian 1.3.2.1       assert local_idx < local_words && local_idx >= 0;
250 witchel  1.1.2.5       return frameSize() + fp_off - (REGSIZE * (callee_regs.size() + 1 + 
251 witchel  1.1.2.5                                                 local_idx));
252 witchel  1.1.2.1    }
253 witchel  1.1.2.1    public int getFPOffset() {
254 witchel  1.1.2.1       return frameSize() + fp_off;
255 witchel  1.1.2.1    }
256 witchel  1.1.2.1    public int getRAOffset() {
257 witchel  1.1.2.1       return frameSize() + ra_off;
258 witchel  1.1.2.1    }
259 witchel  1.1.2.1    public int frameSize() {
260 cananian 1.3.2.1       assert locals_done && callee_done;
261 witchel  1.1.2.3       int fs = REGSIZE * (max_arg_words 
262 witchel  1.1.2.3                           + callee_regs.size()
263 witchel  1.1.2.3                           + local_words
264 witchel  1.1.2.3                           + fixed_words);
265 witchel  1.1.2.3       if(fs/BYTEALIGNMENT * BYTEALIGNMENT == fs)
266 witchel  1.1.2.3          return fs;
267 witchel  1.1.2.3       else
268 witchel  1.1.2.3          return (fs/BYTEALIGNMENT + 1) * BYTEALIGNMENT;
269 witchel  1.1.2.1    }
270 witchel  1.1.2.1    
271 witchel  1.1.2.1    /**
272 witchel  1.1.2.1     * Call <code>callInfo</code> with the destination label and argument list
273 witchel  1.1.2.1     * for all calls made by this activation frame.  The stack then
274 witchel  1.1.2.1     * knows about every function it has to call.
275 witchel  1.1.2.1     */
276 witchel  1.1.2.1    public void callInfo(INVOCATION inv) {
277 witchel  1.1.2.1       ExpList elist = inv.getArgs();
278 witchel  1.1.2.1       int words = 0;
279 witchel  1.1.2.1       CallInfo ci = new CallInfo();
280 witchel  1.1.2.1       int narg = 0;
281 witchel  1.1.2.4       if(trace >= TRACE_INTERNAL_CALLS) {
282 witchel  1.1.2.1          print(psout, inv);
283 witchel  1.1.2.1       }
284 witchel  1.1.2.1       for(; elist != null; ++narg, elist = elist.tail) {
285 witchel  1.1.2.1          // Like gcc we don't break doubles into one
286 witchel  1.1.2.1          // register and one stack word 
287 witchel  1.1.2.1          if(words == NARGREGS - 1 && nWords(elist.head) == 2) {
288 witchel  1.1.2.1             words ++;
289 witchel  1.1.2.1          }
290 witchel  1.1.2.1          ci.setArg2Word(narg, words);
291 witchel  1.1.2.4          if(trace >= TRACE_INTERNAL_CALLS) {
292 witchel  1.1.2.1             psout.print(" a" + narg + "=" + words);
293 witchel  1.1.2.1          }
294 witchel  1.1.2.1          words += nWords(elist.head);
295 witchel  1.1.2.1       }
296 witchel  1.1.2.1       // Set the value after the last entry so we know the total number
297 witchel  1.1.2.1       ci.setArg2Word(narg, words);
298 witchel  1.1.2.4       if(trace >= TRACE_INTERNAL_CALLS) {
299 witchel  1.1.2.1          psout.print(" a" + narg + "=" + words);
300 witchel  1.1.2.1          psout.println(" END");
301 witchel  1.1.2.1       }
302 witchel  1.1.2.1       // XXX is this right? If we need any params, leave at least 16 bytes.
303 witchel  1.1.2.4       // If this is the largest call we have seen, then increase max_arg_words
304 witchel  1.1.2.4       if(words > max_arg_words)
305 witchel  1.1.2.1          if(words < 4)
306 witchel  1.1.2.1             max_arg_words = 4;
307 witchel  1.1.2.1          else
308 witchel  1.1.2.1             max_arg_words = words;
309 witchel  1.1.2.1       inv2info.put(inv, ci);
310 witchel  1.1.2.1    }
311 witchel  1.1.2.2    /**
312 witchel  1.1.2.2     * For callee argument information call <code>callInfo</code> with
313 witchel  1.1.2.2     * METHOD object, and we will interpret the parameter list.
314 witchel  1.1.2.2     */
315 witchel  1.1.2.2    public void callInfo(METHOD meth) {
316 witchel  1.1.2.2       // This code duplicates the algorithm from the INVOCATION
317 witchel  1.1.2.2       // version which annoys me, but merging them would also be
318 witchel  1.1.2.2       // annoying because of the differences between INVOCATION and
319 witchel  1.1.2.2       // METHOD 
320 witchel  1.1.2.2       CallInfo ci = new CallInfo();
321 witchel  1.1.2.2       int words = 0;
322 witchel  1.1.2.4       if(trace >= TRACE_INTERNAL_CALLS) {
323 witchel  1.1.2.2          print(psout, meth);
324 witchel  1.1.2.2       }
325 witchel  1.1.2.2       // skip param[0], which is the explicit 'exceptional return
326 witchel  1.1.2.2       // address'
327 witchel  1.1.2.2       int narg = 0;
328 witchel  1.1.2.2       for(int param_narg = 1; param_narg < meth.getParamsLength(); 
329 witchel  1.1.2.2           ++param_narg) {
330 witchel  1.1.2.2          // Like gcc we don't break doubles into one
331 witchel  1.1.2.2          // register and one stack word 
332 witchel  1.1.2.2          if(words == NARGREGS - 1 
333 witchel  1.1.2.2             && nWords(meth.getParams(param_narg)) == 2) {
334 witchel  1.1.2.2             words ++;
335 witchel  1.1.2.2          }
336 witchel  1.1.2.2          ci.setArg2Word(narg, words);
337 witchel  1.1.2.4          if(trace >= TRACE_INTERNAL_CALLS) {
338 witchel  1.1.2.2             psout.print(" Ma" + narg + "=" + words);
339 witchel  1.1.2.2          }
340 witchel  1.1.2.2          words += nWords(meth.getParams(param_narg));
341 witchel  1.1.2.2          narg++;
342 witchel  1.1.2.2       }
343 witchel  1.1.2.2       // Set the value after the last entry so we know the total number
344 witchel  1.1.2.2       ci.setArg2Word(narg, words);
345 witchel  1.1.2.4       if(trace >= TRACE_INTERNAL_CALLS) {
346 witchel  1.1.2.2          psout.print(" Ma" + narg + "=" + words);
347 witchel  1.1.2.2          psout.println(" MEND");
348 witchel  1.1.2.2       }
349 witchel  1.1.2.2       inv2info.put(meth, ci);
350 witchel  1.1.2.2    }
351 witchel  1.1.2.2 
352 witchel  1.1.2.1 
353 witchel  1.1.2.1    private final int NARGREGS = 4; // how many arg regs
354 witchel  1.1.2.1    private final int REGSIZE  = 4; // bytes per reg
355 witchel  1.1.2.1    private final int ra_off   = -4;
356 witchel  1.1.2.1    private final int fp_off   = -8;
357 witchel  1.1.2.1    
358 witchel  1.1.2.1    private int max_arg_words;
359 witchel  1.1.2.1    private HashMap inv2info;
360 witchel  1.1.2.1    private RegFileInfo regfile;
361 witchel  1.1.2.1    private boolean locals_done;
362 witchel  1.1.2.1    private int local_words;
363 witchel  1.1.2.1    private boolean callee_done;
364 witchel  1.1.2.4    private final int TRACE_NONE           = 0;
365 witchel  1.1.2.4    private final int TRACE_FUNCTION       = 1;
366 witchel  1.1.2.4    private final int TRACE_INTERNAL_CALLS = 2;
367 witchel  1.1.2.4    private int trace = TRACE_NONE;
368 witchel  1.1.2.1    private final PrintStream psout = System.out;
369 witchel  1.1.2.1    private ArrayList callee_regs;
370 witchel  1.1.2.1    private int fixed_words;
371 witchel  1.1.2.1    private void print(PrintStream ps, INVOCATION inv) {
372 witchel  1.1.2.1       if(inv.getFunc() instanceof NAME)
373 witchel  1.1.2.1          ps.print("func=" + (NAME)inv.getFunc());
374 witchel  1.1.2.1       else if(inv.getFunc() instanceof MEM)
375 witchel  1.1.2.1          ps.print("func=" + (MEM)inv.getFunc());
376 witchel  1.1.2.1       else
377 witchel  1.1.2.1          ps.print("Ufunc=" + inv.getFunc());
378 witchel  1.1.2.2    }
379 witchel  1.1.2.2    private void print(PrintStream ps, METHOD meth) {
380 witchel  1.1.2.2       ps.print("meth=" + meth.toString());
381 witchel  1.1.2.1    }
382 witchel  1.1.2.1 
383 witchel  1.1.2.1    private Temp idx2ArgReg(int idx) {
384 cananian 1.3.2.1       assert idx < NARGREGS;
385 witchel  1.1.2.1       switch(idx) {
386 witchel  1.1.2.1       case 0: return regfile.A0;
387 witchel  1.1.2.1       case 1: return regfile.A1;
388 witchel  1.1.2.1       case 2: return regfile.A2;
389 witchel  1.1.2.1       case 3: return regfile.A3;
390 witchel  1.1.2.1       }
391 cananian 1.3.2.1       assert false;
392 witchel  1.1.2.1       return null;
393 witchel  1.1.2.1    }
394 witchel  1.1.2.1    private int  nWords(Typed ty) {
395 witchel  1.1.2.1       switch (ty.type()) {
396 witchel  1.1.2.1       case Type.LONG: case Type.DOUBLE: return 2;
397 witchel  1.1.2.1       default: return 1;
398 witchel  1.1.2.1       }
399 witchel  1.1.2.1    }
400 cananian 1.2     }