1 // CodeGen.spec, created Tue Jul 6 12:12:41 1999 by pnkfelix
   2 // Copyright (C) 1999 Felix S. Klock II <pnkfelix@mit.edu>
   3 // Licensed under the terms of the GNU GPL; see COPYING for details.
   4 package harpoon.Backend.MIPS;
   5 
   6 import harpoon.Backend.Maps.NameMap;
   7 import harpoon.Backend.StrongARM.TwoWordTemp;
   8 import harpoon.ClassFile.HClass;
   9 import harpoon.ClassFile.HCodeElement;
  10 import harpoon.ClassFile.HMethod;
  11 import harpoon.IR.Assem.Instr;
  12 import harpoon.IR.Assem.InstrEdge;
  13 import harpoon.IR.Assem.InstrMEM;
  14 import harpoon.IR.Assem.InstrJUMP;
  15 import harpoon.IR.Assem.InstrMOVE;
  16 import harpoon.IR.Assem.InstrCALL;
  17 import harpoon.IR.Assem.InstrLABEL;
  18 import harpoon.IR.Assem.InstrDIRECTIVE;
  19 import harpoon.IR.Assem.InstrFactory;
  20 import harpoon.Analysis.Tree.DominatingMemoryAccess;
  21 import harpoon.IR.Tree.TreeDerivation;
  22 import harpoon.IR.Tree.Bop;
  23 import harpoon.IR.Tree.Uop;
  24 import harpoon.IR.Tree.Type;
  25 import harpoon.IR.Tree.TEMP;
  26 import harpoon.IR.Tree.Typed;
  27 import harpoon.IR.Tree.PreciselyTyped;
  28 import harpoon.IR.Tree.ExpList;
  29 import harpoon.Util.Util;
  30 import harpoon.Temp.TempList;
  31 import harpoon.Temp.Temp;
  32 import harpoon.Temp.LabelList;
  33 import harpoon.Temp.Label;
  34 
  35 import harpoon.IR.Tree.BINOP;
  36 import harpoon.IR.Tree.CALL;
  37 import harpoon.IR.Tree.INVOCATION;
  38 import harpoon.IR.Tree.CJUMP;
  39 import harpoon.IR.Tree.CONST;
  40 import harpoon.IR.Tree.EXPR;
  41 import harpoon.IR.Tree.JUMP;
  42 import harpoon.IR.Tree.LABEL;
  43 import harpoon.IR.Tree.MEM;
  44 import harpoon.IR.Tree.MOVE;
  45 import harpoon.IR.Tree.NAME;
  46 import harpoon.IR.Tree.NATIVECALL;
  47 import harpoon.IR.Tree.OPER;
  48 import harpoon.IR.Tree.RETURN;
  49 import harpoon.IR.Tree.TEMP;
  50 import harpoon.IR.Tree.UNOP;
  51 import harpoon.IR.Tree.SEQ;
  52 
  53 import java.util.ArrayList;
  54 import java.util.Arrays;
  55 import java.util.Collections;
  56 import java.util.Comparator;
  57 import java.util.List;
  58 import java.util.LinkedList;
  59 import java.util.Set;
  60 import java.util.Map;
  61 import java.util.HashMap;
  62 import java.util.Iterator;
  63 
  64 
  65 /**
  66  * <code>MIPS.CodeGen</code> is a code-generator for the MIPS II architecture.
  67  * 
  68  * @see "Kane, <U>MIPS Risc Architecture</U>"
  69  * @author  Emmett Witchel <witchel@mit.edu>
  70  * @version $Id: CodeGen.spec,v 1.6 2004/02/08 01:57:34 cananian Exp $
  71  */
  72 // All calling conventions and endian layout comes from observing gcc
  73 // for vpekoe.  This is standard for cc on MIPS IRIX64 lion 6.2 03131016 IP19.
  74 // as well.
  75 // MIPS is big endian by default.  This also applies to long longs and
  76 // doubles (for which we are using software fp.  The most sinifigant
  77 // 32 bit quantity is at the lower address (and in v0, as opposed to
  78 // v1) 
  79 
  80 public class CodeGen extends harpoon.Backend.Generic.MaxMunchCG { 
  81     private void collectCallInfo(harpoon.IR.Tree.Data data) {
  82     }
  83     private void collectCallInfo(harpoon.IR.Tree.Code code) {
  84        //System.out.println("CCCollectCallInfo " + code + " Name " 
  85        //+ code.getName()
  86        //+ " Meth " + code.getMethod());
  87        
  88        final class CallVisitor extends harpoon.IR.Tree.TreeVisitor {
  89           public void visit(harpoon.IR.Tree.Tree treee){
  90              assert false : "Should never visit generic harpoon.IR.Tree.Treein CallVisitor";
  91           } // end visit(harpoon.IR.Tree.Tree)
  92           public void visit(harpoon.IR.Tree.Stm stm) {
  93              harpoon.IR.Tree.INVOCATION inv = null;
  94              if(stm instanceof harpoon.IR.Tree.CALL) {
  95                 inv = (harpoon.IR.Tree.INVOCATION)stm;
  96              }
  97              if(stm instanceof harpoon.IR.Tree.NATIVECALL) {
  98                 inv = (harpoon.IR.Tree.INVOCATION)stm;
  99              }
 100              if(inv != null) {
 101                 stack.callInfo(inv);
 102              }
 103           } // end visit(harpoon.IR.Tree.Stm)
 104           public void visit(harpoon.IR.Tree.SEQ treee){
 105              treee.getLeft().accept(this);
 106              treee.getRight().accept(this);
 107           }
 108        }
 109        CallVisitor visitor = new CallVisitor();
 110        harpoon.IR.Tree.Tree t = (harpoon.IR.Tree.Tree) code.getRootElement();
 111        t.accept(visitor);
 112     }
 113 
 114     // InstrFactory to generate Instrs from
 115     private InstrFactory instrFactory;
 116 
 117     // Track information about the activation frame for this method.
 118     private StackInfo stack;
 119     
 120 
 121     final RegFileInfo regfile;
 122     private Temp  v0, v1, a0, a1, a2, a3, t0, t1, t2, 
 123        t3, t4, t5, t6, t7, t8, t9, GP, SP, FP, LR;
 124     Comparator regComp;
 125     private final Temp call_use[];
 126     /* The maximum def set for a call */
 127     private Temp call_def_full[];
 128     /* The def set we use in our support functions */
 129     private  Temp call_def_builtin[];
 130 
 131     // whether to generate stabs debugging information in output (-g flag)
 132     // Currently broken on MIPS
 133     private static final boolean stabsDebugging = true;
 134     private static final boolean stabsLineDebugging = false;
 135 
 136     // NameMap for calling C functions.
 137     NameMap nameMap;
 138 
 139     // whether to generate a.out-style or elf-style segment directives
 140     private final boolean is_elf;
 141     // mipspro assember requires section attributes in .section directive
 142     // GNU as requires that they be absent
 143     // NB: Our output will not work with mipspro assemblers!
 144     private final boolean mipspro_assem = false;
 145     // whether to use soft-float or hard-float calling convention.
 146     private final boolean soft_float = false; // skiffs use hard-float
 147     // Add yellow pekoe register usage suffixes to long instr patterns
 148     private boolean yellow_pekoe = false;
 149     // Add phantom instructions that indicate DA register usage
 150     private boolean enable_daregs = false;
 151 
 152     public CodeGen(Frame frame, boolean is_elf) {
 153        super(frame);
 154         last = null;
 155         this.regfile = (RegFileInfo) frame.getRegFileInfo();
 156         this.nameMap = frame.getRuntime().getNameMap();
 157         this.is_elf = is_elf;
 158     this.yellow_pekoe = frame.getType().equalsIgnoreCase("yp");
 159     this.enable_daregs = frame.getType().equalsIgnoreCase("da");
 160     v0 = regfile.V0;
 161     v1 = regfile.V1;
 162     a0 = regfile.A0;
 163     a1 = regfile.A1;
 164     a2 = regfile.A2;
 165     a3 = regfile.A3;
 166         t0 = regfile.T0;
 167     t1 = regfile.T1;
 168     t2 = regfile.T2;
 169     t3 = regfile.T3;
 170     t4 = regfile.T4;
 171     t5 = regfile.T5;
 172     t6 = regfile.T6;
 173     t7 = regfile.T7;
 174     t8 = regfile.T8;
 175     t9 = regfile.T9;
 176         GP = regfile.GP; // reg 28
 177         SP = regfile.SP; // reg 29
 178         FP = regfile.FP; // s8
 179         LR = regfile.LR; // reg 31
 180     call_use = new Temp[] {a0, a1, a2, a3, SP, FP};
 181     call_def_full = new Temp[] {v0, v1, a0, a1, a2, a3, t0, t1, 
 182                                 t2, t3, t4, t5, t6, t7, t8, t9, 
 183                                 GP, LR};
 184     call_def_builtin = new Temp[] {v0, v1, a0, a1, a2, a3, t0, t1, t2,
 185                                    GP, LR};
 186 
 187 
 188     // allow sorting of registers so that stm and ldm work correctly.
 189     final Map regToNum = new HashMap();
 190     for (int i=0; i<regfile.reg.length; i++)
 191        regToNum.put(regfile.reg[i], new Integer(i));
 192     regComp = new Comparator() {
 193           public int compare(Object o1, Object o2) {
 194              assert regToNum.keySet().contains(o1) : o1+" not in regToNum's keys";
 195              assert regToNum.keySet().contains(o2) : o2+" not in regToNum's keys";
 196              return ((Integer)regToNum.get(o1)).intValue() -
 197                 ((Integer)regToNum.get(o2)).intValue();
 198           }
 199        };
 200     }
 201 
 202 
 203 
 204     /** Sub-class to represent delay-slots.
 205      * <code>optimize()</code> uses this class information to determine that
 206      * it should rearrange code to try to eliminate these instructions.
 207      * @author Emmett Witchel <witchel@mit.edu>
 208      */
 209     private class InstrDELAYSLOT extends Instr {
 210        // a nop to fill the delay slot
 211        public InstrDELAYSLOT(InstrFactory inf, HCodeElement source) {
 212           super(inf, source, "nop  # delay slot");
 213        }
 214     }
 215     private String GetLdSuffix(MEM root) {
 216        String suffix = "";
 217        if(root.isSmall()) {
 218           switch(root.bitwidth()) {
 219           case 8:
 220              if(root.signed())
 221                 suffix = "b";
 222              else
 223                 suffix = "bu";
 224              break;
 225           case 16:
 226              if(root.signed())
 227                 suffix = "h";
 228              else
 229                 suffix = "hu";
 230              break;
 231           default:
 232              assert false : "Constant offset memory load wants to load bitwidth that is not 8, 16";       
 233           }
 234        } else {
 235           suffix = "w";
 236        }
 237        return suffix;
 238     }
 239     private String GetStSuffix(MOVE root) {
 240        String suffix = "";
 241        if(((MEM)root.getDst()).isSmall()) {
 242           switch(((MEM)root.getDst()).bitwidth()) {
 243           case 8:
 244              suffix = "b";
 245              break;
 246           case 16:
 247              suffix = "h";
 248              break;
 249           default:
 250              assert false : "Constant offset memory load wants to load bitwidth that is not 8, 16, or 32";       
 251           }
 252        } else {
 253           suffix = "w";
 254        }
 255        return suffix;
 256     }
 257 
 258     /** The main Instr layer; nothing below this line should call
 259         emit(Instr) directly, unless they are constructing extensions
 260         of Instr.
 261     */
 262     private Instr emit(HCodeElement root, String assem,
 263                        Temp[] dst, Temp[] src,
 264                        boolean canFallThrough, List<Label> targets) {
 265        return emit(new Instr( instrFactory, root, assem,
 266                               dst, src, canFallThrough, targets));
 267     }                 
 268 
 269     /** Secondary emit layer; for primary usage by the other emit
 270         methods. 
 271     */
 272     private Instr emit2(HCodeElement root, String assem,
 273                         Temp[] dst, Temp[] src) {
 274         return emit(root, assem, dst, src, true, null);
 275     }
 276     /** Single dest Single source Emit Helper. */
 277     private Instr emit( HCodeElement root, String assem, 
 278                         Temp dst, Temp src) {
 279        if( dst == null && src == null )
 280           return emit2(root, assem, new Temp[]{ }, new Temp[]{ });
 281        else if (dst == null)
 282           return emit2(root, assem, new Temp[]{ }, new Temp[]{ src });
 283        else if (src == null)
 284           return emit2(root, assem, new Temp[]{ }, new Temp[]{ src });
 285        return emit2(root, assem, new Temp[]{ dst }, new Temp[]{ src });
 286     }
 287     /** Single dest Two source Emit Helper. */
 288     private Instr emit( HCodeElement root, String assem, 
 289                         Temp dst, Temp src1, Temp src2) {
 290        if(dst == null)
 291           return emit2(root, assem, new Temp[]{ },
 292                        new Temp[]{ src1, src2 });
 293        return emit2(root, assem, new Temp[]{ dst },
 294                     new Temp[]{ src1, src2 });
 295     }
 296     /** Single dest Null source Emit Helper. */
 297     private Instr emit( HCodeElement root, String assem, Temp dst) {
 298        return emit2(root, assem, new Temp[]{ dst }, null);
 299     }
 300     /** Null dest Null source Emit Helper. */
 301     private Instr emit( HCodeElement root, String assem ) {
 302         return emit2(root, assem, null, null);
 303     }
 304 
 305     /** Single dest Single source emit InstrMOVE helper */
 306     private Instr emitMOVE( HCodeElement root, String assem,
 307                            Temp dst, Temp src) {
 308        return emit(new InstrMOVE( instrFactory, root, assem+"         # move",
 309                                   new Temp[]{ dst },
 310                             new Temp[]{ src }));
 311     }
 312     // This is called before a compound instr that defines a long temp 
 313     // It is intended to fool the global register allocator into not
 314    // believing that the destination long and a source long can be
 315    // allocated to the same registers 
 316     private Instr emitRegAllocDef( HCodeElement root, Temp t) {
 317        return null;
 318        // assert t != null : t;
 319        // return emitDUMMY( root, "# Reg alloc def " + t, new Temp[]{t}, null);
 320     }
 321     private Instr emitRegAllocUse( HCodeElement root, Temp t) {
 322        assert t != null : t;
 323        return emitDUMMY( root, "# Reg alloc use " + t, null, new Temp[]{t});
 324     }
 325 
 326     /* Branching instruction emit helper. 
 327        Instructions emitted using this *can* fall through.
 328     */
 329     private Instr emit( HCodeElement root, String assem,
 330                         Temp[] dst, Temp[] src, Label[] targets ) {
 331         return emit(new Instr( instrFactory, root, assem,
 332                         dst, src, true, Arrays.asList(targets)));
 333     }
 334     
 335     /* Branching instruction emit helper. 
 336        Instructions emitted using this *cannot* fall through.
 337     */
 338     private Instr emitNoFall( HCodeElement root, String assem,
 339                        Temp[] dst, Temp[] src, Label[] targets ) {
 340         return emit(new Instr( instrFactory, root, assem,
 341                         dst, src, false, Arrays.asList(targets)));
 342     }
 343 
 344     /* Call instruction emit helper. 
 345        Instructions emitted using this *cannot* fall through.
 346     */
 347     private Instr emitCallNoFall( HCodeElement root, String assem,
 348                        Temp[] dst, Temp[] src, Label[] targets ) {
 349         List<Label> tlist = (targets==null?null:Arrays.asList(targets));
 350         return emit(new InstrCALL( instrFactory, root, assem,
 351                                    dst, src, false, tlist));
 352     }
 353 
 354     private Instr emitNativeCall( HCodeElement root, String assem,
 355                                   Temp[] dst, Temp[] src, 
 356                                   boolean canFall, Label[] targets) {
 357        List<Label> tlist = (targets==null?null:Arrays.asList(targets));
 358        return emit(new InstrCALL( instrFactory, root, assem,
 359                                   dst, src, canFall, tlist));
 360     }
 361 
 362     private static class InstrDUMMY extends Instr {
 363         InstrDUMMY(InstrFactory inf, HCodeElement root,
 364                    String assem, Temp[] dst, Temp[] src) {
 365             super(inf, root, assem, dst, src, true, null);
 366         }
 367         public boolean isDummy() { return true; }
 368     }
 369     private Instr emitDUMMY( HCodeElement root, String assem,
 370                              Temp[] dst, Temp[] src ) {
 371         return emit(new InstrDUMMY( instrFactory, root, assem, dst, src));
 372     }
 373     /* InstrJUMP emit helper; automatically adds entry to
 374        label->branches map. */ 
 375     private Instr emitJUMP( HCodeElement root, String assem, Label l ) {
 376        return emit( new InstrJUMP( instrFactory, root, assem, l ));
 377     }
 378     private Instr emitCondBr( HCodeElement root, String assem, Temp srca,
 379                             Temp srcb, Label l ) {
 380        if(srca == null && srcb == null) {
 381           return emitJUMP(root, assem, l);
 382        } else if (srca == null) {
 383           return emit( root, assem, null, new Temp[] {srcb}, true,
 384                        Arrays.asList(new Label[] { l }) );
 385        } else if (srcb == null) {
 386           return emit( root, assem, null, new Temp[] {srca}, true,
 387                        Arrays.asList(new Label[] { l }) );
 388        } else {
 389           return emit( root, assem, null, new Temp[] {srca, srcb}, true,
 390                        Arrays.asList(new Label[] { l }) );
 391        }
 392     }
 393 
 394     /* InstrLABEL emit helper. */
 395     private Instr emitLABEL( HCodeElement root, String assem, Label l ) {
 396         return emit( new InstrLABEL( instrFactory, root, assem, l ));
 397     }   
 398     /* InstrLABEL emit helper. */
 399     private Instr emitNoFallLABEL( HCodeElement root, String assem, Label l ) {
 400         return emit( InstrLABEL.makeNoFall( instrFactory, root, assem, l ));
 401     }   
 402 
 403     /* InstrDIRECTIVE emit helper. */
 404     private Instr emitDIRECTIVE( HCodeElement root, String assem ) {
 405         return emit( new InstrDIRECTIVE( instrFactory, root, assem ));
 406     }
 407     /* InstrDIRECTIVE emit helper. */
 408     private Instr emitNoFallDIRECTIVE( HCodeElement root, String assem ) {
 409         return emit( InstrDIRECTIVE.makeNoFall( instrFactory, root, assem ));
 410     }
 411     private Instr emitDELAYSLOT(HCodeElement root) {
 412         return emit(new InstrDELAYSLOT(instrFactory, root));
 413     }
 414     private void emitLineDebugInfo(HCodeElement root) {
 415        if(stabsLineDebugging && stabsDebugging) {
 416           Label l = new Label();
 417           emit( new InstrLABEL(instrFactory, root, l.toString() + ":", l) );
 418           emit( new InstrDIRECTIVE(instrFactory, root, 
 419                                    ".stabn 68,0," + root.getLineNumber()
 420                                    + "," + l));
 421        }
 422     }
 423     private String getDAOpcodeSuffix(HCodeElement root) {
 424        if(enable_daregs) {
 425           harpoon.Backend.MIPS.Frame mframe = (harpoon.Backend.MIPS.Frame) frame;
 426           Object danum = mframe.daNum(root);
 427           if(danum != null) {
 428              if(DominatingMemoryAccess.isDef(danum)) {
 429                 return "lda";
 430              } else {
 431                 return "da";
 432              }
 433           }
 434        } else {
 435           harpoon.Backend.MIPS.Frame mframe = (harpoon.Backend.MIPS.Frame) frame;
 436           if(mframe.memAccessNoTagCheck(root)) {
 437              return ".u";
 438           }
 439        }
 440        return "";
 441     }
 442     private String getDANum(HCodeElement root) {
 443        if(enable_daregs) {
 444           harpoon.Backend.MIPS.Frame mframe = (harpoon.Backend.MIPS.Frame) frame;
 445           Object danum = mframe.daNum(root);
 446           if(danum != null) {
 447              int dan = DominatingMemoryAccess.num(danum);
 448              return ", " + (new Integer(dan).toString());
 449           }
 450        }
 451        return "";
 452     }
 453 private String makeDAFlushBitmask() {
 454    harpoon.Backend.MIPS.Frame mframe = (harpoon.Backend.MIPS.Frame) frame;
 455    Set usedda = mframe.getUsedDANum();
 456    int bitmask = 0;
 457    for(Iterator it = usedda.iterator(); it.hasNext(); ) {
 458       int i = ((Integer)it.next()).intValue();
 459       bitmask |= 1 << i;
 460       assert i < 31; // Don't overflow int
 461    }
 462    // XXX Always set DA reg 0 because we use it on function
 463    // entry/return.  Even for leaf procedures currently.  If we get to
 464    // optimizing leaves, then this would not be necessary for an
 465    // optimized leaf 
 466    bitmask |= 1;
 467    Integer bitm = new Integer(bitmask);
 468    return bitm.toString();
 469 }
 470 
 471     private boolean is16BitOffset(long val) {
 472         // addressing mode two takes a 12 bit unsigned offset, with
 473         // an additional bit in the instruction word indicating whether
 474         // to add or subtract this offset.  This means that there
 475         // are two representations for zero offset: +0 and -0.
 476         long absval = (val<0)?-val:val;
 477         return (absval&(~0xFFFF))==0;
 478     }
 479     private boolean is16BitOffset(Number n) {
 480         if (n instanceof Double || n instanceof Float) return false;
 481         else return is16BitOffset(n.longValue());
 482     }
 483 
 484     // helper for operand2 shifts
 485     private boolean is5BitShift(long val) {
 486         return (val>=0) && (val<=31);
 487     }
 488     private boolean is5BitShift(Number n) {
 489         if (n instanceof Double || n instanceof Float) return false;
 490         else return is5BitShift(n.longValue());
 491     }
 492     private boolean isShiftOp(int op) {
 493         switch (op) {
 494         case Bop.SHL: case Bop.SHR: case Bop.USHR: return true;
 495         default: return false;
 496         }
 497     }
 498     private String shiftOp2Str(int op) {
 499         switch (op) {
 500         case Bop.SHL: return "sll";
 501         case Bop.SHR: return "sra";
 502         case Bop.USHR: return "srl";
 503         default: throw new Error("Illegal shift operation");
 504         }
 505     }
 506     // helper for comparison operations
 507     private boolean isCmpOp(int op) {
 508         switch (op) {
 509         case Bop.CMPEQ: case Bop.CMPNE:
 510         case Bop.CMPGT: case Bop.CMPGE:
 511         case Bop.CMPLT: case Bop.CMPLE: return true;
 512         default: return false;
 513         }
 514     }
 515     // Given a comparison operation, return the implementation in MIPS
 516     // assembler
 517     private String cmpOp2AsStr(int op) {
 518         switch (op) {
 519         case Bop.CMPEQ: return "seq";
 520         case Bop.CMPNE: return "sne";
 521         case Bop.CMPGT: return "sgt";
 522         case Bop.CMPGE: return "sge";
 523         case Bop.CMPLE: return "sle";
 524         case Bop.CMPLT: return "slt";
 525         default: throw new Error("Illegal compare operation");
 526         }
 527     }
 528     // Given a comparison operation, return the corresponding branch
 529     // in MIPS assembler
 530     private String cmpOp2BrStr(int op) {
 531         switch (op) {
 532         case Bop.CMPEQ: return "beq";
 533         case Bop.CMPNE: return "bne";
 534         case Bop.CMPGT: return "bgt";
 535         case Bop.CMPGE: return "bge";
 536         case Bop.CMPLE: return "ble";
 537         case Bop.CMPLT: return "blt";
 538         default: throw new Error("Illegal compare operation");
 539         }
 540     }
 541 
 542     /** simple tuple class to wrap some bits of info about the call prologue */
 543     private class CallState {
 544       /** set of registers used by parameters to the call. */
 545       final List callUses;
 546       CallState(List callUses) {
 547          this.callUses=callUses;
 548       }
 549     }
 550 
 551     /** Declare Void types for a0, a1, a2, a3, t0, LR in prep for a call. */
 552     private void declareCALL() {
 553        declare(a0, HClass.Void);
 554        declare(a1, HClass.Void);
 555        declare(a2, HClass.Void);
 556        declare(a3, HClass.Void);
 557        declare(t0, HClass.Void);
 558        declare(LR, HClass.Void);
 559     }
 560     private void declareCALLDefFull() {
 561        declare(v0, HClass.Void);
 562        declare(v1, HClass.Void);
 563        declare(a0, HClass.Void);
 564        declare(a1, HClass.Void);
 565        declare(a2, HClass.Void);
 566        declare(a3, HClass.Void);
 567        declare(t0, HClass.Void);
 568        declare(t1, HClass.Void);
 569        declare(t2, HClass.Void);
 570        declare(t3, HClass.Void);
 571        declare(t4, HClass.Void);
 572        declare(t5, HClass.Void);
 573        declare(t6, HClass.Void);
 574        declare(t7, HClass.Void);
 575        declare(t8, HClass.Void);
 576        declare(t9, HClass.Void);
 577        declare(GP, HClass.Void);
 578        declare(LR, HClass.Void);
 579     }
 580     private void declareCALLDefBuiltin() {
 581        declare(v0, HClass.Void);
 582        declare(v1, HClass.Void);
 583        declare(a0, HClass.Void);
 584        declare(a1, HClass.Void);
 585        declare(a2, HClass.Void);
 586        declare(a3, HClass.Void);
 587        declare(t0, HClass.Void);
 588        declare(t1, HClass.Void);
 589        declare(t2, HClass.Void);
 590        declare(GP, HClass.Void);
 591        declare(LR, HClass.Void);
 592     }
 593     private void DoLLCall(HCodeElement root,
 594                           Temp i, Temp j, Temp k, String func_name) {
 595        declare( a3, HClass.Void );
 596        declare( a2, HClass.Void );
 597        declare( a1, HClass.Void );
 598        declare( a0, HClass.Void );
 599        // an emitMOVE is not legal with the l/h modifiers
 600        assert j instanceof TwoWordTemp;
 601        assert k instanceof TwoWordTemp;
 602        emit2( root, "move `d0, `s0h\n"
 603               + "move `d1, `s0l", new Temp[]{a0, a1}, new Temp[] {j});
 604        emitRegAllocUse( root, j );
 605        emit2( root, "move `d0, `s0h\n"
 606               + "move `d1, `s0l", new Temp[]{a2, a3}, new Temp[] {k});
 607        emitRegAllocUse( root, k );
 608        declareCALLDefFull();
 609        emit2(root, "jal "+nameMap.c_function_name(func_name),
 610              call_def_full, call_use);
 611        assert i instanceof TwoWordTemp;
 612        emitRegAllocDef(root, i);
 613        emit( root, "move `d0h, `s0\n"
 614              + "move `d0l, `s1", i, v0, v1 ); 
 615        emitRegAllocUse( root, v0);
 616        emitRegAllocUse( root, v1);
 617     }
 618     /** Source for long long arithmetic routines is in Flex_MIPS.S */
 619     private void DoLLShiftCall(HCodeElement root,
 620                                Temp i, Temp j, Temp k, String func_name) {
 621        declare( a2, HClass.Int );
 622        declare( a1, HClass.Void );
 623        declare( a0, HClass.Void );
 624        declareCALLDefBuiltin();
 625        // an emitMOVE is not legal with the l/h modifiers
 626        assert j instanceof TwoWordTemp;
 627        emit2( root, "move `d0, `s0h\n"
 628               + "move `d1, `s0l", new Temp[]{a0, a1}, new Temp[] {j});
 629        emitRegAllocUse( root, j );
 630        assert (k instanceof TwoWordTemp) == false;
 631        emitMOVE( root, "move `d0, `s0", a2, k );
 632        declareCALLDefFull();
 633        emit2(root, "jal "+nameMap.c_function_name(func_name),
 634              // uses & stomps on these registers:
 635              call_def_full, call_use);
 636        assert i instanceof TwoWordTemp;
 637        emitRegAllocDef(root, i);
 638        emit( root, "move `d0h, `s0\n"
 639              + "move `d0l, `s1", i, v0, v1 ); 
 640        emitRegAllocUse( root, v0);
 641        emitRegAllocUse( root, v1);
 642     }
 643     /** For now all float and double operations are in software.  Each
 644      routine has an assembly jacket function which now calls a C
 645      function.  Eventually, we can implement them in assembly using
 646      fewer registers if we want*/
 647     private void DoFCall(HCodeElement root,
 648                          Temp i, Temp j, Temp k, String func_name) {
 649        /* call auxillary fp routines */
 650        declare(a0, HClass.Float);
 651        declare(a1, HClass.Float);
 652        emitMOVE( root, "move `d0, `s0", a1, k );
 653        emitMOVE( root, "move `d0, `s0", a0, j );
 654        declareCALLDefFull();
 655        emit2( root, "jal "+nameMap.c_function_name(func_name),
 656               call_def_full, new Temp[] {a0, a1, SP, FP} );
 657        emitMOVE( root, "move `d0, `s0", i, v0 );
 658     }
 659     private void DoFCall(HCodeElement root,
 660                          Temp i, Temp j, String func_name) {
 661        /* call auxillary fp routines */
 662        declare(a0, HClass.Float);
 663        emitMOVE( root, "move `d0, `s0", a0, j );
 664        declareCALLDefFull();
 665        emit2( root, "jal "+nameMap.c_function_name(func_name),
 666               call_def_full, new Temp[] {a0, a1, SP, FP} );
 667        emitMOVE( root, "move `d0, `s0", i, v0 );
 668     }
 669     private void DoDCall(HCodeElement root,
 670                          Temp i, Temp j, Temp k, String func_name) {
 671        /* call auxillary fp routines */
 672        declare( a3, HClass.Void );
 673        declare( a2, HClass.Void );
 674        declare( a1, HClass.Void );
 675        declare( a0, HClass.Void );
 676        // not certain an emitMOVE is legal with the l/h modifiers
 677        assert j instanceof TwoWordTemp;
 678        assert k instanceof TwoWordTemp;
 679        emit2( root, "move `d0, `s0h\n"
 680               + "move `d1, `s0l", new Temp[]{a0, a1}, new Temp[] {j});
 681        emitRegAllocUse( root, j );
 682        emit2( root, "move `d0, `s0h\n"
 683               + "move `d1, `s0l", new Temp[]{a2, a3}, new Temp[] {k});
 684        emitRegAllocUse( root, k );
 685        declareCALLDefFull();
 686        emit2(root, "jal "+nameMap.c_function_name(func_name),
 687              // uses & stomps on these registers:
 688              call_def_full, call_use);
 689        if(i instanceof TwoWordTemp) {
 690           emitRegAllocDef(root, i);
 691           emit( root, "move `d0h, `s0\n"
 692                 + "move `d0l, `s1", i, v0, v1 ); 
 693           emitRegAllocUse( root, v0);
 694           emitRegAllocUse( root, v1);
 695        } else {
 696           emitMOVE( root, "move `d0, `s0", i, v0 );
 697        }
 698     }
 699     private void DoDCall(HCodeElement root,
 700                          Temp i, Temp j, String func_name) {
 701        /* call auxillary fp routines */
 702        declare( a0, HClass.Void );
 703        if(j instanceof TwoWordTemp) {
 704           declare( a1, HClass.Void );
 705           // not certain an emitMOVE is legal with the l/h modifiers
 706           emit2( root, "move `d0, `s0h\n"
 707                  + "move `d1, `s0l", new Temp[]{a0, a1}, new Temp[] {j});
 708           emitRegAllocUse( root, j );
 709        } else {
 710           emitMOVE( root, "move `d0, `s0", a0, j );
 711        }
 712        declareCALLDefFull();
 713        emit2(root, "jal "+nameMap.c_function_name(func_name),
 714              // uses & stomps on these registers:
 715              call_def_full, call_use);
 716        if(i instanceof TwoWordTemp) {
 717           emitRegAllocDef(root, i);
 718           emit( root, "move `d0h, `s0\n"
 719                 + "move `d0l, `s1", i, v0, v1 ); 
 720           emitRegAllocUse( root, v0);
 721           emitRegAllocUse( root, v1);
 722        } else {
 723           emitMOVE( root, "move `d0, `s0", i, v0 );
 724        }
 725     }
 726 
 727     private boolean isDoubleWord(Typed ty) {
 728        switch (ty.type()) {
 729        case Type.LONG: case Type.DOUBLE: return true;
 730        default: return false;
 731        }
 732     }
 733     /** Helper for setting up registers/memory with the strongARM standard
 734      *  calling convention.  Returns the stack offset necessary,
 735      *  along with a set of registers used by the parameters. */
 736     private CallState emitCallPrologue(INVOCATION ROOT, 
 737                                        TempList tlist,
 738                                        TreeDerivation td) {
 739        ExpList elist = ROOT.getArgs();
 740        List callUses = new ArrayList(call_use.length);
 741 
 742        // add all used registers to callUses list.
 743        for (int i=0; i<call_use.length; ++i) {
 744           callUses.add(call_use[i]);
 745        }
 746 
 747        int index = 0;
 748        for (TempList tl = tlist; tl != null; tl=tl.tail,
 749                elist=elist.tail, ++index) {
 750           switch(stack.argWhere(ROOT, index)) {
 751           case StackInfo.REGISTER:
 752              if(isDoubleWord(elist.head)) {
 753                 Temp reg1 = stack.argReg(ROOT, index); 
 754                 Temp reg2 = stack.argSecondReg( ROOT, index); 
 755                 declare( reg1, HClass.Void);
 756                 declare( reg2, HClass.Void);
 757                 assert tl.head instanceof TwoWordTemp;
 758                 emit2( ROOT, "move `d0, `s0h\n"
 759                        + "move `d1, `s0l", 
 760                        new Temp[]{reg1, reg2}, new Temp[] {tl.head});
 761                 emitRegAllocUse( ROOT, tl.head );
 762              } else {
 763                 Temp reg = stack.argReg( ROOT, index); 
 764                 declare( reg, td, elist.head );
 765                 emitMOVE( ROOT, "move `d0, `s0", reg, tl.head );
 766              }
 767           break;
 768           case StackInfo.STACK:
 769              if(isDoubleWord(elist.head)) {
 770                 declare (SP, HClass.Void);
 771                 assert tl.head instanceof TwoWordTemp;
 772                 emit(new InstrMEM( instrFactory, ROOT,
 773                                    "sw `s0h, " 
 774                                    + stack.argOffset(ROOT, index) 
 775                                    + "(`s1)",
 776                                    null,
 777                                    new Temp[]{ tl.head, SP })); 
 778                 emit(new InstrMEM( instrFactory, ROOT,
 779                                    "sw `s0l, " 
 780                                    + stack.argSecondOffset(ROOT, index) 
 781                                    + "(`s1)",
 782                                    null,
 783                                    new Temp[]{ tl.head, SP })); 
 784              } else {
 785                 declare( SP, HClass.Void );
 786                 emit(new InstrMEM(
 787                    instrFactory, ROOT,
 788                    "sw `s0, " + stack.argOffset(ROOT, index)
 789                    + "(`s1)",
 790                    null,
 791                    new Temp[]{ tl.head, SP }));
 792              }
 793              break;
 794           case StackInfo.REGSTACKSPLIT:
 795              assert tl.head instanceof TwoWordTemp;
 796              // gcc and cc (mipspro) on mips don't do this
 797              assert false;
 798              break;
 799           default:
 800              assert false;
 801           }
 802        }
 803 
 804        declareCALL();
 805        if (ROOT.getRetval()!=null) declare( v0, td, ROOT.getRetval() );
 806        return new CallState(callUses);
 807     }
 808     /** Make a handler stub. */
 809     private void emitHandlerStub(INVOCATION ROOT, Temp retex, Label handler) {
 810        declare( retex, frame.getLinker().forName("java.lang.Throwable"));
 811        emitMOVE ( ROOT, "move `d0, `s0", retex, v0 );
 812        emitJUMP ( ROOT, "b "+handler+" # handler stub", handler);
 813        // I don't think we need this use/def info because all temps
 814        // are available at this point since we threw in the current
 815        // frame 
 816        //emit( ROOT, "b "+handler+" # handler stub",
 817        //      call_def_builtin, // clobbers
 818        //     call_use, 
 819        //     new Label[] { handler} );
 820     }
 821 /** Emit a fixup table entry */
 822     private void emitCallFixup(INVOCATION ROOT, Label retaddr, Label handler) {
 823       // this '1f' and '1:' business is taking advantage of a GNU
 824       // Assembly feature to avoid polluting the global name space with
 825       // local labels
 826       // these may need to be included in the previous instr to preserve
 827       // ordering semantics, but for now this way they indent properly
 828        emitDIRECTIVE( ROOT, !is_elf?".rdata ": (mipspro_assem ? ".data\n.section .flex.fixup,1, 3, 4, 16" : ".data\n.section .flex.fixup"));
 829       emitDIRECTIVE( ROOT, "\t.word "+retaddr+", "+handler+" # (retaddr, handler)");
 830       emitDIRECTIVE( ROOT, !is_elf?".text": (mipspro_assem ? ".text\n.section .flex.code,1, 7, 4, 16" : ".text\n.section .flex.code"));
 831     }
 832     /** Finish up a CALL or NATIVECALL. */
 833 
 834 
 835 
 836     private void emitCallEpilogue(INVOCATION ROOT, boolean isNative,
 837                                   Temp retval, HClass type, 
 838                                   CallState cs) {
 839        if (ROOT.getRetval()==null) {
 840           // this is a void method.  don't bother to emit move.
 841        } else if (isNative && (!soft_float) &&
 842                   ROOT.getRetval().type()==Type.FLOAT) {
 843           // float retval passed in float registers.
 844           declare(retval, type); declare ( SP, HClass.Void );
 845           //emitMOVE( ROOT, "move `d0, `s0", retval, v0 );
 846           emit( ROOT, "swc1 $f0, 0($sp)", null, SP);
 847           emit2( ROOT, "lw   `d0, 0(`s0)", 
 848                  new Temp[]{retval,SP},new Temp[]{SP});
 849           //emit2(ROOT, "lw `d0, 4($sp)",new Temp[]{retval,SP},new Temp[]{SP});
 850        } else if (isNative && (!soft_float) &&
 851                   ROOT.getRetval().type()==Type.DOUBLE) {
 852           // double retval passed in float registers.
 853           declare(retval, type); declare ( SP, HClass.Void );
 854           assert retval instanceof TwoWordTemp;
 855           //emit( ROOT, "move `d0h, `s0", retval, v0 );
 856           // emit( ROOT, "move `d0l, `s0", retval, v1 );
 857           // sdc1 is mips2
 858           emit( ROOT, "sdc1 $f0, 0($sp)", null, SP);
 859           emitRegAllocDef(ROOT, retval);
 860           emit(ROOT, "lw `d0l, 4($sp)\n"
 861                + "lw `d0h, 0($sp)", retval, SP);
 862              emitRegAllocUse( ROOT, SP ); // FSK: (for consistency)
 863        } else if (ROOT.getRetval().isDoubleWord()) {
 864           // not certain an emitMOVE is legal with the l/h modifiers
 865           declare(retval, type);
 866           assert retval instanceof TwoWordTemp;
 867           emitRegAllocDef(ROOT, retval);
 868           emit( ROOT, "move `d0h, `s0\n"
 869                 + "move `d0l, `s1", retval, v0, v1 ); 
 870           emitRegAllocUse( ROOT, v0);
 871           emitRegAllocUse( ROOT, v1);
 872        } else {
 873           declare(retval, type);
 874           emitMOVE( ROOT, "move `d0, `s0", retval, v0 );
 875        }  
 876     }
 877 
 878     /** remove nulls from array */
 879     private Instr[] compactArray(Instr[] instrs) {
 880        ArrayList inl = new ArrayList(instrs.length);
 881        for(int i = 0; i < instrs.length; ++i) {
 882           if(instrs[i] != null)
 883              inl.add(instrs[i]);
 884        }
 885        return (Instr[])inl.toArray();
 886     }
 887     private void LayoutInstr(Instr anchor, Instr[] instrs) {
 888        if(instrs.length == 0) return;
 889        instrs[0].layout(anchor.getPrev(), anchor);
 890        for(int i = 1; i < instrs.length; ++i) {
 891           instrs[i].layout(instrs[i-1], anchor);
 892        }
 893     }
 894     // make a string "safe". This is made necessary by obfuscators.
 895     private static String safe(String s) {
 896         char[] ca = s.toCharArray();
 897         for (int i=0; i<ca.length; i++)
 898             if (Character.isISOControl(ca[i])) ca[i]='#';
 899         return new String(ca);
 900     }
 901 
 902 
 903     // Mandated by CodeGen generic class: perform entry/exit
 904     public Instr procFixup(HMethod hm, Instr instr,
 905                            int stackspace, Set usedRegisters) {
 906        InstrFactory inf = instrFactory; // convenient abbreviation.
 907        Label methodlabel = nameMap.label(hm);
 908 
 909        // Really we should be passed a SortedSet, but since we aren't,
 910        // we will make our own
 911        Temp[] usedRegArray =
 912           (Temp[]) usedRegisters.toArray(new Temp[usedRegisters.size()]);
 913        ArrayList usedRegArrList = new ArrayList(usedRegisters.size());
 914        for(int i = 0; i < usedRegisters.size(); ++i) {
 915           usedRegArrList.add(usedRegArray[i]);
 916        }
 917        Collections.sort(usedRegArrList, regComp);
 918        
 919        stack.regAllocUsedRegs(usedRegArrList);
 920        // This can include space for callee saved registers if such
 921        // temps need to be spilled and restored.  Using local reg
 922        // alloc, this happens depressingly often 
 923        stack.regAllocLocalWords(stackspace);
 924        int nregs = stack.calleeSaveTotal();
 925 
 926        //  Signifies a tag unchecked load or store if we have them.
 927        String ntag = enable_daregs ? "da" : (yellow_pekoe ? ".u" : "");
 928        String tag = enable_daregs ? "lda" : "";
 929        String danum = enable_daregs ? ", 0" : "";
 930        // find method entry/exit stubs
 931        Instr last=instr;
 932 
 933        for (Instr il = instr; il!=null; il=il.getNext()) {
 934           if (il instanceof InstrENTRY) { // entry stub.
 935              Instr[] entry_instr;
 936              entry_instr = new Instr[10];
 937              int en = 0;
 938              entry_instr[en++] = new InstrDIRECTIVE(inf, il, ".align 2");
 939              entry_instr[en++] = 
 940                 new InstrDIRECTIVE(inf, il, ".globl " + methodlabel.name);
 941              entry_instr[en++] = 
 942                 new InstrDIRECTIVE(inf, il, ".type " + methodlabel.name
 943                                    + ",@function");
 944              entry_instr[en++] = 
 945                 new InstrDIRECTIVE(inf, il, ".ent " +
 946                                    methodlabel.name+",#function");
 947              entry_instr[en++] = 
 948                 new InstrLABEL(inf, il, methodlabel.name+":", methodlabel);
 949              entry_instr[en++] = 
 950                 new InstrDIRECTIVE(inf, il, ".frame $sp," +
 951                                    stack.frameSize() + ", $31");
 952              entry_instr[en++] = 
 953                 new Instr(inf, il,"subu $sp, "+ stack.frameSize() 
 954                           + "\t##RR_DO_NOT_ANNOTATE",
 955                           new Temp[] {SP}, new Temp[] {SP});
 956              entry_instr[en++] = 
 957                 new Instr(inf, il,"sw" + tag + " $31, " + stack.getRAOffset() 
 958                           +"($sp)" + danum , 
 959                           null, new Temp[] { LR, SP });
 960              entry_instr[en++] = 
 961                 new Instr(inf, il, "sw" + ntag + " $30, " + stack.getFPOffset() 
 962                           +"($sp)" + danum ,  
 963                           null, new Temp[] { FP, SP });
 964              entry_instr[en++] = 
 965                 new Instr(inf, il, "addu $30, $sp, "+ stack.frameSize() + "\t##RR_DO_NOT_ANNOTATE",
 966                           new Temp[]{FP}, new Temp[]{SP});
 967              assert en == 10;
 968              ////// Now create instrs to save non-trivial callee saved regs
 969              Instr[] callee_save = new Instr [nregs];
 970              if(nregs > 0) {
 971                 // make list of instructions saving callee-save registers we
 972                 // gotta save.
 973                 int j = 0;
 974                 for (int i=0; i < stack.calleeSaveTotal(); i++) {
 975                    String usuffix = ntag;
 976                    if(i!= 0 && (i % 6 == 0)) {
 977                       usuffix = tag;
 978                    }
 979                    callee_save[j++] = 
 980                       new Instr(inf, il, "sw" + usuffix + " "
 981                                 + stack.calleeReg(i) + ", "
 982                                 + stack.calleeSaveOffset(i)
 983                                 + "($sp)" + danum + "        # callee save", 
 984                                 null, new Temp[]{stack.calleeReg(i),SP});
 985                 }
 986              }
 987              /// Layout function entry
 988              LayoutInstr(il, entry_instr);
 989              if(nregs > 0) {
 990                 assert nregs == callee_save.length;
 991                 // This puts all of the callee saving before the
 992                 // creation of the frame pointer which is the last
 993                 // instruction in entry_isntr.
 994                 LayoutInstr(entry_instr[entry_instr.length-1], callee_save);
 995              }
 996              // fixup root if necessary
 997              if (il==instr) instr = entry_instr[entry_instr.length - 1];
 998              // if (stackspace==0) in7.remove(); // optimize
 999              il.remove(); il = entry_instr[entry_instr.length - 1];
1000 
1001           }
1002           if (il instanceof InstrEXIT) { // exit stub
1003              Instr[] callee_restore = new Instr [nregs];
1004              if(stack.calleeSaveTotal() > 0) {
1005                 // restore the regs we saved on entry
1006                 int j = 0;
1007                 for (int i = nregs - 1; i >= 0; --i) {
1008                    String usuffix = ntag;
1009                    if(j % 8 == 0) {
1010                       usuffix = tag;
1011                    }
1012                    callee_restore[j++] = 
1013                       new Instr(inf, il, "lw" + usuffix + " "
1014                                 + stack.calleeReg(i) + ", "
1015                                 + stack.calleeSaveOffset(i) 
1016                                 + "($sp)" + danum + "        # callee restore", 
1017                                 new Temp[]{stack.calleeReg(i)}, 
1018                                 new Temp[]{SP});
1019                 }
1020              }
1021              String ralw = "";
1022              Instr[] exit_instr;
1023              int en = 0;
1024              if(enable_daregs) {
1025                 exit_instr = new Instr[5];
1026              } else {
1027                 exit_instr = new Instr[4];
1028              }
1029              switch(nregs % 8) {
1030              case 0:
1031                 exit_instr[en++] = new Instr(inf, il, 
1032                                              "lw" + tag + " $30, " 
1033                                              + stack.getFPOffset() 
1034                                              + "($sp)" + danum,
1035                                              new Temp[] {FP}, new Temp[] {SP});
1036                 ralw = "lw" + ntag;
1037                 break;
1038              case 7:
1039                 exit_instr[en++] = new Instr(inf, il, 
1040                                              "lw" + ntag + " $30, " 
1041                                              + stack.getFPOffset() 
1042                                              + "($sp)" + danum,
1043                                              new Temp[] {FP}, new Temp[] {SP});
1044                 ralw = "lw" + tag;
1045                 break;
1046              default:
1047                 exit_instr[en++] = new Instr(inf, il, 
1048                                              "lw" + ntag + " $30, " 
1049                                              + stack.getFPOffset() 
1050                                              + "($sp)" + danum ,
1051                                              new Temp[] {FP}, new Temp[] {SP});
1052                 ralw = "lw" + ntag;
1053                 break;
1054              }
1055              exit_instr[en++] = new Instr(inf, il, 
1056                                           ralw + " $31, " 
1057                                           + stack.getRAOffset() + "($sp)" 
1058                                           + danum,
1059                                           new Temp[] {LR}, new Temp[] {SP});
1060              if(enable_daregs)
1061                 exit_instr[en++] = new Instr(inf, il, "ph 3, " +
1062                                              makeDAFlushBitmask());
1063              exit_instr[en++] = new Instr(inf, il, "addu $sp, " 
1064                                           + stack.frameSize() 
1065                                           + "\t##RR_DO_NOT_ANNOTATE",
1066                                           new Temp[] {SP}, new Temp[] {SP});
1067              exit_instr[en++] = new Instr(inf, il, "j  $31  # return",
1068                                           null, new Temp[]{LR});
1069              if(enable_daregs) {
1070                 assert en == 5;
1071              } else {
1072                 assert en == 4;
1073              }
1074              if(nregs > 0) {
1075                 LayoutInstr(il, callee_restore);
1076              }
1077              LayoutInstr(il, exit_instr);
1078              il.remove(); 
1079              il = (Instr)exit_instr[exit_instr.length-1];
1080           }
1081           last=il;
1082        }
1083        // add a size directive to the end of the function to let gdb
1084        // know how long it is.
1085        if (last!=null) { // best be safe.
1086           // Instructions show up in reverse order
1087           Instr in1 = new InstrDIRECTIVE(inf, last, "\t.end " +
1088                                          methodlabel.name);
1089           // I can't find a way to make the MIPSpro assembler
1090           // understand this.  It complains about the symbols not
1091           // having aboslute value
1092           Instr in2 = new InstrDIRECTIVE(inf, last, "\t.size " +
1093                                          methodlabel.name + ", . - " +
1094                                          methodlabel.name);
1095           in1.layout(last, last.getNext());
1096           assert mipspro_assem == false;
1097           in2.layout(last, in1);
1098           last=in2;
1099        }
1100        // stabs debugging information:
1101        if (stabsDebugging && !hm.getDeclaringClass().isArray()) {
1102           int lineno=-1;
1103           for (Instr il = instr; il!=null; il=il.getNext())
1104              // XXXX vpekoe-as does not support .stabd
1105              if (false && il.getLineNumber()!=lineno) {
1106                 lineno = il.getLineNumber();
1107                 Instr in1 = new InstrDIRECTIVE(inf, il, // line number
1108                                                "\t.stabd 68,0,"+lineno);
1109                 in1.layout(il.getPrev(), il);
1110                 if (il==instr) instr=in1;
1111              }
1112           Instr in1 = new InstrDIRECTIVE(inf, instr, // source path
1113                                          "\t.stabs \""+
1114                                          hm.getDeclaringClass().getPackage()
1115                                          .replace('.','/')+"/"+
1116                                          "\",100,0,0,"+methodlabel.name);
1117           Instr in2 = new InstrDIRECTIVE(inf, instr, // source file name
1118                                          "\t.stabs \""+
1119                                          safe(instr.getSourceFile())+
1120                                          "\",100,0,0,"+methodlabel.name);
1121           Instr in3 = new InstrDIRECTIVE(inf, instr, // define void type
1122                                          "\t.stabs \"void:t19=19\",128,0,0,0"
1123              );
1124           // F1 instead of F19 looks like the vpekoe-gcc output
1125           Instr in4 = new InstrDIRECTIVE(inf, instr, // mark as function
1126                                          "\t.stabs \""+
1127                                          methodlabel.name.substring(1)+":F1"
1128                                          +"\",36,0,"+(nregs*4)+","+
1129                                          methodlabel.name);
1130           in1.layout(instr.getPrev(), instr);
1131           in2.layout(in1, instr);
1132           in3.layout(in2, instr);
1133           instr = in1;
1134           in4.layout(last, last.getNext());
1135           last = in4;
1136        }
1137        return instr;
1138     }
1139 
1140     public StackInfo getStackInfo() {
1141       return stack;
1142     }
1143     // now define our little InstrENTRY and InstrEXIT sub-types.
1144     private class InstrENTRY extends Instr {
1145        public InstrENTRY(InstrFactory inf, HCodeElement src) {
1146           // defines SP, FP providing reaching defs for
1147           // InstrEXIT uses.
1148           super(inf, src, "# --method entry point--",
1149                 new Temp[] { SP, FP }, null);
1150        }
1151     }
1152     private class InstrEXIT extends Instr {
1153        public InstrEXIT(InstrFactory inf, HCodeElement hce) {
1154           // uses SP, FP, making them live in whole
1155           // procedure (so register allocator doesn't stomp
1156           // on them!)
1157           super(inf, hce, "# --method exit point--", null, 
1158                 new Temp[]{ SP, FP }, false, null);
1159        }
1160     }
1161 
1162 
1163 private static boolean __CommExp__isCommutative(int op) {
1164         switch(op) {
1165         case harpoon.IR.Tree.Bop.CMPGT:
1166         case harpoon.IR.Tree.Bop.CMPGE:
1167         case harpoon.IR.Tree.Bop.CMPLE:
1168         case harpoon.IR.Tree.Bop.CMPLT:  return true; 
1169         default: return harpoon.IR.Tree.Bop.isCommutative(op);
1170         }
1171 }
1172 private static int __CommExp__swapCmpOp(int op) {
1173         switch(op) {
1174         case harpoon.IR.Tree.Bop.CMPGT:return harpoon.IR.Tree.Bop.CMPLT;
1175         case harpoon.IR.Tree.Bop.CMPGE:return harpoon.IR.Tree.Bop.CMPLE;
1176         case harpoon.IR.Tree.Bop.CMPLE:return harpoon.IR.Tree.Bop.CMPGE;
1177         case harpoon.IR.Tree.Bop.CMPLT:return harpoon.IR.Tree.Bop.CMPGT;
1178         default: return op;
1179         }
1180 }
1181 
1182 
1183         /** Generates assembly code from a <code>harpoon.IR.Tree.Code</code>.
1184             <BR> <B>modifies:</B> <code>this</code>
1185             <BR> <B>effects:</B>
1186                  Scans <code>tree</code> to find a tiling of 
1187                  Instruction Patterns, calling auxillary methods
1188                  and data structures as defined in the .spec file.
1189                  Generates an associated <code>Derivation</code>
1190                  object as the second element of the returned
1191                  <code>List</code>.
1192             @param tree Set of abstract <code>Tree</code> instructions 
1193                         that form the body of the procedure being compiled.
1194         */
1195         public final java.util.List cgg_genCode(final harpoon.IR.Tree.Code code, final harpoon.IR.Assem.InstrFactory inf) {
1196         _methodPrologue_(inf);
1197 
1198         // *** METHOD PROLOGUE ***
1199         this.instrFactory = inf; // XXX this should probably move to superclass
1200     // Create a stack object and let it know about all calls made by
1201     // this method.  Shouldn't this be in the constructor?
1202     this.stack = new StackInfo(regfile);
1203     collectCallInfo(code);
1204 
1205         final class CggVisitor extends harpoon.IR.Tree.TreeVisitor {
1206                  harpoon.Temp.Temp munchExp(harpoon.IR.Tree.Exp expArg) {
1207                         boolean _matched_ = false;
1208                         clearDecl(); // reset temp type mappings
1209                                  /* BINOP<i,p>(ADD,j,UNOP<i,p>(NEG,CONST<i>(c))) */
1210                         if (true
1211                                 // check expression type
1212                                 && expArg instanceof harpoon.IR.Tree.BINOP
1213                                 // check opcode
1214                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
1215                                 // check operand types
1216                                 && ( 
1217                                         expArg.type() == Type.POINTER ||
1218                                 (       expArg.type() == Type.INT && !
1219                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1220                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1221                                         false )
1222                                 // end check operand types
1223                                         // check left child
1224                                         // no check needed for ExpId children
1225                                         // check right child
1226                                         // check expression type
1227                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.UNOP 
1228                                         // check opcode
1229                                         && ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).op == harpoon.IR.Tree.Uop.NEG
1230                                         // check operand types
1231                                         && ( 
1232                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1233                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1234                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1235                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1236                                                 false )
1237                                         // end check operand types
1238                                                 // check child
1239                                                 // check expression type
1240                                                 && ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand() instanceof harpoon.IR.Tree.CONST 
1241                                                 // check operand types
1242                                                 && ( 
1243                                                 (       ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand().type() == Type.INT && !
1244                                                  (((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand() instanceof harpoon.IR.Tree.PreciselyTyped &&
1245                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand()).isSmall())) ||
1246                                                         false )
1247                                                 // end check operand types
1248                         ){
1249                                                 Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand()).value;
1250                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1251                                 _matched_ = true;
1252 
1253                                 if (_matched_) { // action code! degree: 3
1254                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1255 
1256 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1257 clearDecl();
1258 declare(i, code.getTreeDerivation(), ROOT);
1259 
1260    emitLineDebugInfo(ROOT);
1261     emit( ROOT, "subu `d0, `s0, "+c, i, j);
1262                         return i;
1263                         }
1264                         }
1265                                  /* MEM<i,f,p,u:8,u:16,s:8,s:16>(BINOP<p>(ADD,CONST<i,p>(c),j)) */
1266                         if (true
1267                                 // check expression type
1268                                 && expArg instanceof harpoon.IR.Tree.MEM 
1269                                 // check operand types
1270                                 && ( 
1271                                         expArg.type() == Type.FLOAT ||
1272                                         expArg.type() == Type.POINTER ||
1273                                 (       expArg.type() == Type.INT && !
1274                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1275                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1276                                         (((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall() && (
1277                                          ((harpoon.IR.Tree.PreciselyTyped)expArg).signed() ? (
1278                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==8 ||
1279                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==16 ||
1280                                           false) : (
1281                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==8 ||
1282                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==16 ||
1283                                           false) ) ) ||
1284                                         false )
1285                                 // end check operand types
1286                                         // check child
1287                                         // check expression type
1288                                         && ((harpoon.IR.Tree.MEM)expArg).getExp() instanceof harpoon.IR.Tree.BINOP
1289                                         // check opcode
1290                                         && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).op == harpoon.IR.Tree.Bop.ADD
1291                                         // check operand types
1292                                         && ( 
1293                                                 ((harpoon.IR.Tree.MEM)expArg).getExp().type() == Type.POINTER ||
1294                                                 false )
1295                                         // end check operand types
1296                                                 // check left child
1297                                                 // check expression type
1298                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getLeft() instanceof harpoon.IR.Tree.CONST 
1299                                                 // check operand types
1300                                                 && ( 
1301                                                         ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getLeft().type() == Type.POINTER ||
1302                                                 (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getLeft().type() == Type.INT && !
1303                                                  (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getLeft() instanceof harpoon.IR.Tree.PreciselyTyped &&
1304                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getLeft()).isSmall())) ||
1305                                                         false )
1306                                                 // end check operand types
1307                                                 // check right child
1308                                                 // no check needed for ExpId children
1309                         ){
1310                                                 Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getLeft()).value;
1311                         harpoon.IR.Tree.MEM ROOT = (harpoon.IR.Tree.MEM) expArg;
1312                                 _matched_ = true;
1313 
1314                                 if (_matched_) { // action code! degree: 3
1315                                                 harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getRight()); 
1316 
1317 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1318 clearDecl();
1319 declare(i, code.getTreeDerivation(), ROOT);
1320 
1321    String suffix = GetLdSuffix(ROOT);
1322    String usuffix = getDAOpcodeSuffix(ROOT);
1323    emitLineDebugInfo(ROOT);
1324 
1325    emit(new InstrMEM(instrFactory, ROOT,
1326                      "l"+suffix+usuffix+" `d0, " + c + "(`s0)" + getDANum(ROOT),
1327                      new Temp[]{ i }, new Temp[]{ j }));
1328                         return i;
1329                         }
1330                         }
1331                                  /* MEM<i,f,p,u:8,u:16,s:8,s:16>(BINOP<p>(ADD,j,CONST<i,p>(c))) */
1332                         if (true
1333                                 // check expression type
1334                                 && expArg instanceof harpoon.IR.Tree.MEM 
1335                                 // check operand types
1336                                 && ( 
1337                                         expArg.type() == Type.FLOAT ||
1338                                         expArg.type() == Type.POINTER ||
1339                                 (       expArg.type() == Type.INT && !
1340                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1341                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1342                                         (((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall() && (
1343                                          ((harpoon.IR.Tree.PreciselyTyped)expArg).signed() ? (
1344                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==8 ||
1345                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==16 ||
1346                                           false) : (
1347                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==8 ||
1348                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==16 ||
1349                                           false) ) ) ||
1350                                         false )
1351                                 // end check operand types
1352                                         // check child
1353                                         // check expression type
1354                                         && ((harpoon.IR.Tree.MEM)expArg).getExp() instanceof harpoon.IR.Tree.BINOP
1355                                         // check opcode
1356                                         && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).op == harpoon.IR.Tree.Bop.ADD
1357                                         // check operand types
1358                                         && ( 
1359                                                 ((harpoon.IR.Tree.MEM)expArg).getExp().type() == Type.POINTER ||
1360                                                 false )
1361                                         // end check operand types
1362                                                 // check left child
1363                                                 // no check needed for ExpId children
1364                                                 // check right child
1365                                                 // check expression type
1366                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getRight() instanceof harpoon.IR.Tree.CONST 
1367                                                 // check operand types
1368                                                 && ( 
1369                                                         ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getRight().type() == Type.POINTER ||
1370                                                 (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getRight().type() == Type.INT && !
1371                                                  (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1372                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getRight()).isSmall())) ||
1373                                                         false )
1374                                                 // end check operand types
1375                         ){
1376                                                 Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getRight()).value;
1377                         harpoon.IR.Tree.MEM ROOT = (harpoon.IR.Tree.MEM) expArg;
1378                                 _matched_ = true;
1379 
1380                                 if (_matched_) { // action code! degree: 3
1381                                                 harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)expArg).getExp()).getLeft()); 
1382 
1383 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1384 clearDecl();
1385 declare(i, code.getTreeDerivation(), ROOT);
1386 
1387    String suffix = GetLdSuffix(ROOT);
1388    String usuffix = getDAOpcodeSuffix(ROOT);
1389    emitLineDebugInfo(ROOT);
1390 
1391    emit(new InstrMEM(instrFactory, ROOT,
1392                      "l"+suffix+usuffix+" `d0, " + c + "(`s0)" + getDANum(ROOT),
1393                      new Temp[]{ i }, new Temp[]{ j }));
1394                         return i;
1395                         }
1396                         }
1397                                  /* BINOP<i,p>(ADD,j,CONST<i,p>(c)) */
1398                         if (true
1399                                 // check expression type
1400                                 && expArg instanceof harpoon.IR.Tree.BINOP
1401                                 // check opcode
1402                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
1403                                 // check operand types
1404                                 && ( 
1405                                         expArg.type() == Type.POINTER ||
1406                                 (       expArg.type() == Type.INT && !
1407                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1408                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1409                                         false )
1410                                 // end check operand types
1411                                         // check left child
1412                                         // no check needed for ExpId children
1413                                         // check right child
1414                                         // check expression type
1415                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1416                                         // check operand types
1417                                         && ( 
1418                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1419                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1420                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1421                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1422                                                 false )
1423                                         // end check operand types
1424                         ){
1425                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1426                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1427                                 _matched_ = true;
1428 
1429                                 if (_matched_) { // action code! degree: 2
1430                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1431 
1432 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1433 clearDecl();
1434 declare(i, code.getTreeDerivation(), ROOT);
1435 
1436    emitLineDebugInfo(ROOT);
1437     emit( ROOT, "addu `d0, `s0, "+c, i, j);
1438                         return i;
1439                         }
1440                         }
1441                                  /* BINOP<i,p>(ADD,j,UNOP<i,p>(NEG,k)) */
1442                         if (true
1443                                 // check expression type
1444                                 && expArg instanceof harpoon.IR.Tree.BINOP
1445                                 // check opcode
1446                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
1447                                 // check operand types
1448                                 && ( 
1449                                         expArg.type() == Type.POINTER ||
1450                                 (       expArg.type() == Type.INT && !
1451                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1452                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1453                                         false )
1454                                 // end check operand types
1455                                         // check left child
1456                                         // no check needed for ExpId children
1457                                         // check right child
1458                                         // check expression type
1459                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.UNOP 
1460                                         // check opcode
1461                                         && ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).op == harpoon.IR.Tree.Uop.NEG
1462                                         // check operand types
1463                                         && ( 
1464                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1465                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1466                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1467                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1468                                                 false )
1469                                         // end check operand types
1470                                                 // check child
1471                                                 // no check needed for ExpId children
1472                         ){
1473                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1474                                 _matched_ = true;
1475 
1476                                 if (_matched_) { // action code! degree: 2
1477                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1478                                                 harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand()); 
1479 
1480 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1481 clearDecl();
1482 declare(i, code.getTreeDerivation(), ROOT);
1483 
1484    emitLineDebugInfo(ROOT);
1485     emit( ROOT, "subu `d0, `s0, `s1", i, j, k);
1486                         return i;
1487                         }
1488                         }
1489                                  /* BINOP<l>(ADD,j,UNOP<l>(NEG,k)) */
1490                         if (true
1491                                 // check expression type
1492                                 && expArg instanceof harpoon.IR.Tree.BINOP
1493                                 // check opcode
1494                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
1495                                 // check operand types
1496                                 && ( 
1497                                         expArg.type() == Type.LONG ||
1498                                         false )
1499                                 // end check operand types
1500                                         // check left child
1501                                         // no check needed for ExpId children
1502                                         // check right child
1503                                         // check expression type
1504                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.UNOP 
1505                                         // check opcode
1506                                         && ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).op == harpoon.IR.Tree.Uop.NEG
1507                                         // check operand types
1508                                         && ( 
1509                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.LONG ||
1510                                                 false )
1511                                         // end check operand types
1512                                                 // check child
1513                                                 // no check needed for ExpId children
1514                         ){
1515                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1516                                 _matched_ = true;
1517 
1518                                 if (_matched_) { // action code! degree: 2
1519                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1520                                                 harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand()); 
1521 
1522 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1523 clearDecl();
1524 declare(i, code.getTreeDerivation(), ROOT);
1525 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
1526         public int type() { return harpoon.IR.Tree.Type.INT; }
1527         public boolean isFloatingPoint() { return false; }
1528         public boolean isDoubleWord() { return false; }
1529 }, inf.tempFactory() );
1530 declare(extra, HClass.Int);
1531 
1532    emitLineDebugInfo(ROOT);
1533    emitRegAllocDef(ROOT, i);
1534    if(yellow_pekoe) {
1535    emit2( ROOT, 
1536           "subu `d0l, `s0l, `s1l\n"
1537           + "subu `d0h, `s0h, `s1h\n"
1538           + "sltu `d1, `s0l, `s1l\n"
1539           + "subu.l2 `d0h, `s2h, `s3",
1540           new Temp[]{i,extra}, new Temp[] {j, k, i, extra} );
1541    } else {
1542       emit2( ROOT, 
1543              "subu `d0l, `s0l, `s1l\n"
1544              + "subu `d0h, `s0h, `s1h\n"
1545              + "sltu `d1, `s0l, `s1l\n"
1546              + "subu `d0h, `s2h, `s3",
1547              new Temp[]{i,extra}, new Temp[] {j, k, i, extra} );
1548    }
1549    emitRegAllocUse(ROOT, j);
1550    emitRegAllocUse(ROOT, k);
1551                         return i;
1552                         }
1553                         }
1554                                  /* BINOP<f>(ADD,j,UNOP<f>(NEG,k)) */
1555                         if (true
1556                                 // check expression type
1557                                 && expArg instanceof harpoon.IR.Tree.BINOP
1558                                 // check opcode
1559                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
1560                                 // check operand types
1561                                 && ( 
1562                                         expArg.type() == Type.FLOAT ||
1563                                         false )
1564                                 // end check operand types
1565                                         // check left child
1566                                         // no check needed for ExpId children
1567                                         // check right child
1568                                         // check expression type
1569                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.UNOP 
1570                                         // check opcode
1571                                         && ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).op == harpoon.IR.Tree.Uop.NEG
1572                                         // check operand types
1573                                         && ( 
1574                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.FLOAT ||
1575                                                 false )
1576                                         // end check operand types
1577                                                 // check child
1578                                                 // no check needed for ExpId children
1579                         ){
1580                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1581                                 _matched_ = true;
1582 
1583                                 if (_matched_) { // action code! degree: 2
1584                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1585                                                 harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand()); 
1586 
1587 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1588 clearDecl();
1589 declare(i, code.getTreeDerivation(), ROOT);
1590 
1591    emitLineDebugInfo(ROOT);
1592    DoFCall(ROOT, i, j, k, "__subsf3");
1593                         return i;
1594                         }
1595                         }
1596                                  /* BINOP<d>(ADD,j,UNOP<d>(NEG,k)) */
1597                         if (true
1598                                 // check expression type
1599                                 && expArg instanceof harpoon.IR.Tree.BINOP
1600                                 // check opcode
1601                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
1602                                 // check operand types
1603                                 && ( 
1604                                         expArg.type() == Type.DOUBLE ||
1605                                         false )
1606                                 // end check operand types
1607                                         // check left child
1608                                         // no check needed for ExpId children
1609                                         // check right child
1610                                         // check expression type
1611                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.UNOP 
1612                                         // check opcode
1613                                         && ((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).op == harpoon.IR.Tree.Uop.NEG
1614                                         // check operand types
1615                                         && ( 
1616                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.DOUBLE ||
1617                                                 false )
1618                                         // end check operand types
1619                                                 // check child
1620                                                 // no check needed for ExpId children
1621                         ){
1622                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1623                                 _matched_ = true;
1624 
1625                                 if (_matched_) { // action code! degree: 2
1626                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1627                                                 harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.UNOP)((harpoon.IR.Tree.BINOP)expArg).getRight()).getOperand()); 
1628 
1629 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1630 clearDecl();
1631 declare(i, code.getTreeDerivation(), ROOT);
1632 
1633    emitLineDebugInfo(ROOT);
1634    DoDCall(ROOT, i, j, k, "__subdf3");
1635                         return i;
1636                         }
1637                         }
1638                                  /* BINOP<i,p>(MUL,j,CONST<i,p>(c)) */
1639                         if (true
1640                                 // check expression type
1641                                 && expArg instanceof harpoon.IR.Tree.BINOP
1642                                 // check opcode
1643                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.MUL
1644                                 // check operand types
1645                                 && ( 
1646                                         expArg.type() == Type.POINTER ||
1647                                 (       expArg.type() == Type.INT && !
1648                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1649                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1650                                         false )
1651                                 // end check operand types
1652                                         // check left child
1653                                         // no check needed for ExpId children
1654                                         // check right child
1655                                         // check expression type
1656                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1657                                         // check operand types
1658                                         && ( 
1659                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1660                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1661                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1662                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1663                                                 false )
1664                                         // end check operand types
1665                         ){
1666                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1667                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1668                                 _matched_ = true;
1669 
1670                                 if (_matched_) { // action code! degree: 2
1671                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1672 
1673 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1674 clearDecl();
1675 declare(i, code.getTreeDerivation(), ROOT);
1676 
1677    emitLineDebugInfo(ROOT);
1678     emit( ROOT, "mul `d0, `s0, "+c, i, j );
1679                         return i;
1680                         }
1681                         }
1682                                  /* BINOP<i,p>(DIV,j,CONST<i,p>(c)) */
1683                         if (true
1684                                 // check expression type
1685                                 && expArg instanceof harpoon.IR.Tree.BINOP
1686                                 // check opcode
1687                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.DIV
1688                                 // check operand types
1689                                 && ( 
1690                                         expArg.type() == Type.POINTER ||
1691                                 (       expArg.type() == Type.INT && !
1692                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1693                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1694                                         false )
1695                                 // end check operand types
1696                                         // check left child
1697                                         // no check needed for ExpId children
1698                                         // check right child
1699                                         // check expression type
1700                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1701                                         // check operand types
1702                                         && ( 
1703                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1704                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1705                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1706                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1707                                                 false )
1708                                         // end check operand types
1709                         ){
1710                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1711                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1712                                 _matched_ = true;
1713 
1714                                 if (_matched_) { // action code! degree: 2
1715                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1716 
1717 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1718 clearDecl();
1719 declare(i, code.getTreeDerivation(), ROOT);
1720 
1721    emitLineDebugInfo(ROOT);
1722    emit( ROOT, "div `d0, `s0, "+c, i, j );
1723                         return i;
1724                         }
1725                         }
1726                                  /* BINOP<i>(REM,j,CONST<i,p>(c)) */
1727                         if (true
1728                                 // check expression type
1729                                 && expArg instanceof harpoon.IR.Tree.BINOP
1730                                 // check opcode
1731                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.REM
1732                                 // check operand types
1733                                 && ( 
1734                                 (       expArg.type() == Type.INT && !
1735                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1736                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1737                                         false )
1738                                 // end check operand types
1739                                         // check left child
1740                                         // no check needed for ExpId children
1741                                         // check right child
1742                                         // check expression type
1743                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1744                                         // check operand types
1745                                         && ( 
1746                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1747                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1748                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1749                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1750                                                 false )
1751                                         // end check operand types
1752                         ){
1753                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1754                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1755                                 _matched_ = true;
1756 
1757                                 if (_matched_) { // action code! degree: 2
1758                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1759 
1760 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1761 clearDecl();
1762 declare(i, code.getTreeDerivation(), ROOT);
1763 
1764    emitLineDebugInfo(ROOT);
1765    emit( ROOT, "rem `d0, `s0, "+c, i, j );
1766                         return i;
1767                         }
1768                         }
1769                                  /* BINOP<i,p>(AND,j,CONST<i,p>(c)) */
1770                         if (true
1771                                 // check expression type
1772                                 && expArg instanceof harpoon.IR.Tree.BINOP
1773                                 // check opcode
1774                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.AND
1775                                 // check operand types
1776                                 && ( 
1777                                         expArg.type() == Type.POINTER ||
1778                                 (       expArg.type() == Type.INT && !
1779                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1780                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1781                                         false )
1782                                 // end check operand types
1783                                         // check left child
1784                                         // no check needed for ExpId children
1785                                         // check right child
1786                                         // check expression type
1787                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1788                                         // check operand types
1789                                         && ( 
1790                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1791                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1792                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1793                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1794                                                 false )
1795                                         // end check operand types
1796                         ){
1797                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1798                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1799                                 _matched_ = true;
1800 
1801                                 if (_matched_) { // action code! degree: 2
1802                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1803 
1804 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1805 clearDecl();
1806 declare(i, code.getTreeDerivation(), ROOT);
1807 
1808    emitLineDebugInfo(ROOT);
1809    emit( ROOT, "and `d0, `s0, "+c, i, j );
1810                         return i;
1811                         }
1812                         }
1813                                  /* BINOP<i,p>(OR,j,CONST<i,p>(c)) */
1814                         if (true
1815                                 // check expression type
1816                                 && expArg instanceof harpoon.IR.Tree.BINOP
1817                                 // check opcode
1818                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.OR
1819                                 // check operand types
1820                                 && ( 
1821                                         expArg.type() == Type.POINTER ||
1822                                 (       expArg.type() == Type.INT && !
1823                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1824                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1825                                         false )
1826                                 // end check operand types
1827                                         // check left child
1828                                         // no check needed for ExpId children
1829                                         // check right child
1830                                         // check expression type
1831                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1832                                         // check operand types
1833                                         && ( 
1834                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1835                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1836                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1837                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1838                                                 false )
1839                                         // end check operand types
1840                         ){
1841                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1842                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1843                                 _matched_ = true;
1844 
1845                                 if (_matched_) { // action code! degree: 2
1846                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1847 
1848 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1849 clearDecl();
1850 declare(i, code.getTreeDerivation(), ROOT);
1851 
1852    emitLineDebugInfo(ROOT);
1853    emit( ROOT, "or `d0, `s0, "+c, i, j );
1854                         return i;
1855                         }
1856                         }
1857                                  /* BINOP<i,p>(XOR,j,CONST<i,p>(c)) */
1858                         if (true
1859                                 // check expression type
1860                                 && expArg instanceof harpoon.IR.Tree.BINOP
1861                                 // check opcode
1862                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.XOR
1863                                 // check operand types
1864                                 && ( 
1865                                         expArg.type() == Type.POINTER ||
1866                                 (       expArg.type() == Type.INT && !
1867                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1868                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1869                                         false )
1870                                 // end check operand types
1871                                         // check left child
1872                                         // no check needed for ExpId children
1873                                         // check right child
1874                                         // check expression type
1875                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1876                                         // check operand types
1877                                         && ( 
1878                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1879                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1880                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1881                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1882                                                 false )
1883                                         // end check operand types
1884                         ){
1885                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1886                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1887                                 _matched_ = true;
1888 
1889                                 if (_matched_) { // action code! degree: 2
1890                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1891 
1892 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1893 clearDecl();
1894 declare(i, code.getTreeDerivation(), ROOT);
1895 
1896    emitLineDebugInfo(ROOT);
1897     emit( ROOT, "xor `d0, `s0, "+c, i, j );
1898                         return i;
1899                         }
1900                         }
1901                                  /* BINOP<i,p>(shiftop,j,CONST<i,l,f,d,p>(c)) */
1902                         if (true
1903                                 // check expression type
1904                                 && expArg instanceof harpoon.IR.Tree.BINOP
1905                                 // check operand types
1906                                 && ( 
1907                                         expArg.type() == Type.POINTER ||
1908                                 (       expArg.type() == Type.INT && !
1909                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1910                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1911                                         false )
1912                                 // end check operand types
1913                                         // check left child
1914                                         // no check needed for ExpId children
1915                                         // check right child
1916                                         // check expression type
1917                                         && ((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.CONST 
1918                                         // check operand types
1919                                         && ( 
1920                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.DOUBLE ||
1921                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.FLOAT ||
1922                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.LONG ||
1923                                                 ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.POINTER ||
1924                                         (       ((harpoon.IR.Tree.BINOP)expArg).getRight().type() == Type.INT && !
1925                                          (((harpoon.IR.Tree.BINOP)expArg).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
1926                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)expArg).getRight()).isSmall())) ||
1927                                                 false )
1928                                         // end check operand types
1929                         ){
1930                                 int shiftop = ((harpoon.IR.Tree.BINOP) expArg).op;
1931                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)expArg).getRight()).value;
1932                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
1933                                 _matched_ = true&& ( isShiftOp(shiftop) && is5BitShift(c) );
1934 
1935                                 if (_matched_) { // action code! degree: 2
1936                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
1937 
1938 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1939 clearDecl();
1940 declare(i, code.getTreeDerivation(), ROOT);
1941 
1942    emitLineDebugInfo(ROOT);
1943     emit( ROOT, shiftOp2Str(shiftop) + " `d0, `s0, "+c, i, j);
1944                         return i;
1945                         }
1946                         }
1947                                  /* MEM<i,f,p>(NAME(id)) */
1948                         if (true
1949                                 // check expression type
1950                                 && expArg instanceof harpoon.IR.Tree.MEM 
1951                                 // check operand types
1952                                 && ( 
1953                                         expArg.type() == Type.FLOAT ||
1954                                         expArg.type() == Type.POINTER ||
1955                                 (       expArg.type() == Type.INT && !
1956                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
1957                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
1958                                         false )
1959                                 // end check operand types
1960                                         // check child
1961                                         // check expression type
1962                                         && ((harpoon.IR.Tree.MEM)expArg).getExp() instanceof harpoon.IR.Tree.NAME 
1963                         ){
1964                                         harpoon.Temp.Label id = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MEM)expArg).getExp()).label;
1965                         harpoon.IR.Tree.MEM ROOT = (harpoon.IR.Tree.MEM) expArg;
1966                                 _matched_ = true;
1967 
1968                                 if (_matched_) { // action code! degree: 2
1969 
1970 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
1971 clearDecl();
1972 declare(i, code.getTreeDerivation(), ROOT);
1973 
1974    emitLineDebugInfo(ROOT);
1975    String usuffix = getDAOpcodeSuffix(ROOT);
1976    emit(new Instr( instrFactory, ROOT,
1977                    "lw" + usuffix + " `d0, " + id + getDANum(ROOT), 
1978                    new Temp[]{ i }, null ));
1979                         return i;
1980                         }
1981                         }
1982                                  /* MEM<l,d>(NAME(id)) */
1983                         if (true
1984                                 // check expression type
1985                                 && expArg instanceof harpoon.IR.Tree.MEM 
1986                                 // check operand types
1987                                 && ( 
1988                                         expArg.type() == Type.DOUBLE ||
1989                                         expArg.type() == Type.LONG ||
1990                                         false )
1991                                 // end check operand types
1992                                         // check child
1993                                         // check expression type
1994                                         && ((harpoon.IR.Tree.MEM)expArg).getExp() instanceof harpoon.IR.Tree.NAME 
1995                         ){
1996                                         harpoon.Temp.Label id = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MEM)expArg).getExp()).label;
1997                         harpoon.IR.Tree.MEM ROOT = (harpoon.IR.Tree.MEM) expArg;
1998                                 _matched_ = true;
1999 
2000                                 if (_matched_) { // action code! degree: 2
2001 
2002 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2003 clearDecl();
2004 declare(i, code.getTreeDerivation(), ROOT);
2005 
2006    emitLineDebugInfo(ROOT);
2007    String usuffix = getDAOpcodeSuffix(ROOT);
2008    emit(new InstrMEM( instrFactory, ROOT,
2009                       "lw" + usuffix + " `d0l, " + id + " +4" 
2010                       + getDANum(ROOT) + "\n"
2011                       + "lw" + usuffix + " `d0h, " + id + getDANum(ROOT),
2012                       new Temp[]{i}, new Temp[]{}));
2013                         return i;
2014                         }
2015                         }
2016                                  /* BINOP<i,p>(ADD,j,k) */
2017                         if (true
2018                                 // check expression type
2019                                 && expArg instanceof harpoon.IR.Tree.BINOP
2020                                 // check opcode
2021                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
2022                                 // check operand types
2023                                 && ( 
2024                                         expArg.type() == Type.POINTER ||
2025                                 (       expArg.type() == Type.INT && !
2026                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2027                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2028                                         false )
2029                                 // end check operand types
2030                                         // check left child
2031                                         // no check needed for ExpId children
2032                                         // check right child
2033                                         // no check needed for ExpId children
2034                         ){
2035                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2036                                 _matched_ = true;
2037 
2038                                 if (_matched_) { // action code! degree: 1
2039                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2040                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2041 
2042 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2043 clearDecl();
2044 declare(i, code.getTreeDerivation(), ROOT);
2045 
2046    emitLineDebugInfo(ROOT);
2047    emit( ROOT, "addu `d0, `s0, `s1", i, j, k);
2048                         return i;
2049                         }
2050                         }
2051                                  /* BINOP<l>(ADD,j,k) */
2052                         if (true
2053                                 // check expression type
2054                                 && expArg instanceof harpoon.IR.Tree.BINOP
2055                                 // check opcode
2056                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
2057                                 // check operand types
2058                                 && ( 
2059                                         expArg.type() == Type.LONG ||
2060                                         false )
2061                                 // end check operand types
2062                                         // check left child
2063                                         // no check needed for ExpId children
2064                                         // check right child
2065                                         // no check needed for ExpId children
2066                         ){
2067                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2068                                 _matched_ = true;
2069 
2070                                 if (_matched_) { // action code! degree: 1
2071                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2072                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2073 
2074 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2075 clearDecl();
2076 declare(i, code.getTreeDerivation(), ROOT);
2077 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
2078         public int type() { return harpoon.IR.Tree.Type.INT; }
2079         public boolean isFloatingPoint() { return false; }
2080         public boolean isDoubleWord() { return false; }
2081 }, inf.tempFactory() );
2082 declare(extra, HClass.Int);
2083 
2084    assert i instanceof TwoWordTemp;
2085    emitLineDebugInfo(ROOT);
2086    emitRegAllocDef(ROOT, i);
2087    if(yellow_pekoe) {
2088       emit2( ROOT, "addu `d0l, `s0l, `s1l\n"
2089              + "sltu `d1, `s2l, `s1l\n"
2090              + "addu.l1 `d0h, `s3, `s0h\n"
2091              + "addu `d0h, `s2h, `s1h",
2092           new Temp[] {i, extra}, new Temp[] {j, k, i, extra} );
2093    } else {
2094       emit2( ROOT, "addu `d0l, `s0l, `s1l\n"
2095              + "sltu `d1, `s2l, `s1l\n"
2096              + "addu `d0h, `s3, `s0h\n"
2097              + "addu `d0h, `s2h, `s1h",
2098              new Temp[] {i, extra}, new Temp[] {j, k, i, extra} );
2099    }
2100    emitRegAllocUse(ROOT, j);
2101    emitRegAllocUse(ROOT, k);
2102                         return i;
2103                         }
2104                         }
2105                                  /* BINOP<f>(ADD,j,k) */
2106                         if (true
2107                                 // check expression type
2108                                 && expArg instanceof harpoon.IR.Tree.BINOP
2109                                 // check opcode
2110                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
2111                                 // check operand types
2112                                 && ( 
2113                                         expArg.type() == Type.FLOAT ||
2114                                         false )
2115                                 // end check operand types
2116                                         // check left child
2117                                         // no check needed for ExpId children
2118                                         // check right child
2119                                         // no check needed for ExpId children
2120                         ){
2121                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2122                                 _matched_ = true;
2123 
2124                                 if (_matched_) { // action code! degree: 1
2125                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2126                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2127 
2128 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2129 clearDecl();
2130 declare(i, code.getTreeDerivation(), ROOT);
2131 
2132    emitLineDebugInfo(ROOT);
2133    DoFCall(ROOT, i,j,k,"__addsf3");
2134                         return i;
2135                         }
2136                         }
2137                                  /* BINOP<d>(ADD,j,k) */
2138                         if (true
2139                                 // check expression type
2140                                 && expArg instanceof harpoon.IR.Tree.BINOP
2141                                 // check opcode
2142                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.ADD
2143                                 // check operand types
2144                                 && ( 
2145                                         expArg.type() == Type.DOUBLE ||
2146                                         false )
2147                                 // end check operand types
2148                                         // check left child
2149                                         // no check needed for ExpId children
2150                                         // check right child
2151                                         // no check needed for ExpId children
2152                         ){
2153                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2154                                 _matched_ = true;
2155 
2156                                 if (_matched_) { // action code! degree: 1
2157                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2158                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2159 
2160 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2161 clearDecl();
2162 declare(i, code.getTreeDerivation(), ROOT);
2163 
2164    emitLineDebugInfo(ROOT);
2165    DoDCall(ROOT, i, j, k, "__adddf3");
2166                         return i;
2167                         }
2168                         }
2169                                  /* BINOP<i,p>(MUL,j,k) */
2170                         if (true
2171                                 // check expression type
2172                                 && expArg instanceof harpoon.IR.Tree.BINOP
2173                                 // check opcode
2174                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.MUL
2175                                 // check operand types
2176                                 && ( 
2177                                         expArg.type() == Type.POINTER ||
2178                                 (       expArg.type() == Type.INT && !
2179                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2180                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2181                                         false )
2182                                 // end check operand types
2183                                         // check left child
2184                                         // no check needed for ExpId children
2185                                         // check right child
2186                                         // no check needed for ExpId children
2187                         ){
2188                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2189                                 _matched_ = true;
2190 
2191                                 if (_matched_) { // action code! degree: 1
2192                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2193                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2194 
2195 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2196 clearDecl();
2197 declare(i, code.getTreeDerivation(), ROOT);
2198 
2199    emitLineDebugInfo(ROOT);
2200    emit( ROOT, "mul `d0, `s0, `s1", i, j, k );
2201                         return i;
2202                         }
2203                         }
2204                                  /* BINOP<l>(MUL,j,k) */
2205                         if (true
2206                                 // check expression type
2207                                 && expArg instanceof harpoon.IR.Tree.BINOP
2208                                 // check opcode
2209                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.MUL
2210                                 // check operand types
2211                                 && ( 
2212                                         expArg.type() == Type.LONG ||
2213                                         false )
2214                                 // end check operand types
2215                                         // check left child
2216                                         // no check needed for ExpId children
2217                                         // check right child
2218                                         // no check needed for ExpId children
2219                         ){
2220                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2221                                 _matched_ = true;
2222 
2223                                 if (_matched_) { // action code! degree: 1
2224                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2225                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2226 
2227 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2228 clearDecl();
2229 declare(i, code.getTreeDerivation(), ROOT);
2230 
2231    emitLineDebugInfo(ROOT);
2232    DoLLCall(ROOT, i, j, k, "__ll_mul");
2233                         return i;
2234                         }
2235                         }
2236                                  /* BINOP<f>(MUL,j,k) */
2237                         if (true
2238                                 // check expression type
2239                                 && expArg instanceof harpoon.IR.Tree.BINOP
2240                                 // check opcode
2241                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.MUL
2242                                 // check operand types
2243                                 && ( 
2244                                         expArg.type() == Type.FLOAT ||
2245                                         false )
2246                                 // end check operand types
2247                                         // check left child
2248                                         // no check needed for ExpId children
2249                                         // check right child
2250                                         // no check needed for ExpId children
2251                         ){
2252                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2253                                 _matched_ = true;
2254 
2255                                 if (_matched_) { // action code! degree: 1
2256                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2257                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2258 
2259 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2260 clearDecl();
2261 declare(i, code.getTreeDerivation(), ROOT);
2262 
2263    emitLineDebugInfo(ROOT);
2264    DoFCall(ROOT, i, j, k, "__mulsf3");
2265                         return i;
2266                         }
2267                         }
2268                                  /* BINOP<d>(MUL,j,k) */
2269                         if (true
2270                                 // check expression type
2271                                 && expArg instanceof harpoon.IR.Tree.BINOP
2272                                 // check opcode
2273                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.MUL
2274                                 // check operand types
2275                                 && ( 
2276                                         expArg.type() == Type.DOUBLE ||
2277                                         false )
2278                                 // end check operand types
2279                                         // check left child
2280                                         // no check needed for ExpId children
2281                                         // check right child
2282                                         // no check needed for ExpId children
2283                         ){
2284                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2285                                 _matched_ = true;
2286 
2287                                 if (_matched_) { // action code! degree: 1
2288                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2289                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2290 
2291 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2292 clearDecl();
2293 declare(i, code.getTreeDerivation(), ROOT);
2294 
2295    emitLineDebugInfo(ROOT);
2296    DoDCall(ROOT, i, j, k, "__muldf3");
2297                         return i;
2298                         }
2299                         }
2300                                  /* BINOP<i,p>(DIV,j,k) */
2301                         if (true
2302                                 // check expression type
2303                                 && expArg instanceof harpoon.IR.Tree.BINOP
2304                                 // check opcode
2305                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.DIV
2306                                 // check operand types
2307                                 && ( 
2308                                         expArg.type() == Type.POINTER ||
2309                                 (       expArg.type() == Type.INT && !
2310                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2311                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2312                                         false )
2313                                 // end check operand types
2314                                         // check left child
2315                                         // no check needed for ExpId children
2316                                         // check right child
2317                                         // no check needed for ExpId children
2318                         ){
2319                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2320                                 _matched_ = true;
2321 
2322                                 if (_matched_) { // action code! degree: 1
2323                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2324                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2325 
2326 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2327 clearDecl();
2328 declare(i, code.getTreeDerivation(), ROOT);
2329 
2330    emitLineDebugInfo(ROOT);
2331    emit( ROOT, "div `d0, `s0, `s1", i, j, k );
2332                         return i;
2333                         }
2334                         }
2335                                  /* BINOP<l>(DIV,j,k) */
2336                         if (true
2337                                 // check expression type
2338                                 && expArg instanceof harpoon.IR.Tree.BINOP
2339                                 // check opcode
2340                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.DIV
2341                                 // check operand types
2342                                 && ( 
2343                                         expArg.type() == Type.LONG ||
2344                                         false )
2345                                 // end check operand types
2346                                         // check left child
2347                                         // no check needed for ExpId children
2348                                         // check right child
2349                                         // no check needed for ExpId children
2350                         ){
2351                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2352                                 _matched_ = true;
2353 
2354                                 if (_matched_) { // action code! degree: 1
2355                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2356                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2357 
2358 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2359 clearDecl();
2360 declare(i, code.getTreeDerivation(), ROOT);
2361 
2362    emitLineDebugInfo(ROOT);
2363    // Call gcc internal function directly
2364    DoLLCall(ROOT, i, j, k, "__divdi3");
2365    // This is the c-wrapper version
2366    // DoLLCall(ROOT, i, j, k, "__ll_div");
2367                         return i;
2368                         }
2369                         }
2370                                  /* BINOP<f>(DIV,j,k) */
2371                         if (true
2372                                 // check expression type
2373                                 && expArg instanceof harpoon.IR.Tree.BINOP
2374                                 // check opcode
2375                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.DIV
2376                                 // check operand types
2377                                 && ( 
2378                                         expArg.type() == Type.FLOAT ||
2379                                         false )
2380                                 // end check operand types
2381                                         // check left child
2382                                         // no check needed for ExpId children
2383                                         // check right child
2384                                         // no check needed for ExpId children
2385                         ){
2386                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2387                                 _matched_ = true;
2388 
2389                                 if (_matched_) { // action code! degree: 1
2390                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2391                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2392 
2393 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2394 clearDecl();
2395 declare(i, code.getTreeDerivation(), ROOT);
2396 
2397    emitLineDebugInfo(ROOT);
2398    DoFCall(ROOT, i, j, k, "__divsf3");
2399                         return i;
2400                         }
2401                         }
2402                                  /* BINOP<d>(DIV,j,k) */
2403                         if (true
2404                                 // check expression type
2405                                 && expArg instanceof harpoon.IR.Tree.BINOP
2406                                 // check opcode
2407                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.DIV
2408                                 // check operand types
2409                                 && ( 
2410                                         expArg.type() == Type.DOUBLE ||
2411                                         false )
2412                                 // end check operand types
2413                                         // check left child
2414                                         // no check needed for ExpId children
2415                                         // check right child
2416                                         // no check needed for ExpId children
2417                         ){
2418                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2419                                 _matched_ = true;
2420 
2421                                 if (_matched_) { // action code! degree: 1
2422                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2423                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2424 
2425 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2426 clearDecl();
2427 declare(i, code.getTreeDerivation(), ROOT);
2428 
2429    emitLineDebugInfo(ROOT);
2430    DoDCall(ROOT, i, j, k, "__divdf3");
2431                         return i;
2432                         }
2433                         }
2434                                  /* BINOP<i>(REM,j,k) */
2435                         if (true
2436                                 // check expression type
2437                                 && expArg instanceof harpoon.IR.Tree.BINOP
2438                                 // check opcode
2439                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.REM
2440                                 // check operand types
2441                                 && ( 
2442                                 (       expArg.type() == Type.INT && !
2443                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2444                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2445                                         false )
2446                                 // end check operand types
2447                                         // check left child
2448                                         // no check needed for ExpId children
2449                                         // check right child
2450                                         // no check needed for ExpId children
2451                         ){
2452                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2453                                 _matched_ = true;
2454 
2455                                 if (_matched_) { // action code! degree: 1
2456                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2457                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2458 
2459 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2460 clearDecl();
2461 declare(i, code.getTreeDerivation(), ROOT);
2462 
2463    emitLineDebugInfo(ROOT);
2464    emit( ROOT, "rem `d0, `s0, `s1", i, j, k );
2465                         return i;
2466                         }
2467                         }
2468                                  /* BINOP<l>(REM,j,k) */
2469                         if (true
2470                                 // check expression type
2471                                 && expArg instanceof harpoon.IR.Tree.BINOP
2472                                 // check opcode
2473                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.REM
2474                                 // check operand types
2475                                 && ( 
2476                                         expArg.type() == Type.LONG ||
2477                                         false )
2478                                 // end check operand types
2479                                         // check left child
2480                                         // no check needed for ExpId children
2481                                         // check right child
2482                                         // no check needed for ExpId children
2483                         ){
2484                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2485                                 _matched_ = true;
2486 
2487                                 if (_matched_) { // action code! degree: 1
2488                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2489                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2490 
2491 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2492 clearDecl();
2493 declare(i, code.getTreeDerivation(), ROOT);
2494 
2495    emitLineDebugInfo(ROOT);
2496    // Optimize by calling gcc builtin
2497    DoLLCall(ROOT, i, j, k, "__moddi3");
2498    // This the the call to a C function
2499    // DoLLCall(ROOT, i, j, k, "__ll_rem");
2500                         return i;
2501                         }
2502                         }
2503                                  /* BINOP<f>(REM,j,k) */
2504                         if (true
2505                                 // check expression type
2506                                 && expArg instanceof harpoon.IR.Tree.BINOP
2507                                 // check opcode
2508                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.REM
2509                                 // check operand types
2510                                 && ( 
2511                                         expArg.type() == Type.FLOAT ||
2512                                         false )
2513                                 // end check operand types
2514                                         // check left child
2515                                         // no check needed for ExpId children
2516                                         // check right child
2517                                         // no check needed for ExpId children
2518                         ){
2519                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2520                                 _matched_ = true;
2521 
2522                                 if (_matched_) { // action code! degree: 1
2523                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2524                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2525 
2526 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2527 clearDecl();
2528 declare(i, code.getTreeDerivation(), ROOT);
2529 
2530    emitLineDebugInfo(ROOT);
2531    DoFCall(ROOT, i, j, k, "__f_rem");
2532                         return i;
2533                         }
2534                         }
2535                                  /* BINOP<d>(REM,j,k) */
2536                         if (true
2537                                 // check expression type
2538                                 && expArg instanceof harpoon.IR.Tree.BINOP
2539                                 // check opcode
2540                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.REM
2541                                 // check operand types
2542                                 && ( 
2543                                         expArg.type() == Type.DOUBLE ||
2544                                         false )
2545                                 // end check operand types
2546                                         // check left child
2547                                         // no check needed for ExpId children
2548                                         // check right child
2549                                         // no check needed for ExpId children
2550                         ){
2551                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2552                                 _matched_ = true;
2553 
2554                                 if (_matched_) { // action code! degree: 1
2555                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2556                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2557 
2558 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2559 clearDecl();
2560 declare(i, code.getTreeDerivation(), ROOT);
2561 
2562    emitLineDebugInfo(ROOT);
2563    DoDCall(ROOT, i, j, k, "__d_rem");
2564                         return i;
2565                         }
2566                         }
2567                                  /* UNOP<i,p>(NEG,arg) */
2568                         if (true
2569                                 // check expression type
2570                                 && expArg instanceof harpoon.IR.Tree.UNOP 
2571                                 // check opcode
2572                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.NEG
2573                                 // check operand types
2574                                 && ( 
2575                                         expArg.type() == Type.POINTER ||
2576                                 (       expArg.type() == Type.INT && !
2577                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2578                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2579                                         false )
2580                                 // end check operand types
2581                                         // check child
2582                                         // no check needed for ExpId children
2583                         ){
2584                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
2585                                 _matched_ = true;
2586 
2587                                 if (_matched_) { // action code! degree: 1
2588                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
2589 
2590 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2591 clearDecl();
2592 declare(i, code.getTreeDerivation(), ROOT);
2593 
2594    emitLineDebugInfo(ROOT);
2595    emit( ROOT, "negu `d0, `s0", i, arg );
2596                         return i;
2597                         }
2598                         }
2599                                  /* UNOP<f>(NEG,arg) */
2600                         if (true
2601                                 // check expression type
2602                                 && expArg instanceof harpoon.IR.Tree.UNOP 
2603                                 // check opcode
2604                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.NEG
2605                                 // check operand types
2606                                 && ( 
2607                                         expArg.type() == Type.FLOAT ||
2608                                         false )
2609                                 // end check operand types
2610                                         // check child
2611                                         // no check needed for ExpId children
2612                         ){
2613                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
2614                                 _matched_ = true;
2615 
2616                                 if (_matched_) { // action code! degree: 1
2617                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
2618 
2619 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2620 clearDecl();
2621 declare(i, code.getTreeDerivation(), ROOT);
2622 
2623    emitLineDebugInfo(ROOT);
2624    DoFCall(ROOT, i, arg, "__f_neg");
2625                         return i;
2626                         }
2627                         }
2628                                  /* UNOP<d>(NEG,arg) */
2629                         if (true
2630                                 // check expression type
2631                                 && expArg instanceof harpoon.IR.Tree.UNOP 
2632                                 // check opcode
2633                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.NEG
2634                                 // check operand types
2635                                 && ( 
2636                                         expArg.type() == Type.DOUBLE ||
2637                                         false )
2638                                 // end check operand types
2639                                         // check child
2640                                         // no check needed for ExpId children
2641                         ){
2642                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
2643                                 _matched_ = true;
2644 
2645                                 if (_matched_) { // action code! degree: 1
2646                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
2647 
2648 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2649 clearDecl();
2650 declare(i, code.getTreeDerivation(), ROOT);
2651 
2652    emitLineDebugInfo(ROOT);
2653    DoDCall(ROOT, i, arg, "__d_neg");
2654                         return i;
2655                         }
2656                         }
2657                                  /* UNOP<l>(NEG,arg) */
2658                         if (true
2659                                 // check expression type
2660                                 && expArg instanceof harpoon.IR.Tree.UNOP 
2661                                 // check opcode
2662                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.NEG
2663                                 // check operand types
2664                                 && ( 
2665                                         expArg.type() == Type.LONG ||
2666                                         false )
2667                                 // end check operand types
2668                                         // check child
2669                                         // no check needed for ExpId children
2670                         ){
2671                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
2672                                 _matched_ = true;
2673 
2674                                 if (_matched_) { // action code! degree: 1
2675                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
2676 
2677 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2678 clearDecl();
2679 declare(i, code.getTreeDerivation(), ROOT);
2680 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
2681         public int type() { return harpoon.IR.Tree.Type.INT; }
2682         public boolean isFloatingPoint() { return false; }
2683         public boolean isDoubleWord() { return false; }
2684 }, inf.tempFactory() );
2685 declare(extra, HClass.Int);
2686 
2687    emitLineDebugInfo(ROOT);
2688    emitRegAllocDef(ROOT, i);
2689    if(yellow_pekoe) {
2690       emit2( ROOT, "subu `d0l, $0, `s0l\n"
2691              + "subu `d0h, $0, `s0h\n"
2692              + "sltu `d1, $0, `s0l\n"
2693              + "subu.l2 `d0h, `s1h, `s2",
2694              new Temp[] {i,extra}, new Temp[] {arg, i, extra} );
2695    } else {
2696       emit2( ROOT, "subu `d0l, $0, `s0l\n"
2697              + "subu `d0h, $0, `s0h\n"
2698              + "sltu `d1, $0, `s0l\n"
2699              + "subu `d0h, `s1h, `s2",
2700              new Temp[] {i,extra}, new Temp[] {arg, i, extra} );
2701    }
2702    emitRegAllocUse(ROOT, arg);
2703                         return i;
2704                         }
2705                         }
2706                                  /* BINOP<i,p>(AND,j,k) */
2707                         if (true
2708                                 // check expression type
2709                                 && expArg instanceof harpoon.IR.Tree.BINOP
2710                                 // check opcode
2711                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.AND
2712                                 // check operand types
2713                                 && ( 
2714                                         expArg.type() == Type.POINTER ||
2715                                 (       expArg.type() == Type.INT && !
2716                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2717                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2718                                         false )
2719                                 // end check operand types
2720                                         // check left child
2721                                         // no check needed for ExpId children
2722                                         // check right child
2723                                         // no check needed for ExpId children
2724                         ){
2725                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2726                                 _matched_ = true;
2727 
2728                                 if (_matched_) { // action code! degree: 1
2729                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2730                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2731 
2732 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2733 clearDecl();
2734 declare(i, code.getTreeDerivation(), ROOT);
2735 
2736    emitLineDebugInfo(ROOT);
2737    emit( ROOT, "and `d0, `s0, `s1", i, j, k );
2738                         return i;
2739                         }
2740                         }
2741                                  /* BINOP<l>(AND,j,k) */
2742                         if (true
2743                                 // check expression type
2744                                 && expArg instanceof harpoon.IR.Tree.BINOP
2745                                 // check opcode
2746                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.AND
2747                                 // check operand types
2748                                 && ( 
2749                                         expArg.type() == Type.LONG ||
2750                                         false )
2751                                 // end check operand types
2752                                         // check left child
2753                                         // no check needed for ExpId children
2754                                         // check right child
2755                                         // no check needed for ExpId children
2756                         ){
2757                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2758                                 _matched_ = true;
2759 
2760                                 if (_matched_) { // action code! degree: 1
2761                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2762                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2763 
2764 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2765 clearDecl();
2766 declare(i, code.getTreeDerivation(), ROOT);
2767 
2768    emitLineDebugInfo(ROOT);
2769    emitRegAllocDef(ROOT, i);
2770    emit( ROOT, "and `d0l, `s0l, `s1l\n"
2771          + "and `d0h, `s0h, `s1h", i, j, k);
2772    emitRegAllocUse(ROOT, j);
2773    emitRegAllocUse(ROOT, k);
2774                         return i;
2775                         }
2776                         }
2777                                  /* BINOP<i,p>(OR,j,k) */
2778                         if (true
2779                                 // check expression type
2780                                 && expArg instanceof harpoon.IR.Tree.BINOP
2781                                 // check opcode
2782                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.OR
2783                                 // check operand types
2784                                 && ( 
2785                                         expArg.type() == Type.POINTER ||
2786                                 (       expArg.type() == Type.INT && !
2787                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2788                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2789                                         false )
2790                                 // end check operand types
2791                                         // check left child
2792                                         // no check needed for ExpId children
2793                                         // check right child
2794                                         // no check needed for ExpId children
2795                         ){
2796                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2797                                 _matched_ = true;
2798 
2799                                 if (_matched_) { // action code! degree: 1
2800                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2801                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2802 
2803 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2804 clearDecl();
2805 declare(i, code.getTreeDerivation(), ROOT);
2806 
2807    emitLineDebugInfo(ROOT);
2808    emit( ROOT, "or `d0, `s0, `s1", i, j, k );
2809                         return i;
2810                         }
2811                         }
2812                                  /* BINOP<l>(OR,j,k) */
2813                         if (true
2814                                 // check expression type
2815                                 && expArg instanceof harpoon.IR.Tree.BINOP
2816                                 // check opcode
2817                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.OR
2818                                 // check operand types
2819                                 && ( 
2820                                         expArg.type() == Type.LONG ||
2821                                         false )
2822                                 // end check operand types
2823                                         // check left child
2824                                         // no check needed for ExpId children
2825                                         // check right child
2826                                         // no check needed for ExpId children
2827                         ){
2828                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2829                                 _matched_ = true;
2830 
2831                                 if (_matched_) { // action code! degree: 1
2832                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2833                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2834 
2835 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2836 clearDecl();
2837 declare(i, code.getTreeDerivation(), ROOT);
2838 
2839    emitLineDebugInfo(ROOT);
2840    emitRegAllocDef(ROOT, i);
2841    emit( ROOT, "or `d0l, `s0l, `s1l\n"
2842          + "or `d0h, `s0h, `s1h", i, j, k );
2843    emitRegAllocUse(ROOT, j);
2844    emitRegAllocUse(ROOT, k);
2845                         return i;
2846                         }
2847                         }
2848                                  /* BINOP<i,p>(XOR,j,k) */
2849                         if (true
2850                                 // check expression type
2851                                 && expArg instanceof harpoon.IR.Tree.BINOP
2852                                 // check opcode
2853                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.XOR
2854                                 // check operand types
2855                                 && ( 
2856                                         expArg.type() == Type.POINTER ||
2857                                 (       expArg.type() == Type.INT && !
2858                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2859                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2860                                         false )
2861                                 // end check operand types
2862                                         // check left child
2863                                         // no check needed for ExpId children
2864                                         // check right child
2865                                         // no check needed for ExpId children
2866                         ){
2867                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2868                                 _matched_ = true;
2869 
2870                                 if (_matched_) { // action code! degree: 1
2871                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2872                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2873 
2874 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2875 clearDecl();
2876 declare(i, code.getTreeDerivation(), ROOT);
2877 
2878    emitLineDebugInfo(ROOT);
2879     emit( ROOT, "xor `d0, `s0, `s1", i, j, k );
2880                         return i;
2881                         }
2882                         }
2883                                  /* BINOP<l>(XOR,j,k) */
2884                         if (true
2885                                 // check expression type
2886                                 && expArg instanceof harpoon.IR.Tree.BINOP
2887                                 // check opcode
2888                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.XOR
2889                                 // check operand types
2890                                 && ( 
2891                                         expArg.type() == Type.LONG ||
2892                                         false )
2893                                 // end check operand types
2894                                         // check left child
2895                                         // no check needed for ExpId children
2896                                         // check right child
2897                                         // no check needed for ExpId children
2898                         ){
2899                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
2900                                 _matched_ = true;
2901 
2902                                 if (_matched_) { // action code! degree: 1
2903                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
2904                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
2905 
2906 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2907 clearDecl();
2908 declare(i, code.getTreeDerivation(), ROOT);
2909 
2910    emitLineDebugInfo(ROOT);
2911    emitRegAllocDef(ROOT, i);
2912    emit( ROOT, "xor `d0l, `s0l, `s1l\n"
2913          + "xor `d0h, `s0h, `s1h", i, j, k );
2914    emitRegAllocUse(ROOT, j);
2915    emitRegAllocUse(ROOT, k);
2916                         return i;
2917                         }
2918                         }
2919                                  /* UNOP<i,p>(NOT,arg) */
2920                         if (true
2921                                 // check expression type
2922                                 && expArg instanceof harpoon.IR.Tree.UNOP 
2923                                 // check opcode
2924                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.NOT
2925                                 // check operand types
2926                                 && ( 
2927                                         expArg.type() == Type.POINTER ||
2928                                 (       expArg.type() == Type.INT && !
2929                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2930                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2931                                         false )
2932                                 // end check operand types
2933                                         // check child
2934                                         // no check needed for ExpId children
2935                         ){
2936                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
2937                                 _matched_ = true;
2938 
2939                                 if (_matched_) { // action code! degree: 1
2940                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
2941 
2942 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2943 clearDecl();
2944 declare(i, code.getTreeDerivation(), ROOT);
2945 
2946    emitLineDebugInfo(ROOT);
2947    emit( ROOT, "not `d0, `s0", i, arg );
2948                         return i;
2949                         }
2950                         }
2951                                  /* UNOP<l>(NOT,arg) */
2952                         if (true
2953                                 // check expression type
2954                                 && expArg instanceof harpoon.IR.Tree.UNOP 
2955                                 // check opcode
2956                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.NOT
2957                                 // check operand types
2958                                 && ( 
2959                                         expArg.type() == Type.LONG ||
2960                                         false )
2961                                 // end check operand types
2962                                         // check child
2963                                         // no check needed for ExpId children
2964                         ){
2965                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
2966                                 _matched_ = true;
2967 
2968                                 if (_matched_) { // action code! degree: 1
2969                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
2970 
2971 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
2972 clearDecl();
2973 declare(i, code.getTreeDerivation(), ROOT);
2974 
2975    emitLineDebugInfo(ROOT);
2976    emitRegAllocDef(ROOT, i);
2977    emit( ROOT, "not `d0l, `s0l\n"
2978          + "not `d0h, `s0h", i, arg );
2979    emitRegAllocUse(ROOT, arg);
2980                         return i;
2981                         }
2982                         }
2983                                  /* BINOP<i,l,f,d,p>(cmpop,j,k) */
2984                         if (true
2985                                 // check expression type
2986                                 && expArg instanceof harpoon.IR.Tree.BINOP
2987                                 // check operand types
2988                                 && ( 
2989                                         expArg.type() == Type.DOUBLE ||
2990                                         expArg.type() == Type.FLOAT ||
2991                                         expArg.type() == Type.LONG ||
2992                                         expArg.type() == Type.POINTER ||
2993                                 (       expArg.type() == Type.INT && !
2994                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
2995                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
2996                                         false )
2997                                 // end check operand types
2998                                         // check left child
2999                                         // no check needed for ExpId children
3000                                         // check right child
3001                                         // no check needed for ExpId children
3002                         ){
3003                                 int cmpop = ((harpoon.IR.Tree.BINOP) expArg).op;
3004                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3005                                 _matched_ = true&& ( (ROOT.operandType()==Type.POINTER || ROOT.operandType()==Type.INT)
3006          && isCmpOp(cmpop) );
3007 
3008                                 if (_matched_) { // action code! degree: 1
3009                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3010                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3011 
3012 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3013 clearDecl();
3014 declare(i, code.getTreeDerivation(), ROOT);
3015 
3016    emitLineDebugInfo(ROOT);
3017    // Lets hear it for the MIPS assembler
3018    emit( ROOT, cmpOp2AsStr(cmpop) + " `d0, `s0, `s1 # cmpop", i, j, k );
3019                         return i;
3020                         }
3021                         }
3022                                  /* BINOP<i,l,f,d,p>(CMPEQ,j,k) */
3023                         if (true
3024                                 // check expression type
3025                                 && expArg instanceof harpoon.IR.Tree.BINOP
3026                                 // check opcode
3027                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.CMPEQ
3028                                 // check operand types
3029                                 && ( 
3030                                         expArg.type() == Type.DOUBLE ||
3031                                         expArg.type() == Type.FLOAT ||
3032                                         expArg.type() == Type.LONG ||
3033                                         expArg.type() == Type.POINTER ||
3034                                 (       expArg.type() == Type.INT && !
3035                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3036                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3037                                         false )
3038                                 // end check operand types
3039                                         // check left child
3040                                         // no check needed for ExpId children
3041                                         // check right child
3042                                         // no check needed for ExpId children
3043                         ){
3044                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3045                                 _matched_ = true&& ( ROOT.operandType()==Type.LONG );
3046 
3047                                 if (_matched_) { // action code! degree: 1
3048                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3049                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3050 
3051 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3052 clearDecl();
3053 declare(i, code.getTreeDerivation(), ROOT);
3054 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
3055         public int type() { return harpoon.IR.Tree.Type.INT; }
3056         public boolean isFloatingPoint() { return false; }
3057         public boolean isDoubleWord() { return false; }
3058 }, inf.tempFactory() );
3059 declare(extra, HClass.Int);
3060 
3061    emitLineDebugInfo(ROOT);
3062     emit( ROOT, "xor `d0, `s0l, `s1l", i, j, k );
3063     emit( ROOT, "xor `d0, `s0h, `s1h", extra, j, k );
3064     emit( ROOT, "or  `d0, `s0,  `s1", i, i, extra );
3065     emit( ROOT, "sltiu `d0, `s0, 1", i, i );
3066                         return i;
3067                         }
3068                         }
3069                                  /* BINOP<i,l,f,d,p>(CMPNE,j,k) */
3070                         if (true
3071                                 // check expression type
3072                                 && expArg instanceof harpoon.IR.Tree.BINOP
3073                                 // check opcode
3074                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.CMPNE
3075                                 // check operand types
3076                                 && ( 
3077                                         expArg.type() == Type.DOUBLE ||
3078                                         expArg.type() == Type.FLOAT ||
3079                                         expArg.type() == Type.LONG ||
3080                                         expArg.type() == Type.POINTER ||
3081                                 (       expArg.type() == Type.INT && !
3082                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3083                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3084                                         false )
3085                                 // end check operand types
3086                                         // check left child
3087                                         // no check needed for ExpId children
3088                                         // check right child
3089                                         // no check needed for ExpId children
3090                         ){
3091                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3092                                 _matched_ = true&& ( ROOT.operandType()==Type.LONG );
3093 
3094                                 if (_matched_) { // action code! degree: 1
3095                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3096                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3097 
3098 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3099 clearDecl();
3100 declare(i, code.getTreeDerivation(), ROOT);
3101 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
3102         public int type() { return harpoon.IR.Tree.Type.INT; }
3103         public boolean isFloatingPoint() { return false; }
3104         public boolean isDoubleWord() { return false; }
3105 }, inf.tempFactory() );
3106 declare(extra, HClass.Int);
3107 
3108    emitLineDebugInfo(ROOT);
3109     emit( ROOT, "xor `d0, `s0l, `s1l", i, j, k );
3110     emit( ROOT, "xor `d0, `s0h, `s1h", extra, j, k );
3111     emit( ROOT, "or  `d0, `s0,  `s1", i, i, extra );
3112     emit( ROOT, "sltu `d0, $0, `s0", i, i );
3113                         return i;
3114                         }
3115                         }
3116                                  /* BINOP<i,l,f,d,p>(CMPLT,j,k) */
3117                         if (true
3118                                 // check expression type
3119                                 && expArg instanceof harpoon.IR.Tree.BINOP
3120                                 // check opcode
3121                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.CMPLT
3122                                 // check operand types
3123                                 && ( 
3124                                         expArg.type() == Type.DOUBLE ||
3125                                         expArg.type() == Type.FLOAT ||
3126                                         expArg.type() == Type.LONG ||
3127                                         expArg.type() == Type.POINTER ||
3128                                 (       expArg.type() == Type.INT && !
3129                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3130                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3131                                         false )
3132                                 // end check operand types
3133                                         // check left child
3134                                         // no check needed for ExpId children
3135                                         // check right child
3136                                         // no check needed for ExpId children
3137                         ){
3138                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3139                                 _matched_ = true&& ( ROOT.operandType()==Type.LONG );
3140 
3141                                 if (_matched_) { // action code! degree: 1
3142                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3143                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3144 
3145 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3146 clearDecl();
3147 declare(i, code.getTreeDerivation(), ROOT);
3148 
3149    emitLineDebugInfo(ROOT);
3150    Label done = new Label();
3151    Label reg = new Label(); // Reg Alloc sanity pass sucks
3152 
3153    emit( ROOT, "slt `d0, `s0h, `s1h", i, j, k);
3154    emitCondBr( ROOT, "bne `s0h, `s1h, `L0", j, k, done);
3155    emitLABEL( ROOT, reg + ": ", reg );
3156    emit( ROOT, "sltu `d0, `s0l, `s1l", i, j, k);
3157    emitLABEL( ROOT, done + ": ", done );
3158                         return i;
3159                         }
3160                         }
3161                                  /* BINOP<i,l,f,d,p>(CMPLE,j,k) */
3162                         if (true
3163                                 // check expression type
3164                                 && expArg instanceof harpoon.IR.Tree.BINOP
3165                                 // check opcode
3166                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.CMPLE
3167                                 // check operand types
3168                                 && ( 
3169                                         expArg.type() == Type.DOUBLE ||
3170                                         expArg.type() == Type.FLOAT ||
3171                                         expArg.type() == Type.LONG ||
3172                                         expArg.type() == Type.POINTER ||
3173                                 (       expArg.type() == Type.INT && !
3174                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3175                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3176                                         false )
3177                                 // end check operand types
3178                                         // check left child
3179                                         // no check needed for ExpId children
3180                                         // check right child
3181                                         // no check needed for ExpId children
3182                         ){
3183                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3184                                 _matched_ = true&& ( ROOT.operandType()==Type.LONG );
3185 
3186                                 if (_matched_) { // action code! degree: 1
3187                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3188                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3189 
3190 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3191 clearDecl();
3192 declare(i, code.getTreeDerivation(), ROOT);
3193 
3194    emitLineDebugInfo(ROOT);
3195    Label done = new Label();
3196    Label reg = new Label(); // Reg Alloc sanity pass sucks
3197 
3198    emit( ROOT, "slt `d0, `s0h, `s1h", i, j, k);
3199    emitCondBr( ROOT, "bne `s0h, `s1h, `L0", j, k, done);
3200    emitLABEL( ROOT, reg + ": ", reg );
3201    emit( ROOT, "sleu `d0, `s0l, `s1l", i, j, k);
3202    emitLABEL( ROOT, done + ": ", done );
3203                         return i;
3204                         }
3205                         }
3206                                  /* BINOP<i,l,f,d,p>(CMPGT,j,k) */
3207                         if (true
3208                                 // check expression type
3209                                 && expArg instanceof harpoon.IR.Tree.BINOP
3210                                 // check opcode
3211                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.CMPGT
3212                                 // check operand types
3213                                 && ( 
3214                                         expArg.type() == Type.DOUBLE ||
3215                                         expArg.type() == Type.FLOAT ||
3216                                         expArg.type() == Type.LONG ||
3217                                         expArg.type() == Type.POINTER ||
3218                                 (       expArg.type() == Type.INT && !
3219                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3220                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3221                                         false )
3222                                 // end check operand types
3223                                         // check left child
3224                                         // no check needed for ExpId children
3225                                         // check right child
3226                                         // no check needed for ExpId children
3227                         ){
3228                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3229                                 _matched_ = true&& ( ROOT.operandType()==Type.LONG );
3230 
3231                                 if (_matched_) { // action code! degree: 1
3232                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3233                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3234 
3235 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3236 clearDecl();
3237 declare(i, code.getTreeDerivation(), ROOT);
3238 
3239    emitLineDebugInfo(ROOT);
3240    Label done = new Label();
3241    Label reg = new Label(); // Reg Alloc sanity pass sucks
3242 
3243    emit( ROOT, "sgt `d0, `s0h, `s1h", i, j, k);
3244    emitCondBr( ROOT, "bne `s0h, `s1h, `L0", j, k, done);
3245    emitLABEL( ROOT, reg + ": ", reg );
3246    emit( ROOT, "sgtu `d0, `s0l, `s1l", i, j, k);
3247    emitLABEL( ROOT, done + ": ", done );
3248                         return i;
3249                         }
3250                         }
3251                                  /* BINOP<i,l,f,d,p>(CMPGE,j,k) */
3252                         if (true
3253                                 // check expression type
3254                                 && expArg instanceof harpoon.IR.Tree.BINOP
3255                                 // check opcode
3256                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.CMPGE
3257                                 // check operand types
3258                                 && ( 
3259                                         expArg.type() == Type.DOUBLE ||
3260                                         expArg.type() == Type.FLOAT ||
3261                                         expArg.type() == Type.LONG ||
3262                                         expArg.type() == Type.POINTER ||
3263                                 (       expArg.type() == Type.INT && !
3264                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3265                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3266                                         false )
3267                                 // end check operand types
3268                                         // check left child
3269                                         // no check needed for ExpId children
3270                                         // check right child
3271                                         // no check needed for ExpId children
3272                         ){
3273                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3274                                 _matched_ = true&& ( ROOT.operandType()==Type.LONG );
3275 
3276                                 if (_matched_) { // action code! degree: 1
3277                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3278                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3279 
3280 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3281 clearDecl();
3282 declare(i, code.getTreeDerivation(), ROOT);
3283 
3284    emitLineDebugInfo(ROOT);
3285    Label done = new Label();
3286    Label reg = new Label(); // Reg Alloc sanity pass sucks
3287 
3288    emit( ROOT, "sgt `d0, `s0h, `s1h", i, j, k);
3289    emitCondBr( ROOT, "bne `s0h, `s1h, `L0", j, k, done);
3290    emitLABEL( ROOT, reg + ": ", reg );
3291    emit( ROOT, "sgeu `d0, `s0l, `s1l", i, j, k);
3292    emitLABEL( ROOT, done + ": ", done );
3293                         return i;
3294                         }
3295                         }
3296                                  /* BINOP<i,l,f,d,p>(cmpop,j,k) */
3297                         if (true
3298                                 // check expression type
3299                                 && expArg instanceof harpoon.IR.Tree.BINOP
3300                                 // check operand types
3301                                 && ( 
3302                                         expArg.type() == Type.DOUBLE ||
3303                                         expArg.type() == Type.FLOAT ||
3304                                         expArg.type() == Type.LONG ||
3305                                         expArg.type() == Type.POINTER ||
3306                                 (       expArg.type() == Type.INT && !
3307                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3308                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3309                                         false )
3310                                 // end check operand types
3311                                         // check left child
3312                                         // no check needed for ExpId children
3313                                         // check right child
3314                                         // no check needed for ExpId children
3315                         ){
3316                                 int cmpop = ((harpoon.IR.Tree.BINOP) expArg).op;
3317                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3318                                 _matched_ = true&& ( ROOT.operandType()==Type.FLOAT && isCmpOp(cmpop) );
3319 
3320                                 if (_matched_) { // action code! degree: 1
3321                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3322                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3323 
3324 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3325 clearDecl();
3326 declare(i, code.getTreeDerivation(), ROOT);
3327 
3328    emitLineDebugInfo(ROOT);
3329    DoFCall(ROOT, i, j, k, "__f_" + cmpOp2AsStr(cmpop));
3330                         return i;
3331                         }
3332                         }
3333                                  /* BINOP<i,l,f,d,p>(cmpop,j,k) */
3334                         if (true
3335                                 // check expression type
3336                                 && expArg instanceof harpoon.IR.Tree.BINOP
3337                                 // check operand types
3338                                 && ( 
3339                                         expArg.type() == Type.DOUBLE ||
3340                                         expArg.type() == Type.FLOAT ||
3341                                         expArg.type() == Type.LONG ||
3342                                         expArg.type() == Type.POINTER ||
3343                                 (       expArg.type() == Type.INT && !
3344                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3345                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3346                                         false )
3347                                 // end check operand types
3348                                         // check left child
3349                                         // no check needed for ExpId children
3350                                         // check right child
3351                                         // no check needed for ExpId children
3352                         ){
3353                                 int cmpop = ((harpoon.IR.Tree.BINOP) expArg).op;
3354                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3355                                 _matched_ = true&& ( ROOT.operandType()==Type.DOUBLE && isCmpOp(cmpop) );
3356 
3357                                 if (_matched_) { // action code! degree: 1
3358                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3359                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3360 
3361 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3362 clearDecl();
3363 declare(i, code.getTreeDerivation(), ROOT);
3364 
3365    emitLineDebugInfo(ROOT);
3366    DoDCall(ROOT, i, j, k, "__d_" + cmpOp2AsStr(cmpop));
3367                         return i;
3368                         }
3369                         }
3370                                  /* BINOP<i,p>(shiftop,j,k) */
3371                         if (true
3372                                 // check expression type
3373                                 && expArg instanceof harpoon.IR.Tree.BINOP
3374                                 // check operand types
3375                                 && ( 
3376                                         expArg.type() == Type.POINTER ||
3377                                 (       expArg.type() == Type.INT && !
3378                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3379                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3380                                         false )
3381                                 // end check operand types
3382                                         // check left child
3383                                         // no check needed for ExpId children
3384                                         // check right child
3385                                         // no check needed for ExpId children
3386                         ){
3387                                 int shiftop = ((harpoon.IR.Tree.BINOP) expArg).op;
3388                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3389                                 _matched_ = true&& ( isShiftOp(shiftop) );
3390 
3391                                 if (_matched_) { // action code! degree: 1
3392                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3393                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3394 
3395 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3396 clearDecl();
3397 declare(i, code.getTreeDerivation(), ROOT);
3398 
3399    emitLineDebugInfo(ROOT);
3400     // java lang spec says shift should occur according to
3401     // 'least significant five bits' of k; MIPS does this correctly
3402    emit( ROOT, shiftOp2Str(shiftop)+" `d0, `s0, `s1", i, j, k);
3403                         return i;
3404                         }
3405                         }
3406                                  /* BINOP<l>(SHL,j,k) */
3407                         if (true
3408                                 // check expression type
3409                                 && expArg instanceof harpoon.IR.Tree.BINOP
3410                                 // check opcode
3411                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.SHL
3412                                 // check operand types
3413                                 && ( 
3414                                         expArg.type() == Type.LONG ||
3415                                         false )
3416                                 // end check operand types
3417                                         // check left child
3418                                         // no check needed for ExpId children
3419                                         // check right child
3420                                         // no check needed for ExpId children
3421                         ){
3422                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3423                                 _matched_ = true;
3424 
3425                                 if (_matched_) { // action code! degree: 1
3426                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3427                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3428 
3429 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3430 clearDecl();
3431 declare(i, code.getTreeDerivation(), ROOT);
3432 
3433    emitLineDebugInfo(ROOT);
3434    DoLLShiftCall(ROOT, i, j, k, "__ll_lshift");
3435                         return i;
3436                         }
3437                         }
3438                                  /* BINOP<l>(SHR,j,k) */
3439                         if (true
3440                                 // check expression type
3441                                 && expArg instanceof harpoon.IR.Tree.BINOP
3442                                 // check opcode
3443                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.SHR
3444                                 // check operand types
3445                                 && ( 
3446                                         expArg.type() == Type.LONG ||
3447                                         false )
3448                                 // end check operand types
3449                                         // check left child
3450                                         // no check needed for ExpId children
3451                                         // check right child
3452                                         // no check needed for ExpId children
3453                         ){
3454                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3455                                 _matched_ = true;
3456 
3457                                 if (_matched_) { // action code! degree: 1
3458                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3459                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3460 
3461 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3462 clearDecl();
3463 declare(i, code.getTreeDerivation(), ROOT);
3464 
3465    emitLineDebugInfo(ROOT);
3466    DoLLShiftCall(ROOT, i, j, k, "__ll_rshift");
3467                         return i;
3468                         }
3469                         }
3470                                  /* BINOP<l>(USHR,j,k) */
3471                         if (true
3472                                 // check expression type
3473                                 && expArg instanceof harpoon.IR.Tree.BINOP
3474                                 // check opcode
3475                                 && ((harpoon.IR.Tree.BINOP)expArg).op == harpoon.IR.Tree.Bop.USHR
3476                                 // check operand types
3477                                 && ( 
3478                                         expArg.type() == Type.LONG ||
3479                                         false )
3480                                 // end check operand types
3481                                         // check left child
3482                                         // no check needed for ExpId children
3483                                         // check right child
3484                                         // no check needed for ExpId children
3485                         ){
3486                         harpoon.IR.Tree.BINOP ROOT = (harpoon.IR.Tree.BINOP) expArg;
3487                                 _matched_ = true;
3488 
3489                                 if (_matched_) { // action code! degree: 1
3490                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)expArg).getLeft()); 
3491                                         harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)expArg).getRight()); 
3492 
3493 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3494 clearDecl();
3495 declare(i, code.getTreeDerivation(), ROOT);
3496 
3497    emitLineDebugInfo(ROOT);
3498    DoLLShiftCall(ROOT, i, j, k, "__ull_rshift");
3499                         return i;
3500                         }
3501                         }
3502                                  /* CONST<l,d>(c) */
3503                         if (true
3504                                 // check expression type
3505                                 && expArg instanceof harpoon.IR.Tree.CONST 
3506                                 // check operand types
3507                                 && ( 
3508                                         expArg.type() == Type.DOUBLE ||
3509                                         expArg.type() == Type.LONG ||
3510                                         false )
3511                                 // end check operand types
3512                         ){
3513                                 Number c = ((harpoon.IR.Tree.CONST) expArg).value;
3514                         harpoon.IR.Tree.CONST ROOT = (harpoon.IR.Tree.CONST) expArg;
3515                                 _matched_ = true;
3516 
3517                                 if (_matched_) { // action code! degree: 1
3518 
3519 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3520 clearDecl();
3521 declare(i, code.getTreeDerivation(), ROOT);
3522 
3523    long val = (ROOT.type()==Type.LONG) ? ROOT.value.longValue()
3524    : Double.doubleToLongBits(ROOT.value.doubleValue());
3525 
3526    emitLineDebugInfo(ROOT);
3527    emitRegAllocDef(ROOT, i);
3528    emit( ROOT, "li `d0h, " + (int)(val>>>32) + " # hi long const\n"
3529          + "li `d0l, " + (int)val + " # lo long const", i);
3530                         return i;
3531                         }
3532                         }
3533                                  /* CONST<i,f>(c) */
3534                         if (true
3535                                 // check expression type
3536                                 && expArg instanceof harpoon.IR.Tree.CONST 
3537                                 // check operand types
3538                                 && ( 
3539                                         expArg.type() == Type.FLOAT ||
3540                                 (       expArg.type() == Type.INT && !
3541                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3542                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3543                                         false )
3544                                 // end check operand types
3545                         ){
3546                                 Number c = ((harpoon.IR.Tree.CONST) expArg).value;
3547                         harpoon.IR.Tree.CONST ROOT = (harpoon.IR.Tree.CONST) expArg;
3548                                 _matched_ = true;
3549 
3550                                 if (_matched_) { // action code! degree: 1
3551 
3552 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3553 clearDecl();
3554 declare(i, code.getTreeDerivation(), ROOT);
3555 
3556     int val = (ROOT.type()==Type.INT) ? ROOT.value.intValue()
3557         : Float.floatToIntBits(ROOT.value.floatValue());
3558 
3559    emitLineDebugInfo(ROOT);
3560     String comment = "";
3561     if(ROOT.type() == Type.FLOAT) {
3562        comment = "  # float " + ROOT.value.floatValue();
3563     }
3564     emit(ROOT, "li `d0, " + val + comment, i);
3565                         return i;
3566                         }
3567                         }
3568                                  /* CONST<p>(c) */
3569                         if (true
3570                                 // check expression type
3571                                 && expArg instanceof harpoon.IR.Tree.CONST 
3572                                 // check operand types
3573                                 && ( 
3574                                         expArg.type() == Type.POINTER ||
3575                                         false )
3576                                 // end check operand types
3577                         ){
3578                                 Number c = ((harpoon.IR.Tree.CONST) expArg).value;
3579                         harpoon.IR.Tree.CONST ROOT = (harpoon.IR.Tree.CONST) expArg;
3580                                 _matched_ = true;
3581 
3582                                 if (_matched_) { // action code! degree: 1
3583 
3584 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3585 clearDecl();
3586 declare(i, code.getTreeDerivation(), ROOT);
3587 
3588     // the only CONST of type Pointer we should see is NULL
3589     assert c==null;
3590    emitLineDebugInfo(ROOT);
3591     emit( ROOT, "li `d0, 0   # null pointer", i);
3592                         return i;
3593                         }
3594                         }
3595                                  /* MEM<i,f,p,u:8,u:16,s:8,s:16>(e) */
3596                         if (true
3597                                 // check expression type
3598                                 && expArg instanceof harpoon.IR.Tree.MEM 
3599                                 // check operand types
3600                                 && ( 
3601                                         expArg.type() == Type.FLOAT ||
3602                                         expArg.type() == Type.POINTER ||
3603                                 (       expArg.type() == Type.INT && !
3604                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3605                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3606                                         (((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall() && (
3607                                          ((harpoon.IR.Tree.PreciselyTyped)expArg).signed() ? (
3608                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==8 ||
3609                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==16 ||
3610                                           false) : (
3611                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==8 ||
3612                                           ((harpoon.IR.Tree.PreciselyTyped)expArg).bitwidth()==16 ||
3613                                           false) ) ) ||
3614                                         false )
3615                                 // end check operand types
3616                                         // check child
3617                                         // no check needed for ExpId children
3618                         ){
3619                         harpoon.IR.Tree.MEM ROOT = (harpoon.IR.Tree.MEM) expArg;
3620                                 _matched_ = true;
3621 
3622                                 if (_matched_) { // action code! degree: 1
3623                                         harpoon.Temp.Temp e = munchExp(((harpoon.IR.Tree.MEM)expArg).getExp()); 
3624 
3625 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3626 clearDecl();
3627 declare(i, code.getTreeDerivation(), ROOT);
3628  
3629    String suffix = GetLdSuffix(ROOT);
3630    String usuffix = getDAOpcodeSuffix(ROOT);
3631    emitLineDebugInfo(ROOT);
3632 
3633    emit(new InstrMEM(instrFactory, ROOT,
3634                      "l"+suffix+usuffix+" `d0, 0(`s0)" + getDANum(ROOT),
3635                      new Temp[]{ i }, new Temp[]{ e }));   
3636                         return i;
3637                         }
3638                         }
3639                                  /* MEM<l,d>(e) */
3640                         if (true
3641                                 // check expression type
3642                                 && expArg instanceof harpoon.IR.Tree.MEM 
3643                                 // check operand types
3644                                 && ( 
3645                                         expArg.type() == Type.DOUBLE ||
3646                                         expArg.type() == Type.LONG ||
3647                                         false )
3648                                 // end check operand types
3649                                         // check child
3650                                         // no check needed for ExpId children
3651                         ){
3652                         harpoon.IR.Tree.MEM ROOT = (harpoon.IR.Tree.MEM) expArg;
3653                                 _matched_ = true;
3654 
3655                                 if (_matched_) { // action code! degree: 1
3656                                         harpoon.Temp.Temp e = munchExp(((harpoon.IR.Tree.MEM)expArg).getExp()); 
3657 
3658 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3659 clearDecl();
3660 declare(i, code.getTreeDerivation(), ROOT);
3661 
3662    String usuffix = getDAOpcodeSuffix(ROOT);
3663    emitLineDebugInfo(ROOT);
3664    emitRegAllocDef(ROOT, i);
3665 
3666    emit(new InstrMEM(instrFactory, ROOT,
3667                      "lw" + usuffix+ " `d0l, 4(`s0)" + getDANum(ROOT) + "\n"
3668                      + "lw" + usuffix + " `d0h, 0(`s0)" + getDANum(ROOT),
3669                      new Temp[]{ i }, new Temp[]{ e }));
3670    emitRegAllocUse(ROOT, e);
3671                         return i;
3672                         }
3673                         }
3674                                  /* NAME(id) */
3675                         if (true
3676                                 // check expression type
3677                                 && expArg instanceof harpoon.IR.Tree.NAME 
3678                         ){
3679                                 harpoon.Temp.Label id = ((harpoon.IR.Tree.NAME)expArg).label;
3680                         harpoon.IR.Tree.NAME ROOT = (harpoon.IR.Tree.NAME) expArg;
3681                                 _matched_ = true;
3682 
3683                                 if (_matched_) { // action code! degree: 1
3684 
3685 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3686 clearDecl();
3687 declare(i, code.getTreeDerivation(), ROOT);
3688 
3689    emitLineDebugInfo(ROOT);
3690    emit(new Instr( instrFactory, ROOT,
3691                    "la `d0, " + id, 
3692                    new Temp[]{ i }, null ));
3693                         return i;
3694                         }
3695                         }
3696                                  /* TEMP<i,l,f,d,p>(t) */
3697                         if (true
3698                                 // check expression type
3699                                 && expArg instanceof harpoon.IR.Tree.TEMP 
3700                                 // check operand types
3701                                 && ( 
3702                                         expArg.type() == Type.DOUBLE ||
3703                                         expArg.type() == Type.FLOAT ||
3704                                         expArg.type() == Type.LONG ||
3705                                         expArg.type() == Type.POINTER ||
3706                                 (       expArg.type() == Type.INT && !
3707                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3708                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3709                                         false )
3710                                 // end check operand types
3711                         ){
3712                                 harpoon.Temp.Temp t = makeTemp((harpoon.IR.Tree.TEMP)expArg, inf.tempFactory());
3713                         harpoon.IR.Tree.TEMP ROOT = (harpoon.IR.Tree.TEMP) expArg;
3714                                 _matched_ = true;
3715 
3716                                 if (_matched_) { // action code! degree: 1
3717 
3718 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3719 clearDecl();
3720 declare(i, code.getTreeDerivation(), ROOT);
3721  i=t; /* this case is basically handled entirely by the CGG */                  return i;
3722                         }
3723                         }
3724                                  /* UNOP<i,l,f,d,p>(I2B,arg) */
3725                         if (true
3726                                 // check expression type
3727                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3728                                 // check opcode
3729                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.I2B
3730                                 // check operand types
3731                                 && ( 
3732                                         expArg.type() == Type.DOUBLE ||
3733                                         expArg.type() == Type.FLOAT ||
3734                                         expArg.type() == Type.LONG ||
3735                                         expArg.type() == Type.POINTER ||
3736                                 (       expArg.type() == Type.INT && !
3737                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3738                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3739                                         false )
3740                                 // end check operand types
3741                                         // check child
3742                                         // no check needed for ExpId children
3743                         ){
3744                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
3745                                 _matched_ = true&& ( ROOT.operandType() == Type.INT );
3746 
3747                                 if (_matched_) { // action code! degree: 1
3748                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
3749 
3750 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3751 clearDecl();
3752 declare(i, code.getTreeDerivation(), ROOT);
3753 
3754    emitLineDebugInfo(ROOT);
3755     emit( ROOT, "sll `d0, `s0, 24", i, arg);
3756     emit( ROOT, "sra `d0, `s0, 24", i, i);
3757                         return i;
3758                         }
3759                         }
3760                                  /* UNOP<i,l,f,d,p>(I2S,arg) */
3761                         if (true
3762                                 // check expression type
3763                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3764                                 // check opcode
3765                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.I2S
3766                                 // check operand types
3767                                 && ( 
3768                                         expArg.type() == Type.DOUBLE ||
3769                                         expArg.type() == Type.FLOAT ||
3770                                         expArg.type() == Type.LONG ||
3771                                         expArg.type() == Type.POINTER ||
3772                                 (       expArg.type() == Type.INT && !
3773                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3774                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3775                                         false )
3776                                 // end check operand types
3777                                         // check child
3778                                         // no check needed for ExpId children
3779                         ){
3780                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
3781                                 _matched_ = true&& ( ROOT.operandType() == Type.INT );
3782 
3783                                 if (_matched_) { // action code! degree: 1
3784                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
3785 
3786 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3787 clearDecl();
3788 declare(i, code.getTreeDerivation(), ROOT);
3789 
3790    emitLineDebugInfo(ROOT);
3791     emit( ROOT, "sll `d0, `s0, 16", i, arg);
3792     emit( ROOT, "sra `d0, `s0, 16", i, i);
3793                         return i;
3794                         }
3795                         }
3796                                  /* UNOP<i,l,f,d,p>(I2C,arg) */
3797                         if (true
3798                                 // check expression type
3799                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3800                                 // check opcode
3801                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop.I2C
3802                                 // check operand types
3803                                 && ( 
3804                                         expArg.type() == Type.DOUBLE ||
3805                                         expArg.type() == Type.FLOAT ||
3806                                         expArg.type() == Type.LONG ||
3807                                         expArg.type() == Type.POINTER ||
3808                                 (       expArg.type() == Type.INT && !
3809                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3810                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3811                                         false )
3812                                 // end check operand types
3813                                         // check child
3814                                         // no check needed for ExpId children
3815                         ){
3816                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
3817                                 _matched_ = true&& ( ROOT.operandType() == Type.INT );
3818 
3819                                 if (_matched_) { // action code! degree: 1
3820                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
3821 
3822 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3823 clearDecl();
3824 declare(i, code.getTreeDerivation(), ROOT);
3825 
3826    emitLineDebugInfo(ROOT);
3827     emit( ROOT, "sll `d0, `s0, 16", i, arg);
3828     emit( ROOT, "srl `d0, `s0, 16", i, i);
3829                         return i;
3830                         }
3831                         }
3832                                  /* UNOP<i,l,f,d,p>(_2F,arg) */
3833                         if (true
3834                                 // check expression type
3835                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3836                                 // check opcode
3837                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2F
3838                                 // check operand types
3839                                 && ( 
3840                                         expArg.type() == Type.DOUBLE ||
3841                                         expArg.type() == Type.FLOAT ||
3842                                         expArg.type() == Type.LONG ||
3843                                         expArg.type() == Type.POINTER ||
3844                                 (       expArg.type() == Type.INT && !
3845                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3846                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3847                                         false )
3848                                 // end check operand types
3849                                         // check child
3850                                         // no check needed for ExpId children
3851                         ){
3852                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
3853                                 _matched_ = true&& ( ROOT.operandType() == Type.INT );
3854 
3855                                 if (_matched_) { // action code! degree: 1
3856                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
3857 
3858 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3859 clearDecl();
3860 declare(i, code.getTreeDerivation(), ROOT);
3861 
3862    emitLineDebugInfo(ROOT);
3863    DoFCall(ROOT, i, arg, "__i2f");
3864                         return i;
3865                         }
3866                         }
3867                                  /* UNOP<i,l,f,d,p>(_2D,arg) */
3868                         if (true
3869                                 // check expression type
3870                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3871                                 // check opcode
3872                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2D
3873                                 // check operand types
3874                                 && ( 
3875                                         expArg.type() == Type.DOUBLE ||
3876                                         expArg.type() == Type.FLOAT ||
3877                                         expArg.type() == Type.LONG ||
3878                                         expArg.type() == Type.POINTER ||
3879                                 (       expArg.type() == Type.INT && !
3880                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3881                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3882                                         false )
3883                                 // end check operand types
3884                                         // check child
3885                                         // no check needed for ExpId children
3886                         ){
3887                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
3888                                 _matched_ = true&& ( ROOT.operandType() == Type.INT );
3889 
3890                                 if (_matched_) { // action code! degree: 1
3891                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
3892 
3893 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3894 clearDecl();
3895 declare(i, code.getTreeDerivation(), ROOT);
3896 
3897    emitLineDebugInfo(ROOT);
3898    DoDCall(ROOT, i, arg, "__i2d");
3899                         return i;
3900                         }
3901                         }
3902                                  /* UNOP<i,l,f,d,p>(_2L,arg) */
3903                         if (true
3904                                 // check expression type
3905                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3906                                 // check opcode
3907                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2L
3908                                 // check operand types
3909                                 && ( 
3910                                         expArg.type() == Type.DOUBLE ||
3911                                         expArg.type() == Type.FLOAT ||
3912                                         expArg.type() == Type.LONG ||
3913                                         expArg.type() == Type.POINTER ||
3914                                 (       expArg.type() == Type.INT && !
3915                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3916                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3917                                         false )
3918                                 // end check operand types
3919                                         // check child
3920                                         // no check needed for ExpId children
3921                         ){
3922                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
3923                                 _matched_ = true&& ( ROOT.operandType() == Type.INT );
3924 
3925                                 if (_matched_) { // action code! degree: 1
3926                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
3927 
3928 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3929 clearDecl();
3930 declare(i, code.getTreeDerivation(), ROOT);
3931 
3932    emitLineDebugInfo(ROOT);
3933    emitRegAllocDef(ROOT, i);
3934    emit( ROOT, "move `d0l, `s0\n"
3935          + "sra `d0h, `s0, 31", i, arg );
3936    emitRegAllocUse(ROOT, arg);
3937                         return i;
3938                         }
3939                         }
3940                                  /* UNOP<i,l,f,d,p>(_2L,arg) */
3941                         if (true
3942                                 // check expression type
3943                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3944                                 // check opcode
3945                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2L
3946                                 // check operand types
3947                                 && ( 
3948                                         expArg.type() == Type.DOUBLE ||
3949                                         expArg.type() == Type.FLOAT ||
3950                                         expArg.type() == Type.LONG ||
3951                                         expArg.type() == Type.POINTER ||
3952                                 (       expArg.type() == Type.INT && !
3953                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
3954                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
3955                                         false )
3956                                 // end check operand types
3957                                         // check child
3958                                         // no check needed for ExpId children
3959                         ){
3960                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
3961                                 _matched_ = true&& ( ROOT.operandType() == Type.FLOAT );
3962 
3963                                 if (_matched_) { // action code! degree: 1
3964                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
3965 
3966 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
3967 clearDecl();
3968 declare(i, code.getTreeDerivation(), ROOT);
3969 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
3970         public int type() { return harpoon.IR.Tree.Type.INT; }
3971         public boolean isFloatingPoint() { return false; }
3972         public boolean isDoubleWord() { return false; }
3973 }, inf.tempFactory() );
3974 declare(extra, HClass.Int);
3975 
3976    emitLineDebugInfo(ROOT);
3977    DoFCall(ROOT, extra, arg, "__f2i");
3978    emitRegAllocDef(ROOT, i);
3979    emit( ROOT, "move `d0l, `s0\n"
3980          + "sra `d0h, `s0, 31", i, extra );
3981    emitRegAllocUse(ROOT, arg);
3982                         return i;
3983                         }
3984                         }
3985                                  /* UNOP<p>(_2I,arg) */
3986                         if (true
3987                                 // check expression type
3988                                 && expArg instanceof harpoon.IR.Tree.UNOP 
3989                                 // check opcode
3990                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2I
3991                                 // check operand types
3992                                 && ( 
3993                                         expArg.type() == Type.POINTER ||
3994                                         false )
3995                                 // end check operand types
3996                                         // check child
3997                                         // no check needed for ExpId children
3998                         ){
3999                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4000                                 _matched_ = true&& ( ROOT.operandType() == Type.POINTER );
4001 
4002                                 if (_matched_) { // action code! degree: 1
4003                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4004 
4005 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4006 clearDecl();
4007 declare(i, code.getTreeDerivation(), ROOT);
4008 
4009    emitLineDebugInfo(ROOT);
4010     emitMOVE( ROOT, "move `d0, `s0", i, arg );
4011                         return i;
4012                         }
4013                         }
4014                                  /* UNOP<i,l,f,d,p>(_2I,arg) */
4015                         if (true
4016                                 // check expression type
4017                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4018                                 // check opcode
4019                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2I
4020                                 // check operand types
4021                                 && ( 
4022                                         expArg.type() == Type.DOUBLE ||
4023                                         expArg.type() == Type.FLOAT ||
4024                                         expArg.type() == Type.LONG ||
4025                                         expArg.type() == Type.POINTER ||
4026                                 (       expArg.type() == Type.INT && !
4027                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4028                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4029                                         false )
4030                                 // end check operand types
4031                                         // check child
4032                                         // no check needed for ExpId children
4033                         ){
4034                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4035                                 _matched_ = true&& ( ROOT.operandType() == Type.LONG );
4036 
4037                                 if (_matched_) { // action code! degree: 1
4038                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4039 
4040 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4041 clearDecl();
4042 declare(i, code.getTreeDerivation(), ROOT);
4043 
4044    emitLineDebugInfo(ROOT);
4045    emit( ROOT, "move `d0, `s0l", i, arg );
4046                         return i;
4047                         }
4048                         }
4049                                  /* UNOP<i,l,f,d,p>(_2F,arg) */
4050                         if (true
4051                                 // check expression type
4052                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4053                                 // check opcode
4054                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2F
4055                                 // check operand types
4056                                 && ( 
4057                                         expArg.type() == Type.DOUBLE ||
4058                                         expArg.type() == Type.FLOAT ||
4059                                         expArg.type() == Type.LONG ||
4060                                         expArg.type() == Type.POINTER ||
4061                                 (       expArg.type() == Type.INT && !
4062                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4063                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4064                                         false )
4065                                 // end check operand types
4066                                         // check child
4067                                         // no check needed for ExpId children
4068                         ){
4069                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4070                                 _matched_ = true&& ( ROOT.operandType() == Type.LONG );
4071 
4072                                 if (_matched_) { // action code! degree: 1
4073                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4074 
4075 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4076 clearDecl();
4077 declare(i, code.getTreeDerivation(), ROOT);
4078 
4079    emitLineDebugInfo(ROOT);
4080    DoDCall(ROOT, i, arg, "__l2f");
4081                         return i;
4082                         }
4083                         }
4084                                  /* UNOP<i,l,f,d,p>(_2D,arg) */
4085                         if (true
4086                                 // check expression type
4087                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4088                                 // check opcode
4089                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2D
4090                                 // check operand types
4091                                 && ( 
4092                                         expArg.type() == Type.DOUBLE ||
4093                                         expArg.type() == Type.FLOAT ||
4094                                         expArg.type() == Type.LONG ||
4095                                         expArg.type() == Type.POINTER ||
4096                                 (       expArg.type() == Type.INT && !
4097                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4098                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4099                                         false )
4100                                 // end check operand types
4101                                         // check child
4102                                         // no check needed for ExpId children
4103                         ){
4104                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4105                                 _matched_ = true&& ( ROOT.operandType() == Type.LONG );
4106 
4107                                 if (_matched_) { // action code! degree: 1
4108                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4109 
4110 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4111 clearDecl();
4112 declare(i, code.getTreeDerivation(), ROOT);
4113 
4114    emitLineDebugInfo(ROOT);
4115    DoDCall(ROOT, i, arg, "__l2d");
4116                         return i;
4117                         }
4118                         }
4119                                  /* UNOP<i,l,f,d,p>(_2I,arg) */
4120                         if (true
4121                                 // check expression type
4122                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4123                                 // check opcode
4124                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2I
4125                                 // check operand types
4126                                 && ( 
4127                                         expArg.type() == Type.DOUBLE ||
4128                                         expArg.type() == Type.FLOAT ||
4129                                         expArg.type() == Type.LONG ||
4130                                         expArg.type() == Type.POINTER ||
4131                                 (       expArg.type() == Type.INT && !
4132                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4133                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4134                                         false )
4135                                 // end check operand types
4136                                         // check child
4137                                         // no check needed for ExpId children
4138                         ){
4139                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4140                                 _matched_ = true&& ( ROOT.operandType() == Type.FLOAT );
4141 
4142                                 if (_matched_) { // action code! degree: 1
4143                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4144 
4145 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4146 clearDecl();
4147 declare(i, code.getTreeDerivation(), ROOT);
4148 
4149    emitLineDebugInfo(ROOT);
4150    DoFCall(ROOT, i, arg, "__f2i");
4151                         return i;
4152                         }
4153                         }
4154                                  /* UNOP<i,l,f,d,p>(_2D,arg) */
4155                         if (true
4156                                 // check expression type
4157                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4158                                 // check opcode
4159                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2D
4160                                 // check operand types
4161                                 && ( 
4162                                         expArg.type() == Type.DOUBLE ||
4163                                         expArg.type() == Type.FLOAT ||
4164                                         expArg.type() == Type.LONG ||
4165                                         expArg.type() == Type.POINTER ||
4166                                 (       expArg.type() == Type.INT && !
4167                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4168                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4169                                         false )
4170                                 // end check operand types
4171                                         // check child
4172                                         // no check needed for ExpId children
4173                         ){
4174                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4175                                 _matched_ = true&& ( ROOT.operandType() == Type.FLOAT );
4176 
4177                                 if (_matched_) { // action code! degree: 1
4178                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4179 
4180 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4181 clearDecl();
4182 declare(i, code.getTreeDerivation(), ROOT);
4183 
4184    emitLineDebugInfo(ROOT);
4185    DoDCall(ROOT, i, arg, "__f2d");
4186                         return i;
4187                         }
4188                         }
4189                                  /* UNOP<i,l,f,d,p>(_2I,arg) */
4190                         if (true
4191                                 // check expression type
4192                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4193                                 // check opcode
4194                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2I
4195                                 // check operand types
4196                                 && ( 
4197                                         expArg.type() == Type.DOUBLE ||
4198                                         expArg.type() == Type.FLOAT ||
4199                                         expArg.type() == Type.LONG ||
4200                                         expArg.type() == Type.POINTER ||
4201                                 (       expArg.type() == Type.INT && !
4202                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4203                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4204                                         false )
4205                                 // end check operand types
4206                                         // check child
4207                                         // no check needed for ExpId children
4208                         ){
4209                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4210                                 _matched_ = true&& ( ROOT.operandType() == Type.DOUBLE );
4211 
4212                                 if (_matched_) { // action code! degree: 1
4213                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4214 
4215 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4216 clearDecl();
4217 declare(i, code.getTreeDerivation(), ROOT);
4218 
4219    emitLineDebugInfo(ROOT);
4220    DoDCall(ROOT, i, arg, "__d2i");
4221                         return i;
4222                         }
4223                         }
4224                                  /* UNOP<i,l,f,d,p>(_2F,arg) */
4225                         if (true
4226                                 // check expression type
4227                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4228                                 // check opcode
4229                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2F
4230                                 // check operand types
4231                                 && ( 
4232                                         expArg.type() == Type.DOUBLE ||
4233                                         expArg.type() == Type.FLOAT ||
4234                                         expArg.type() == Type.LONG ||
4235                                         expArg.type() == Type.POINTER ||
4236                                 (       expArg.type() == Type.INT && !
4237                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4238                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4239                                         false )
4240                                 // end check operand types
4241                                         // check child
4242                                         // no check needed for ExpId children
4243                         ){
4244                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4245                                 _matched_ = true&& ( ROOT.operandType() == Type.DOUBLE );
4246 
4247                                 if (_matched_) { // action code! degree: 1
4248                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4249 
4250 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4251 clearDecl();
4252 declare(i, code.getTreeDerivation(), ROOT);
4253 
4254    emitLineDebugInfo(ROOT);
4255    DoDCall(ROOT, i, arg, "__d2f");
4256                         return i;
4257                         }
4258                         }
4259                                  /* UNOP<i,l,f,d,p>(_2L,arg) */
4260                         if (true
4261                                 // check expression type
4262                                 && expArg instanceof harpoon.IR.Tree.UNOP 
4263                                 // check opcode
4264                                 && ((harpoon.IR.Tree.UNOP)expArg).op == harpoon.IR.Tree.Uop._2L
4265                                 // check operand types
4266                                 && ( 
4267                                         expArg.type() == Type.DOUBLE ||
4268                                         expArg.type() == Type.FLOAT ||
4269                                         expArg.type() == Type.LONG ||
4270                                         expArg.type() == Type.POINTER ||
4271                                 (       expArg.type() == Type.INT && !
4272                                  (expArg instanceof harpoon.IR.Tree.PreciselyTyped &&
4273                                   ((harpoon.IR.Tree.PreciselyTyped)expArg).isSmall())) ||
4274                                         false )
4275                                 // end check operand types
4276                                         // check child
4277                                         // no check needed for ExpId children
4278                         ){
4279                         harpoon.IR.Tree.UNOP ROOT = (harpoon.IR.Tree.UNOP) expArg;
4280                                 _matched_ = true&& ( ROOT.operandType() == Type.DOUBLE );
4281 
4282                                 if (_matched_) { // action code! degree: 1
4283                                         harpoon.Temp.Temp arg = munchExp(((harpoon.IR.Tree.UNOP)expArg).getOperand()); 
4284 
4285 Temp i = frame.getTempBuilder().makeTemp( ROOT , inf.tempFactory());
4286 clearDecl();
4287 declare(i, code.getTreeDerivation(), ROOT);
4288 
4289    emitLineDebugInfo(ROOT);
4290    DoDCall(ROOT, i, arg, "__d2l");
4291                         return i;
4292                         }
4293                         }
4294                 assert false : "Uh oh...\nmaximal munch didn't match anything...SPEC file\nis not complete enough for this program\nDied on "+prettyPrint(expArg)+" in " + prettyPrint(globalStmArg);
4295                 return null; // doesn't matter, we're dead if we didn't match...
4296                  } // end munchExp
4297         harpoon.IR.Tree.Stm globalStmArg=null;
4298                  void munchStm(harpoon.IR.Tree.Stm stmArg) {
4299                          globalStmArg = stmArg;
4300                         boolean _matched_ = false;
4301                         clearDecl(); // reset temp type mappings
4302                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(BINOP<p>(ADD,CONST<i,p>(c),j)),NAME(src)) */
4303                         if (true
4304                                 // check statement type
4305                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4306                                 // check operand types
4307                                 && ( 
4308                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4309                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4310                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4311                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4312                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4313                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4314                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4315                                         false )
4316                                 // end check operand types
4317                                                                 && (true
4318                                         // check expression type
4319                                         && ((harpoon.IR.Tree.MOVE) stmArg).getSrc() instanceof harpoon.IR.Tree.NAME 
4320                                 )
4321                                 && (true
4322                                         // check expression type
4323                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4324                                         // check operand types
4325                                         && ( 
4326                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4327                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4328                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4329                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4330                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4331                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4332                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4333                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4334                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4335                                                   false) : (
4336                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4337                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4338                                                   false) ) ) ||
4339                                                 false )
4340                                         // end check operand types
4341                                                 // check child
4342                                                 // check expression type
4343                                                 && ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp() instanceof harpoon.IR.Tree.BINOP
4344                                                 // check opcode
4345                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).op == harpoon.IR.Tree.Bop.ADD
4346                                                 // check operand types
4347                                                 && ( 
4348                                                         ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp().type() == Type.POINTER ||
4349                                                         false )
4350                                                 // end check operand types
4351                                                         // check left child
4352                                                         // check expression type
4353                                                         && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft() instanceof harpoon.IR.Tree.CONST 
4354                                                         // check operand types
4355                                                         && ( 
4356                                                                 ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft().type() == Type.POINTER ||
4357                                                         (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft().type() == Type.INT && !
4358                                                          (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft() instanceof harpoon.IR.Tree.PreciselyTyped &&
4359                                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft()).isSmall())) ||
4360                                                                 false )
4361                                                         // end check operand types
4362                                                         // check right child
4363                                                         // no check needed for ExpId children
4364                                 )
4365                         ){
4366                                         harpoon.Temp.Label src = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MOVE) stmArg).getSrc()).label;
4367                                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft()).value;
4368                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4369                                 _matched_ = true;
4370 
4371                                 if (_matched_) { // action code! : degree 5
4372                                                                                 harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight()); 
4373 
4374 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
4375         public int type() { return harpoon.IR.Tree.Type.POINTER; }
4376         public boolean isFloatingPoint() { return false; }
4377         public boolean isDoubleWord() { return frame.pointersAreLong(); }
4378 }, inf.tempFactory() );
4379                          
4380    String suffix = GetStSuffix(ROOT);
4381    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4382    emitLineDebugInfo(ROOT);
4383    declare( extra, HClass.Void );
4384    emit(new Instr( instrFactory, ROOT,
4385                    "la `d0, " + src,
4386                    new Temp[]{ extra }, null ));
4387    emit(new InstrMEM(instrFactory, ROOT, "s" + suffix +usuffix+" `s0, "
4388                      + c + "(`s1)"+ getDANum(ROOT.getDst()) +"     # tmp + c <= NAME(src) ",
4389                      null, new Temp[]{ extra, j }));
4390                         return;                 }
4391                         }
4392                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(BINOP<p>(ADD,j,CONST<i,p>(c))),NAME(src)) */
4393                         if (true
4394                                 // check statement type
4395                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4396                                 // check operand types
4397                                 && ( 
4398                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4399                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4400                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4401                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4402                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4403                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4404                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4405                                         false )
4406                                 // end check operand types
4407                                                                 && (true
4408                                         // check expression type
4409                                         && ((harpoon.IR.Tree.MOVE) stmArg).getSrc() instanceof harpoon.IR.Tree.NAME 
4410                                 )
4411                                 && (true
4412                                         // check expression type
4413                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4414                                         // check operand types
4415                                         && ( 
4416                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4417                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4418                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4419                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4420                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4421                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4422                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4423                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4424                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4425                                                   false) : (
4426                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4427                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4428                                                   false) ) ) ||
4429                                                 false )
4430                                         // end check operand types
4431                                                 // check child
4432                                                 // check expression type
4433                                                 && ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp() instanceof harpoon.IR.Tree.BINOP
4434                                                 // check opcode
4435                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).op == harpoon.IR.Tree.Bop.ADD
4436                                                 // check operand types
4437                                                 && ( 
4438                                                         ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp().type() == Type.POINTER ||
4439                                                         false )
4440                                                 // end check operand types
4441                                                         // check left child
4442                                                         // no check needed for ExpId children
4443                                                         // check right child
4444                                                         // check expression type
4445                                                         && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight() instanceof harpoon.IR.Tree.CONST 
4446                                                         // check operand types
4447                                                         && ( 
4448                                                                 ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight().type() == Type.POINTER ||
4449                                                         (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight().type() == Type.INT && !
4450                                                          (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
4451                                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight()).isSmall())) ||
4452                                                                 false )
4453                                                         // end check operand types
4454                                 )
4455                         ){
4456                                         harpoon.Temp.Label src = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MOVE) stmArg).getSrc()).label;
4457                                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight()).value;
4458                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4459                                 _matched_ = true;
4460 
4461                                 if (_matched_) { // action code! : degree 5
4462                                                                                 harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft()); 
4463 
4464 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
4465         public int type() { return harpoon.IR.Tree.Type.POINTER; }
4466         public boolean isFloatingPoint() { return false; }
4467         public boolean isDoubleWord() { return frame.pointersAreLong(); }
4468 }, inf.tempFactory() );
4469                          
4470    String suffix = GetStSuffix(ROOT);
4471    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4472    emitLineDebugInfo(ROOT);
4473    declare( extra, HClass.Void );
4474    emit(new Instr( instrFactory, ROOT,
4475                    "la `d0, " + src,
4476                    new Temp[]{ extra }, null ));
4477    emit(new InstrMEM(instrFactory, ROOT, "s" + suffix +usuffix+" `s0, "
4478                      + c + "(`s1)"+ getDANum(ROOT.getDst()) +"     # tmp + c <= NAME(src) ",
4479                      null, new Temp[]{ extra, j }));
4480                         return;                 }
4481                         }
4482                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(BINOP<p>(ADD,CONST<i,p>(c),j)),src) */
4483                         if (true
4484                                 // check statement type
4485                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4486                                 // check operand types
4487                                 && ( 
4488                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4489                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4490                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4491                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4492                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4493                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4494                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4495                                         false )
4496                                 // end check operand types
4497                                                                 && (true
4498                                         // no check needed for ExpId children
4499                                 )
4500                                 && (true
4501                                         // check expression type
4502                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4503                                         // check operand types
4504                                         && ( 
4505                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4506                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4507                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4508                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4509                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4510                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4511                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4512                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4513                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4514                                                   false) : (
4515                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4516                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4517                                                   false) ) ) ||
4518                                                 false )
4519                                         // end check operand types
4520                                                 // check child
4521                                                 // check expression type
4522                                                 && ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp() instanceof harpoon.IR.Tree.BINOP
4523                                                 // check opcode
4524                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).op == harpoon.IR.Tree.Bop.ADD
4525                                                 // check operand types
4526                                                 && ( 
4527                                                         ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp().type() == Type.POINTER ||
4528                                                         false )
4529                                                 // end check operand types
4530                                                         // check left child
4531                                                         // check expression type
4532                                                         && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft() instanceof harpoon.IR.Tree.CONST 
4533                                                         // check operand types
4534                                                         && ( 
4535                                                                 ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft().type() == Type.POINTER ||
4536                                                         (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft().type() == Type.INT && !
4537                                                          (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft() instanceof harpoon.IR.Tree.PreciselyTyped &&
4538                                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft()).isSmall())) ||
4539                                                                 false )
4540                                                         // end check operand types
4541                                                         // check right child
4542                                                         // no check needed for ExpId children
4543                                 )
4544                         ){
4545                                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft()).value;
4546                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4547                                 _matched_ = true;
4548 
4549                                 if (_matched_) { // action code! : degree 4
4550                                                                 harpoon.Temp.Temp src = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getSrc()); 
4551                                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight()); 
4552 
4553                          
4554    String suffix = GetStSuffix(ROOT);
4555    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4556    emitLineDebugInfo(ROOT);
4557 
4558    emit(new InstrMEM(instrFactory, ROOT,
4559                       "s"+suffix+usuffix+" `s0, "+c+"(`s1)" + getDANum(ROOT.getDst()),
4560                       null, new Temp[]{ src, j }));   
4561                         return;                 }
4562                         }
4563                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(BINOP<p>(ADD,j,CONST<i,p>(c))),src) */
4564                         if (true
4565                                 // check statement type
4566                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4567                                 // check operand types
4568                                 && ( 
4569                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4570                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4571                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4572                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4573                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4574                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4575                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4576                                         false )
4577                                 // end check operand types
4578                                                                 && (true
4579                                         // no check needed for ExpId children
4580                                 )
4581                                 && (true
4582                                         // check expression type
4583                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4584                                         // check operand types
4585                                         && ( 
4586                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4587                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4588                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4589                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4590                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4591                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4592                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4593                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4594                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4595                                                   false) : (
4596                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4597                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4598                                                   false) ) ) ||
4599                                                 false )
4600                                         // end check operand types
4601                                                 // check child
4602                                                 // check expression type
4603                                                 && ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp() instanceof harpoon.IR.Tree.BINOP
4604                                                 // check opcode
4605                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).op == harpoon.IR.Tree.Bop.ADD
4606                                                 // check operand types
4607                                                 && ( 
4608                                                         ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp().type() == Type.POINTER ||
4609                                                         false )
4610                                                 // end check operand types
4611                                                         // check left child
4612                                                         // no check needed for ExpId children
4613                                                         // check right child
4614                                                         // check expression type
4615                                                         && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight() instanceof harpoon.IR.Tree.CONST 
4616                                                         // check operand types
4617                                                         && ( 
4618                                                                 ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight().type() == Type.POINTER ||
4619                                                         (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight().type() == Type.INT && !
4620                                                          (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
4621                                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight()).isSmall())) ||
4622                                                                 false )
4623                                                         // end check operand types
4624                                 )
4625                         ){
4626                                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getRight()).value;
4627                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4628                                 _matched_ = true;
4629 
4630                                 if (_matched_) { // action code! : degree 4
4631                                                                 harpoon.Temp.Temp src = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getSrc()); 
4632                                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).getLeft()); 
4633 
4634                          
4635    String suffix = GetStSuffix(ROOT);
4636    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4637    emitLineDebugInfo(ROOT);
4638 
4639    emit(new InstrMEM(instrFactory, ROOT,
4640                       "s"+suffix+usuffix+" `s0, "+c+"(`s1)" + getDANum(ROOT.getDst()),
4641                       null, new Temp[]{ src, j }));   
4642                         return;                 }
4643                         }
4644                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(NAME(dst)),NAME(src)) */
4645                         if (true
4646                                 // check statement type
4647                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4648                                 // check operand types
4649                                 && ( 
4650                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4651                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4652                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4653                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4654                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4655                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4656                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4657                                         false )
4658                                 // end check operand types
4659                                                                 && (true
4660                                         // check expression type
4661                                         && ((harpoon.IR.Tree.MOVE) stmArg).getSrc() instanceof harpoon.IR.Tree.NAME 
4662                                 )
4663                                 && (true
4664                                         // check expression type
4665                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4666                                         // check operand types
4667                                         && ( 
4668                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4669                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4670                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4671                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4672                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4673                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4674                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4675                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4676                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4677                                                   false) : (
4678                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4679                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4680                                                   false) ) ) ||
4681                                                 false )
4682                                         // end check operand types
4683                                                 // check child
4684                                                 // check expression type
4685                                                 && ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp() instanceof harpoon.IR.Tree.NAME 
4686                                 )
4687                         ){
4688                                         harpoon.Temp.Label src = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MOVE) stmArg).getSrc()).label;
4689                                                 harpoon.Temp.Label dst = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).label;
4690                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4691                                 _matched_ = true;
4692 
4693                                 if (_matched_) { // action code! : degree 4
4694                         
4695 Temp extra0 = frame.getTempBuilder().makeTemp(new Typed() {
4696         public int type() { return harpoon.IR.Tree.Type.POINTER; }
4697         public boolean isFloatingPoint() { return false; }
4698         public boolean isDoubleWord() { return frame.pointersAreLong(); }
4699 }, inf.tempFactory() );
4700 Temp extra1 = frame.getTempBuilder().makeTemp(new Typed() {
4701         public int type() { return harpoon.IR.Tree.Type.POINTER; }
4702         public boolean isFloatingPoint() { return false; }
4703         public boolean isDoubleWord() { return frame.pointersAreLong(); }
4704 }, inf.tempFactory() );
4705                          
4706    String suffix = GetStSuffix(ROOT);
4707    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4708    emitLineDebugInfo(ROOT);
4709    declare( extra0, HClass.Void );
4710    declare( extra1, HClass.Void );
4711    emit(ROOT, "la `d0, " + src, extra0);
4712    emit(ROOT, "la `d0, " + dst, extra1);
4713    emit(new InstrMEM(instrFactory, ROOT, "s" + suffix + usuffix 
4714                      + " `s0, (`s1)" + getDANum(ROOT.getDst()), 
4715                      null, new Temp[] {extra0, extra1}));
4716                         return;                 }
4717                         }
4718                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(NAME(dst)),CONST<i,p>(c)) */
4719                         if (true
4720                                 // check statement type
4721                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4722                                 // check operand types
4723                                 && ( 
4724                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4725                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4726                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4727                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4728                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4729                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4730                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4731                                         false )
4732                                 // end check operand types
4733                                                                 && (true
4734                                         // check expression type
4735                                         && ((harpoon.IR.Tree.MOVE) stmArg).getSrc() instanceof harpoon.IR.Tree.CONST 
4736                                         // check operand types
4737                                         && ( 
4738                                                 ((harpoon.IR.Tree.MOVE) stmArg).getSrc().type() == Type.POINTER ||
4739                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getSrc().type() == Type.INT && !
4740                                          (((harpoon.IR.Tree.MOVE) stmArg).getSrc() instanceof harpoon.IR.Tree.PreciselyTyped &&
4741                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getSrc()).isSmall())) ||
4742                                                 false )
4743                                         // end check operand types
4744                                 )
4745                                 && (true
4746                                         // check expression type
4747                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4748                                         // check operand types
4749                                         && ( 
4750                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4751                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4752                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4753                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4754                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4755                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4756                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4757                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4758                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4759                                                   false) : (
4760                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4761                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4762                                                   false) ) ) ||
4763                                                 false )
4764                                         // end check operand types
4765                                                 // check child
4766                                                 // check expression type
4767                                                 && ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp() instanceof harpoon.IR.Tree.NAME 
4768                                 )
4769                         ){
4770                                         Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.MOVE) stmArg).getSrc()).value;
4771                                                 harpoon.Temp.Label dst = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).label;
4772                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4773                                 _matched_ = true;
4774 
4775                                 if (_matched_) { // action code! : degree 4
4776                         
4777 Temp extra0 = frame.getTempBuilder().makeTemp(new Typed() {
4778         public int type() { return harpoon.IR.Tree.Type.INT; }
4779         public boolean isFloatingPoint() { return false; }
4780         public boolean isDoubleWord() { return false; }
4781 }, inf.tempFactory() );
4782 declare(extra0, HClass.Int);
4783 Temp extra1 = frame.getTempBuilder().makeTemp(new Typed() {
4784         public int type() { return harpoon.IR.Tree.Type.INT; }
4785         public boolean isFloatingPoint() { return false; }
4786         public boolean isDoubleWord() { return false; }
4787 }, inf.tempFactory() );
4788 declare(extra1, HClass.Int);
4789                          
4790    emitLineDebugInfo(ROOT);
4791    String suffix = GetStSuffix(ROOT);
4792    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4793    if(c==null) {
4794       emit(ROOT, "li `d0, 0", extra0);
4795    } else {
4796       emit(ROOT, "li `d0, " + c, extra0);
4797    }
4798    emit(ROOT, "la `d0, " + dst, extra1);
4799    emit(new InstrMEM(instrFactory, ROOT, 
4800                      "s" + suffix + usuffix + " `s0, (`s1)"
4801                      + getDANum(ROOT.getDst()) + "      # NAME(dst) <= CONST",
4802                      null, new Temp[] { extra0, extra1 }));
4803                         return;                 }
4804                         }
4805                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(dst),NAME(src)) */
4806                         if (true
4807                                 // check statement type
4808                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4809                                 // check operand types
4810                                 && ( 
4811                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4812                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4813                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4814                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4815                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4816                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4817                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4818                                         false )
4819                                 // end check operand types
4820                                                                 && (true
4821                                         // check expression type
4822                                         && ((harpoon.IR.Tree.MOVE) stmArg).getSrc() instanceof harpoon.IR.Tree.NAME 
4823                                 )
4824                                 && (true
4825                                         // check expression type
4826                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4827                                         // check operand types
4828                                         && ( 
4829                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4830                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4831                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4832                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4833                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4834                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4835                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4836                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4837                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4838                                                   false) : (
4839                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4840                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4841                                                   false) ) ) ||
4842                                                 false )
4843                                         // end check operand types
4844                                                 // check child
4845                                                 // no check needed for ExpId children
4846                                 )
4847                         ){
4848                                         harpoon.Temp.Label src = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MOVE) stmArg).getSrc()).label;
4849                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4850                                 _matched_ = true;
4851 
4852                                 if (_matched_) { // action code! : degree 3
4853                                                                         harpoon.Temp.Temp dst = munchExp(((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()); 
4854 
4855 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
4856         public int type() { return harpoon.IR.Tree.Type.POINTER; }
4857         public boolean isFloatingPoint() { return false; }
4858         public boolean isDoubleWord() { return frame.pointersAreLong(); }
4859 }, inf.tempFactory() );
4860                          
4861    String suffix = GetStSuffix(ROOT);
4862    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4863    emitLineDebugInfo(ROOT);
4864    declare( extra, HClass.Void );
4865    emit(new Instr( instrFactory, ROOT,
4866                    "la `d0, " + src,
4867                    new Temp[]{ extra }, null ));
4868    emit(new InstrMEM(instrFactory, ROOT, "s" + suffix + usuffix
4869                      +" `s0, (`s1)" + getDANum(ROOT.getDst()) + "        # dst <= NAME(src)",
4870                      null, new Temp[] {extra, dst}));
4871                         return;                 }
4872                         }
4873                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(NAME(dst)),src) */
4874                         if (true
4875                                 // check statement type
4876                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
4877                                 // check operand types
4878                                 && ( 
4879                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
4880                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
4881                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
4882                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
4883                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
4884                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
4885                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
4886                                         false )
4887                                 // end check operand types
4888                                                                 && (true
4889                                         // no check needed for ExpId children
4890                                 )
4891                                 && (true
4892                                         // check expression type
4893                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
4894                                         // check operand types
4895                                         && ( 
4896                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
4897                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
4898                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
4899                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
4900                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
4901                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
4902                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
4903                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4904                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4905                                                   false) : (
4906                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
4907                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
4908                                                   false) ) ) ||
4909                                                 false )
4910                                         // end check operand types
4911                                                 // check child
4912                                                 // check expression type
4913                                                 && ((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp() instanceof harpoon.IR.Tree.NAME 
4914                                 )
4915                         ){
4916                                                 harpoon.Temp.Label dst = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()).label;
4917                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
4918                                 _matched_ = true;
4919 
4920                                 if (_matched_) { // action code! : degree 3
4921                                                                 harpoon.Temp.Temp src = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getSrc()); 
4922 
4923 Temp extra = frame.getTempBuilder().makeTemp(new Typed() {
4924         public int type() { return harpoon.IR.Tree.Type.POINTER; }
4925         public boolean isFloatingPoint() { return false; }
4926         public boolean isDoubleWord() { return frame.pointersAreLong(); }
4927 }, inf.tempFactory() );
4928                          
4929    String suffix = GetStSuffix(ROOT);
4930    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
4931    declare( extra, HClass.Void );
4932    emitLineDebugInfo(ROOT);
4933    emit(new Instr( instrFactory, ROOT,
4934                    "la `d0, " + dst,
4935                    new Temp[]{ extra }, null ));
4936    emit(new InstrMEM(instrFactory, ROOT, "s" + suffix + usuffix
4937                      +" `s0, (`s1)" + getDANum(ROOT.getDst()) 
4938                      + "        # NAME(dst) <= src ",
4939                      null, new Temp[] {src, extra}));
4940                         return;                 }
4941                         }
4942                                  /* CJUMP(BINOP<i,l,f,d,p>(cmpop,CONST<i,p>(c),j),iftrue,iffalse) */
4943                         if (true
4944                                 // check statement type
4945                                 && (stmArg instanceof harpoon.IR.Tree.CJUMP)
4946                                 && (true
4947                                         // check expression type
4948                                         && ((harpoon.IR.Tree.CJUMP) stmArg).getTest() instanceof harpoon.IR.Tree.BINOP
4949                                         // check operand types
4950                                         && ( 
4951                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.DOUBLE ||
4952                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.FLOAT ||
4953                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.LONG ||
4954                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.POINTER ||
4955                                         (       ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.INT && !
4956                                          (((harpoon.IR.Tree.CJUMP) stmArg).getTest() instanceof harpoon.IR.Tree.PreciselyTyped &&
4957                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).isSmall())) ||
4958                                                 false )
4959                                         // end check operand types
4960                                                 // check left child
4961                                                 // check expression type
4962                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft() instanceof harpoon.IR.Tree.CONST 
4963                                                 // check operand types
4964                                                 && ( 
4965                                                         ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft().type() == Type.POINTER ||
4966                                                 (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft().type() == Type.INT && !
4967                                                  (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft() instanceof harpoon.IR.Tree.PreciselyTyped &&
4968                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft()).isSmall())) ||
4969                                                         false )
4970                                                 // end check operand types
4971                                                 // check right child
4972                                                 // no check needed for ExpId children
4973                                 )
4974                         ){
4975                                         int cmpop = ((harpoon.IR.Tree.BINOP) ((harpoon.IR.Tree.CJUMP) stmArg).getTest()).op;
4976                                                 Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft()).value;
4977                                 harpoon.Temp.Label iffalse = ((harpoon.IR.Tree.CJUMP)stmArg).iffalse;
4978                                 harpoon.Temp.Label iftrue = ((harpoon.IR.Tree.CJUMP)stmArg).iftrue;
4979                         harpoon.IR.Tree.CJUMP ROOT = (harpoon.IR.Tree.CJUMP) stmArg;
4980                                 _matched_ = true&& ((__CommExp__isCommutative(cmpop=__CommExp__swapCmpOp(cmpop))) && ( isCmpOp(cmpop) ));
4981 
4982                                 if (_matched_) { // action code! : degree 3
4983                                                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight()); 
4984 
4985                         
4986    emitLineDebugInfo(ROOT);
4987    assert ((BINOP) ROOT.getTest()).operandType()!=Type.POINTER ||
4988                c == null : "Can not compare a pointer to anything but null\n";
4989    if(((BINOP) ROOT.getTest()).operandType() == Type.POINTER &&
4990       c == null) { 
4991       emit( ROOT, cmpOp2BrStr(cmpop) + " `s0, $0, `L0 # null",
4992             null, new Temp[] { j }, new Label[] { iftrue });
4993    } else {
4994       emit( ROOT, cmpOp2BrStr(cmpop) + " `s0, " + c + ", `L0 ",
4995             null, new Temp[] { j }, new Label[] { iftrue });
4996    }
4997    emitJUMP( ROOT, "b `L0", iffalse );
4998                         return;                 }
4999                         }
5000                                  /* CJUMP(BINOP<i,l,f,d,p>(cmpop,j,CONST<i,p>(c)),iftrue,iffalse) */
5001                         if (true
5002                                 // check statement type
5003                                 && (stmArg instanceof harpoon.IR.Tree.CJUMP)
5004                                 && (true
5005                                         // check expression type
5006                                         && ((harpoon.IR.Tree.CJUMP) stmArg).getTest() instanceof harpoon.IR.Tree.BINOP
5007                                         // check operand types
5008                                         && ( 
5009                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.DOUBLE ||
5010                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.FLOAT ||
5011                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.LONG ||
5012                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.POINTER ||
5013                                         (       ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.INT && !
5014                                          (((harpoon.IR.Tree.CJUMP) stmArg).getTest() instanceof harpoon.IR.Tree.PreciselyTyped &&
5015                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).isSmall())) ||
5016                                                 false )
5017                                         // end check operand types
5018                                                 // check left child
5019                                                 // no check needed for ExpId children
5020                                                 // check right child
5021                                                 // check expression type
5022                                                 && ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight() instanceof harpoon.IR.Tree.CONST 
5023                                                 // check operand types
5024                                                 && ( 
5025                                                         ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight().type() == Type.POINTER ||
5026                                                 (       ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight().type() == Type.INT && !
5027                                                  (((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight() instanceof harpoon.IR.Tree.PreciselyTyped &&
5028                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight()).isSmall())) ||
5029                                                         false )
5030                                                 // end check operand types
5031                                 )
5032                         ){
5033                                         int cmpop = ((harpoon.IR.Tree.BINOP) ((harpoon.IR.Tree.CJUMP) stmArg).getTest()).op;
5034                                                 Number c = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight()).value;
5035                                 harpoon.Temp.Label iffalse = ((harpoon.IR.Tree.CJUMP)stmArg).iffalse;
5036                                 harpoon.Temp.Label iftrue = ((harpoon.IR.Tree.CJUMP)stmArg).iftrue;
5037                         harpoon.IR.Tree.CJUMP ROOT = (harpoon.IR.Tree.CJUMP) stmArg;
5038                                 _matched_ = true&& ( isCmpOp(cmpop) );
5039 
5040                                 if (_matched_) { // action code! : degree 3
5041                                                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft()); 
5042 
5043                         
5044    emitLineDebugInfo(ROOT);
5045    assert ((BINOP) ROOT.getTest()).operandType()!=Type.POINTER ||
5046                c == null : "Can not compare a pointer to anything but null\n";
5047    if(((BINOP) ROOT.getTest()).operandType() == Type.POINTER &&
5048       c == null) { 
5049       emit( ROOT, cmpOp2BrStr(cmpop) + " `s0, $0, `L0 # null",
5050             null, new Temp[] { j }, new Label[] { iftrue });
5051    } else {
5052       emit( ROOT, cmpOp2BrStr(cmpop) + " `s0, " + c + ", `L0 ",
5053             null, new Temp[] { j }, new Label[] { iftrue });
5054    }
5055    emitJUMP( ROOT, "b `L0", iffalse );
5056                         return;                 }
5057                         }
5058                                  /* MOVE<i,l,f,d,p>(MEM<i,f,p,u:8,u:16,s:8,s:16>(dst),src) */
5059                         if (true
5060                                 // check statement type
5061                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
5062                                 // check operand types
5063                                 && ( 
5064                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
5065                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
5066                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
5067                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
5068                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
5069                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
5070                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
5071                                         false )
5072                                 // end check operand types
5073                                                                 && (true
5074                                         // no check needed for ExpId children
5075                                 )
5076                                 && (true
5077                                         // check expression type
5078                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
5079                                         // check operand types
5080                                         && ( 
5081                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
5082                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
5083                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
5084                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
5085                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
5086                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall() && (
5087                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).signed() ? (
5088                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
5089                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
5090                                                   false) : (
5091                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==8 ||
5092                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).bitwidth()==16 ||
5093                                                   false) ) ) ||
5094                                                 false )
5095                                         // end check operand types
5096                                                 // check child
5097                                                 // no check needed for ExpId children
5098                                 )
5099                         ){
5100                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
5101                                 _matched_ = true;
5102 
5103                                 if (_matched_) { // action code! : degree 2
5104                                                                 harpoon.Temp.Temp src = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getSrc()); 
5105                                                 harpoon.Temp.Temp dst = munchExp(((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()); 
5106 
5107                         
5108    String suffix = GetStSuffix(ROOT);
5109    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
5110    emitLineDebugInfo(ROOT);
5111 
5112    emit(new InstrMEM(instrFactory, ROOT, 
5113                      "s" + suffix + usuffix+" `s0, 0(`s1)" + getDANum(ROOT.getDst()),
5114                      null, new Temp[] {src, dst}));
5115                         return;                 }
5116                         }
5117                                  /* MOVE<i,l,f,d,p>(MEM<l,d>(dst),src) */
5118                         if (true
5119                                 // check statement type
5120                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
5121                                 // check operand types
5122                                 && ( 
5123                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
5124                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
5125                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
5126                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
5127                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
5128                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
5129                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
5130                                         false )
5131                                 // end check operand types
5132                                                                 && (true
5133                                         // no check needed for ExpId children
5134                                 )
5135                                 && (true
5136                                         // check expression type
5137                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.MEM 
5138                                         // check operand types
5139                                         && ( 
5140                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.DOUBLE ||
5141                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.LONG ||
5142                                                 false )
5143                                         // end check operand types
5144                                                 // check child
5145                                                 // no check needed for ExpId children
5146                                 )
5147                         ){
5148                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
5149                                 _matched_ = true;
5150 
5151                                 if (_matched_) { // action code! : degree 2
5152                                                                 harpoon.Temp.Temp src = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getSrc()); 
5153                                                 harpoon.Temp.Temp dst = munchExp(((harpoon.IR.Tree.MEM)((harpoon.IR.Tree.MOVE) stmArg).getDst()).getExp()); 
5154 
5155                         
5156    emitLineDebugInfo(ROOT);
5157    String suffix = "";
5158    String usuffix = getDAOpcodeSuffix(ROOT.getDst());
5159 
5160    emit(new InstrMEM(instrFactory, ROOT, "sw" + suffix + usuffix 
5161                      + " `s0l, 4(`s1)" + getDANum(ROOT.getDst()),
5162                      null, new Temp[]{ src, dst }));
5163    emit(new InstrMEM(instrFactory, ROOT, "sw" + suffix + usuffix
5164                      + " `s0h, 0(`s1)" + getDANum(ROOT.getDst()),
5165                      null, new Temp[]{ src, dst }));
5166                         return;                 }
5167                         }
5168                                  /* MOVE<l,d>(TEMP<i,l,f,d,p>(dst),src) */
5169                         if (true
5170                                 // check statement type
5171                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
5172                                 // check operand types
5173                                 && ( 
5174                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.DOUBLE ||
5175                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.LONG ||
5176                                         false )
5177                                 // end check operand types
5178                                                                 && (true
5179                                         // no check needed for ExpId children
5180                                 )
5181                                 && (true
5182                                         // check expression type
5183                                         && ((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.TEMP 
5184                                         // check operand types
5185                                         && ( 
5186                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.DOUBLE ||
5187                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.FLOAT ||
5188                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.LONG ||
5189                                                 ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.POINTER ||
5190                                         (       ((harpoon.IR.Tree.MOVE) stmArg).getDst().type() == Type.INT && !
5191                                          (((harpoon.IR.Tree.MOVE) stmArg).getDst() instanceof harpoon.IR.Tree.PreciselyTyped &&
5192                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE) stmArg).getDst()).isSmall())) ||
5193                                                 false )
5194                                         // end check operand types
5195                                 )
5196                         ){
5197                                         harpoon.Temp.Temp dst = makeTemp((harpoon.IR.Tree.TEMP)((harpoon.IR.Tree.MOVE) stmArg).getDst(), inf.tempFactory());
5198                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
5199                                 _matched_ = true;
5200 
5201                                 if (_matched_) { // action code! : degree 2
5202                                                                 harpoon.Temp.Temp src = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getSrc()); 
5203 
5204                         
5205    emitLineDebugInfo(ROOT);
5206     assert dst instanceof TwoWordTemp : "why is dst: "+dst + 
5207                  " a normal Temp? " + harpoon.IR.Tree.Print.print(ROOT);
5208 
5209     assert src instanceof TwoWordTemp : "why is src: "+src + 
5210                  " a normal Temp? " + harpoon.IR.Tree.Print.print(ROOT);
5211 
5212     declare( dst, code.getTreeDerivation(),  ROOT.getSrc() );
5213 
5214     emitRegAllocDef( ROOT, dst );
5215     emit( ROOT, "move `d0l, `s0l\n"
5216           + "move `d0h, `s0h", dst, src );
5217     emitRegAllocUse(ROOT, src);
5218                         return;                 }
5219                         }
5220                                  /* CJUMP(BINOP<i,l,f,d,p>(cmpop,j,k),iftrue,iffalse) */
5221                         if (true
5222                                 // check statement type
5223                                 && (stmArg instanceof harpoon.IR.Tree.CJUMP)
5224                                 && (true
5225                                         // check expression type
5226                                         && ((harpoon.IR.Tree.CJUMP) stmArg).getTest() instanceof harpoon.IR.Tree.BINOP
5227                                         // check operand types
5228                                         && ( 
5229                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.DOUBLE ||
5230                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.FLOAT ||
5231                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.LONG ||
5232                                                 ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.POINTER ||
5233                                         (       ((harpoon.IR.Tree.CJUMP) stmArg).getTest().type() == Type.INT && !
5234                                          (((harpoon.IR.Tree.CJUMP) stmArg).getTest() instanceof harpoon.IR.Tree.PreciselyTyped &&
5235                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).isSmall())) ||
5236                                                 false )
5237                                         // end check operand types
5238                                                 // check left child
5239                                                 // no check needed for ExpId children
5240                                                 // check right child
5241                                                 // no check needed for ExpId children
5242                                 )
5243                         ){
5244                                         int cmpop = ((harpoon.IR.Tree.BINOP) ((harpoon.IR.Tree.CJUMP) stmArg).getTest()).op;
5245                                 harpoon.Temp.Label iffalse = ((harpoon.IR.Tree.CJUMP)stmArg).iffalse;
5246                                 harpoon.Temp.Label iftrue = ((harpoon.IR.Tree.CJUMP)stmArg).iftrue;
5247                         harpoon.IR.Tree.CJUMP ROOT = (harpoon.IR.Tree.CJUMP) stmArg;
5248                                 _matched_ = true&& ( isCmpOp(cmpop) &&
5249          ( ((BINOP) ROOT.getTest()).operandType()==Type.POINTER ||
5250            ((BINOP) ROOT.getTest()).operandType()==Type.INT ) );
5251 
5252                                 if (_matched_) { // action code! : degree 2
5253                                                                         harpoon.Temp.Temp j = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getLeft()); 
5254                                                 harpoon.Temp.Temp k = munchExp(((harpoon.IR.Tree.BINOP)((harpoon.IR.Tree.CJUMP) stmArg).getTest()).getRight()); 
5255 
5256                         
5257    emitLineDebugInfo(ROOT);
5258    emit( ROOT, cmpOp2BrStr(cmpop) + " `s0, `s1, `L0",
5259          null, new Temp[] { j , k }, new Label[] { iftrue });
5260    emitJUMP( ROOT, "b `L0", iffalse );
5261                         return;                 }
5262                         }
5263                                  /* JUMP(NAME(l)) */
5264                         if (true
5265                                 // check statement type
5266                                 && stmArg instanceof harpoon.IR.Tree.JUMP
5267                                 && (true
5268                                         // check expression type
5269                                         && ((harpoon.IR.Tree.JUMP)stmArg).getExp() instanceof harpoon.IR.Tree.NAME 
5270                                 )
5271                         ){
5272                                         harpoon.Temp.Label l = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.JUMP)stmArg).getExp()).label;
5273                         harpoon.IR.Tree.JUMP ROOT = (harpoon.IR.Tree.JUMP) stmArg;
5274                                 _matched_ = true;
5275 
5276                                 if (_matched_) { // action code! : degree 2
5277                         
5278                          // direct jump
5279    emitLineDebugInfo(ROOT);
5280     //FSK   emitNoFall (ROOT, "j " + l + "", null, null, new Label[] { l });
5281    emitJUMP(ROOT, "j " + l + "", l );
5282                         return;                 }
5283                         }
5284                                  /* CALL(retval,retex,NAME(funcLabel),arglist,handler) */
5285                         if (true
5286                                 // check statement type
5287                                 && stmArg instanceof harpoon.IR.Tree.CALL 
5288                                 && (true
5289                                         // check expression type
5290                                         && ((harpoon.IR.Tree.CALL) stmArg).getFunc() instanceof harpoon.IR.Tree.NAME 
5291                                 )
5292                         ){
5293                                         harpoon.Temp.Label funcLabel = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.CALL) stmArg).getFunc()).label;
5294                                 harpoon.Temp.Label handler = ((harpoon.IR.Tree.CALL)stmArg).getHandler().label;
5295                         harpoon.IR.Tree.CALL ROOT = (harpoon.IR.Tree.CALL) stmArg;
5296                                 _matched_ = true;
5297 
5298                                 if (_matched_) { // action code! : degree 2
5299                                                         harpoon.Temp.Temp retval = (((harpoon.IR.Tree.CALL)stmArg).getRetval()==null) ? null : munchExp(((harpoon.IR.Tree.CALL)stmArg).getRetval());
5300                                 harpoon.Temp.Temp retex = munchExp(((harpoon.IR.Tree.CALL)stmArg).getRetex());
5301                                 /* munch argument ExpList into a TempList */
5302                                 harpoon.Temp.TempList arglist = new harpoon.Temp.TempList(null, null);
5303                                 { harpoon.Temp.TempList tl=arglist;
5304                                   for (harpoon.IR.Tree.ExpList el = ((harpoon.IR.Tree.CALL)stmArg).getArgs(); el!=null; el=el.tail, tl=tl.tail) 
5305                                     tl.tail = new harpoon.Temp.TempList(munchExp(el.head), null);
5306                                 }
5307                                 arglist = arglist.tail;
5308 
5309                         
5310    CallState cs = emitCallPrologue(ROOT, arglist, code.getTreeDerivation());
5311    Label rlabel = new Label(), elabel = new Label();
5312 
5313    emitLineDebugInfo(ROOT);
5314    declareCALLDefFull();
5315    emit2(ROOT, "la `d0, " + rlabel + " # funky call",
5316          new Temp[]{ LR }, null );
5317    emitCallNoFall( ROOT, "j "+funcLabel,
5318                    call_def_full,
5319                    (Temp[]) cs.callUses.toArray(new Temp[cs.callUses.size()]),
5320                    new Label[] { rlabel, elabel } );
5321    // make handler stub.
5322    emitLABEL( ROOT, elabel+":", elabel);
5323    emitHandlerStub(ROOT, retex, handler);
5324    // normal return
5325    emitLABEL( ROOT, rlabel+":", rlabel);
5326    emitCallEpilogue(ROOT, false, retval,
5327                     ((ROOT.getRetval()==null)?null:
5328                      code.getTreeDerivation().typeMap(ROOT.getRetval())), cs);
5329    // emit fixup table.
5330    emitCallFixup(ROOT, rlabel, elabel);
5331                         return;                 }
5332                         }
5333                                  /* NATIVECALL(retval,NAME(funcLabel),arglist) */
5334                         if (true
5335                                 // check statement type
5336                                 && stmArg instanceof harpoon.IR.Tree.NATIVECALL
5337                                                                 && (true
5338                                         // check expression type
5339                                         && ((harpoon.IR.Tree.NATIVECALL) stmArg).getFunc() instanceof harpoon.IR.Tree.NAME 
5340                                 )
5341                         ){
5342                                         harpoon.Temp.Label funcLabel = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.NATIVECALL) stmArg).getFunc()).label;
5343                         harpoon.IR.Tree.NATIVECALL ROOT = (harpoon.IR.Tree.NATIVECALL) stmArg;
5344                                 _matched_ = true;
5345 
5346                                 if (_matched_) { // action code! : degree 2
5347                                                         harpoon.Temp.Temp retval = (((harpoon.IR.Tree.NATIVECALL)stmArg).getRetval()==null) ? null : munchExp(((harpoon.IR.Tree.NATIVECALL)stmArg).getRetval());
5348                                 /* munch argument ExpList into a TempList */
5349                                 harpoon.Temp.TempList arglist = new harpoon.Temp.TempList(null, null);
5350                                 { harpoon.Temp.TempList tl=arglist;
5351                                   for (harpoon.IR.Tree.ExpList el = ((harpoon.IR.Tree.NATIVECALL)stmArg).getArgs(); el!=null; el=el.tail, tl=tl.tail) 
5352                                     tl.tail = new harpoon.Temp.TempList(munchExp(el.head), null);
5353                                 }
5354                                 arglist = arglist.tail;
5355 
5356                         
5357    CallState cs = emitCallPrologue(ROOT, arglist,
5358                                    code.getTreeDerivation());
5359    emitLineDebugInfo(ROOT);
5360    declareCALLDefFull();
5361    emitNativeCall( ROOT, "jal " + funcLabel,
5362                    call_def_full,
5363                    (Temp[]) cs.callUses.toArray(new Temp[cs.callUses.size()]),
5364                    true, null);
5365    // clean up.
5366    emitCallEpilogue(ROOT, true, retval, 
5367                     ((ROOT.getRetval()==null)?null:
5368                      code.getTreeDerivation().typeMap(ROOT.getRetval())), cs);
5369                         return;                 }
5370                         }
5371                                  /* DATUM(CONST<i,f>(exp)) */
5372                         if (true
5373                                 // check statement type
5374                                 && stmArg instanceof harpoon.IR.Tree.DATUM
5375                                 && (true
5376                                         // check expression type
5377                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
5378                                         // check operand types
5379                                         && ( 
5380                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.FLOAT ||
5381                                         (       ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.INT && !
5382                                          (((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.PreciselyTyped &&
5383                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).isSmall())) ||
5384                                                 false )
5385                                         // end check operand types
5386                                 )
5387                         ){
5388                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
5389                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
5390                                 _matched_ = true;
5391 
5392                                 if (_matched_) { // action code! : degree 2
5393                         
5394                         
5395    int i = (ROOT.getData().type()==Type.INT) ? exp.intValue()
5396       : Float.floatToIntBits(exp.floatValue());
5397    String lo = "0x"+Integer.toHexString(i);
5398    emitDIRECTIVE( ROOT, "\t.word "+lo+" # "+exp);
5399                         return;                 }
5400                         }
5401                                  /* DATUM(CONST<l,d>(exp)) */
5402                         if (true
5403                                 // check statement type
5404                                 && stmArg instanceof harpoon.IR.Tree.DATUM
5405                                 && (true
5406                                         // check expression type
5407                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
5408                                         // check operand types
5409                                         && ( 
5410                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.DOUBLE ||
5411                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.LONG ||
5412                                                 false )
5413                                         // end check operand types
5414                                 )
5415                         ){
5416                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
5417                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
5418                                 _matched_ = true;
5419 
5420                                 if (_matched_) { // action code! : degree 2
5421                         
5422                         
5423    long l = (ROOT.getData().type()==Type.LONG) ? exp.longValue()
5424       : Double.doubleToLongBits(exp.doubleValue());
5425    String lo = "0x"+Integer.toHexString((int)l);
5426    String hi = "0x"+Integer.toHexString((int)(l>>32));
5427    // Store doubles and longs big endian
5428    emitDIRECTIVE( ROOT, "\t.word "+hi+" # hi("+exp+")");
5429    emitDIRECTIVE( ROOT, "\t.word "+lo+" # lo("+exp+")");
5430                         return;                 }
5431                         }
5432                                  /* DATUM(CONST<p>(exp)) */
5433                         if (true
5434                                 // check statement type
5435                                 && stmArg instanceof harpoon.IR.Tree.DATUM
5436                                 && (true
5437                                         // check expression type
5438                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
5439                                         // check operand types
5440                                         && ( 
5441                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.POINTER ||
5442                                                 false )
5443                                         // end check operand types
5444                                 )
5445                         ){
5446                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
5447                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
5448                                 _matched_ = true;
5449 
5450                                 if (_matched_) { // action code! : degree 2
5451                         
5452                         
5453    emitDIRECTIVE( ROOT, "\t.word 0 # null pointer constant");
5454                         return;                 }
5455                         }
5456                                  /* DATUM(CONST<u:8,s:8>(exp)) */
5457                         if (true
5458                                 // check statement type
5459                                 && stmArg instanceof harpoon.IR.Tree.DATUM
5460                                 && (true
5461                                         // check expression type
5462                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
5463                                         // check operand types
5464                                         && ( 
5465                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).isSmall() && (
5466                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).signed() ? (
5467                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==8 ||
5468                                                   false) : (
5469                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==8 ||
5470                                                   false) ) ) ||
5471                                                 false )
5472                                         // end check operand types
5473                                 )
5474                         ){
5475                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
5476                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
5477                                 _matched_ = true;
5478 
5479                                 if (_matched_) { // action code! : degree 2
5480                         
5481                         
5482    String chardesc = (exp.intValue()>=32 && exp.intValue()<127 
5483                       && exp.intValue()!=96 /* backquotes cause problems */
5484                       && exp.intValue()!=34 /* so do double quotes */) ?
5485       ("\t# char "+((char)exp.intValue())) : "";
5486    emitDIRECTIVE( ROOT, "\t.byte "+exp+chardesc);
5487                         return;                 }
5488                         }
5489                                  /* DATUM(CONST<u:16,s:16>(exp)) */
5490                         if (true
5491                                 // check statement type
5492                                 && stmArg instanceof harpoon.IR.Tree.DATUM
5493                                 && (true
5494                                         // check expression type
5495                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
5496                                         // check operand types
5497                                         && ( 
5498                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).isSmall() && (
5499                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).signed() ? (
5500                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==16 ||
5501                                                   false) : (
5502                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==16 ||
5503                                                   false) ) ) ||
5504                                                 false )
5505                                         // end check operand types
5506                                 )
5507                         ){
5508                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
5509                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
5510                                 _matched_ = true;
5511 
5512                                 if (_matched_) { // action code! : degree 2
5513                         
5514                         
5515    String chardesc = (exp.intValue()>=32 && exp.intValue()<127
5516                       && exp.intValue()!=96 /* backquotes cause problems */
5517                       && exp.intValue()!=34 /* so do double quotes */) ?
5518       ("\t# char "+((char)exp.intValue())) : "";
5519    emitDIRECTIVE( ROOT, "\t.short "+exp+chardesc);
5520                         return;                 }
5521                         }
5522                                  /* DATUM(NAME(l)) */
5523                         if (true
5524                                 // check statement type
5525                                 && stmArg instanceof harpoon.IR.Tree.DATUM
5526                                 && (true
5527                                         // check expression type
5528                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.NAME 
5529                                 )
5530                         ){
5531                                         harpoon.Temp.Label l = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.DATUM)stmArg).getData()).label;
5532                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
5533                                 _matched_ = true;
5534 
5535                                 if (_matched_) { // action code! : degree 2
5536                         
5537                         
5538    emitDIRECTIVE( ROOT, "\t.word "+l);
5539                         return;                 }
5540                         }
5541                                  /* MOVE<i,f,p>(dst,src) */
5542                         if (true
5543                                 // check statement type
5544                                 && stmArg instanceof harpoon.IR.Tree.MOVE 
5545                                 // check operand types
5546                                 && ( 
5547                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.FLOAT ||
5548                                         ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.POINTER ||
5549                                 (       ((harpoon.IR.Tree.MOVE)stmArg).type() == Type.INT && !
5550                                  (((harpoon.IR.Tree.MOVE)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
5551                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.MOVE)stmArg)).isSmall())) ||
5552                                         false )
5553                                 // end check operand types
5554                                                                 && (true
5555                                         // no check needed for ExpId children
5556                                 )
5557                                 && (true
5558                                         // no check needed for ExpId children
5559                                 )
5560                         ){
5561                         harpoon.IR.Tree.MOVE ROOT = (harpoon.IR.Tree.MOVE) stmArg;
5562                                 _matched_ = true;
5563 
5564                                 if (_matched_) { // action code! : degree 1
5565                                                                 harpoon.Temp.Temp src = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getSrc()); 
5566                                         harpoon.Temp.Temp dst = munchExp(((harpoon.IR.Tree.MOVE) stmArg).getDst()); 
5567 
5568                         
5569    emitLineDebugInfo(ROOT);
5570     declare( dst, code.getTreeDerivation(), ROOT.getSrc());
5571     emitMOVE( ROOT, "move `d0, `s0", dst, src );
5572                         return;                 }
5573                         }
5574                                  /* EXPR(e) */
5575                         if (true
5576                                 // check statement type
5577                                 && stmArg instanceof harpoon.IR.Tree.EXPR
5578                                 && (true
5579                                         // no check needed for ExpId children
5580                                 )
5581                         ){
5582                         harpoon.IR.Tree.EXPR ROOT = (harpoon.IR.Tree.EXPR) stmArg;
5583                                 _matched_ = true;
5584 
5585                                 if (_matched_) { // action code! : degree 1
5586                                                                 harpoon.Temp.Temp e = munchExp(((harpoon.IR.Tree.EXPR)stmArg).getExp()); 
5587 
5588                         
5589                         /* this is a statement that's just an
5590                            expression; just throw away 
5591                            calculated value */
5592                         return;                 }
5593                         }
5594                                  /* CJUMP(test,iftrue,iffalse) */
5595                         if (true
5596                                 // check statement type
5597                                 && (stmArg instanceof harpoon.IR.Tree.CJUMP)
5598                                 && (true
5599                                         // no check needed for ExpId children
5600                                 )
5601                         ){
5602                                 harpoon.Temp.Label iffalse = ((harpoon.IR.Tree.CJUMP)stmArg).iffalse;
5603                                 harpoon.Temp.Label iftrue = ((harpoon.IR.Tree.CJUMP)stmArg).iftrue;
5604                         harpoon.IR.Tree.CJUMP ROOT = (harpoon.IR.Tree.CJUMP) stmArg;
5605                                 _matched_ = true;
5606 
5607                                 if (_matched_) { // action code! : degree 1
5608                                                                 harpoon.Temp.Temp test = munchExp(((harpoon.IR.Tree.CJUMP) stmArg).getTest()); 
5609 
5610                         
5611    emitLineDebugInfo(ROOT);
5612    emit( ROOT, "beq `s0, 0, `L0",
5613          null, new Temp[]{ test },
5614          new Label[]{ iffalse });
5615    emitJUMP( ROOT, "b `L0", iftrue );
5616                         return;                 }
5617                         }
5618                                  /* JUMP(e) */
5619                         if (true
5620                                 // check statement type
5621                                 && stmArg instanceof harpoon.IR.Tree.JUMP
5622                                 && (true
5623                                         // no check needed for ExpId children
5624                                 )
5625                         ){
5626                         harpoon.IR.Tree.JUMP ROOT = (harpoon.IR.Tree.JUMP) stmArg;
5627                                 _matched_ = true;
5628 
5629                                 if (_matched_) { // action code! : degree 1
5630                                                                 harpoon.Temp.Temp e = munchExp(((harpoon.IR.Tree.JUMP)stmArg).getExp()); 
5631 
5632                         
5633    emitLineDebugInfo(ROOT);
5634     List<Label> labelList = LabelList.toList( ROOT.targets );
5635     emit(new Instr( instrFactory, ROOT, 
5636                     "j `s0",
5637                     new Temp[]{ },
5638                     new Temp[]{ e },
5639                     false, labelList ) {
5640           public boolean hasModifiableTargets(){ 
5641              return false; 
5642           }
5643        });
5644                         return;                 }
5645                         }
5646                                  /* LABEL(id) */
5647                         if (true
5648                                 // check statement type
5649                                 && stmArg instanceof harpoon.IR.Tree.LABEL 
5650                         ){
5651                                 String id = ((harpoon.IR.Tree.LABEL)stmArg).label.toString();
5652 
5653                         harpoon.IR.Tree.LABEL ROOT = (harpoon.IR.Tree.LABEL) stmArg;
5654                                 _matched_ = true;
5655 
5656                                 if (_matched_) { // action code! : degree 1
5657                         
5658                         
5659     if (ROOT.exported) {
5660       emitLABEL( ROOT, "\t.globl "+ROOT.label+"\n"+
5661                     ROOT.label + ":", ROOT.label);
5662     } else {
5663       emitLABEL( ROOT, ROOT.label + ":", ROOT.label);
5664     }
5665                         return;                 }
5666                         }
5667                                  /* METHOD(params) */
5668                         if (true
5669                                 // check statement type
5670                                 && stmArg instanceof harpoon.IR.Tree.METHOD 
5671                         ){
5672                         harpoon.IR.Tree.METHOD ROOT = (harpoon.IR.Tree.METHOD) stmArg;
5673                                 _matched_ = true;
5674 
5675                                 if (_matched_) { // action code! : degree 1
5676                                                         harpoon.Temp.Temp[] params = new harpoon.Temp.Temp[((harpoon.IR.Tree.METHOD)stmArg).getParamsLength()];
5677                                 for (int _i_=0; _i_<params.length; _i_++)
5678                                   params[_i_] = munchExp(((harpoon.IR.Tree.METHOD)stmArg).getParams(_i_));
5679 
5680                         
5681    emitLineDebugInfo(ROOT);
5682     // mark entry point.
5683     declare(SP, HClass.Void);
5684     declare(FP, HClass.Void);
5685     emit(new InstrENTRY( instrFactory, ROOT ));
5686     // Here is the deal.  By this point in code generation, we have
5687     // not finished this routine, nor have we register allocated, so
5688     // we don't know how big the frame is.  The arguments are on top
5689     // of the frame, so that means we either
5690     // 1. Use sp to address args, use psuedo ops now and replace
5691     //      them in proc fixup when we know the correct offset
5692     // 2. Use fp to address args, and use real instructions now
5693     // 
5694     // We choose option 2.  To figure out if an arg is going to be in
5695     // a register or on the stack (and if its on the stack, where is
5696     // it), we build a local stack object and pass it this routine (as
5697     // if this were the stack frame for another routine that called
5698     // this one and needed to pass it parameters).
5699     // Create a new stack that believes this routine is what it is
5700     // calling.  That will give us correct information about the
5701     // location of the parameters for this routine.
5702     StackInfo param_stack = new StackInfo(regfile);
5703     param_stack.callInfo(ROOT);
5704     // move arguments to temporaries.
5705     // skip param[0], which is the explicit 'exceptional return address'
5706     for (int i=1; i<params.length; i++) {
5707        declare(params[i], code.getTreeDerivation(), ROOT.getParams(i));
5708        switch(param_stack.argWhere(ROOT, i-1)) {
5709        case StackInfo.REGISTER:
5710           if (ROOT.getParams(i).isDoubleWord()) {
5711              emitRegAllocDef( ROOT, params[i] );
5712              emit2( ROOT, "move `d0h, `s0\n"
5713                           + "move `d0l, `s1",
5714                     new Temp[] {params[i]},
5715                     new Temp[] { param_stack.argReg(ROOT, i-1),
5716                                  param_stack.argSecondReg(ROOT, i-1) } );
5717              emitRegAllocUse(ROOT, param_stack.argReg(ROOT, i-1));
5718              emitRegAllocUse(ROOT, param_stack.argSecondReg(ROOT, i-1));
5719           } else {
5720              emitMOVE( ROOT, "move `d0, `s0", params[i],
5721                        param_stack.argReg(ROOT, i-1));
5722           }
5723           break;
5724        case StackInfo.STACK:
5725           if(ROOT.getParams(i).isDoubleWord()) {
5726              declare (SP, HClass.Void);
5727              emitRegAllocDef(ROOT, params[i]);
5728              emit(new InstrMEM( instrFactory, ROOT,
5729                                 "lw `d0h, " 
5730                                 + param_stack.argOffset(ROOT, i-1)
5731                                 + "(`s0)        # arg "
5732                                 + (i-1) + "h"
5733                                 + "\nlw `d0l, " 
5734                                 + param_stack.argSecondOffset(ROOT, i-1)
5735                                 + "(`s0)        # arg "
5736                                 + (i-1) + "l",
5737                                 new Temp[]{ params[i] },
5738                                 new Temp[]{ FP })); 
5739              emitRegAllocUse( ROOT, FP ); // FSK: (for consistency)
5740           } else {
5741              declare( SP, HClass.Void );
5742              emit(new InstrMEM(
5743                 instrFactory, ROOT,
5744                 "lw `d0, " + param_stack.argOffset(ROOT, i-1)
5745                 + "(`s0)         # arg " + (i-1),
5746                 new Temp[]{ params[i] },
5747                 new Temp[]{ FP }));
5748           }
5749           break;
5750        case StackInfo.REGSTACKSPLIT:
5751           assert false;
5752        }
5753     }
5754     param_stack = null; // free
5755                         return;                 }
5756                         }
5757                                  /* THROW(val,handler) */
5758                         if (true
5759                                 // check expression type
5760                                 && stmArg instanceof harpoon.IR.Tree.THROW
5761                                                                 && (true
5762                                         // no check needed for ExpId children
5763                                 )
5764                                                                 && (true
5765                                         // no check needed for ExpId children
5766                                 )
5767                         ){
5768                         harpoon.IR.Tree.THROW ROOT = (harpoon.IR.Tree.THROW) stmArg;
5769                                 _matched_ = true;
5770 
5771                                 if (_matched_) { // action code! : degree 1
5772                                                                 harpoon.Temp.Temp val = munchExp(((harpoon.IR.Tree.THROW) stmArg).getRetex()); 
5773                                         harpoon.Temp.Temp handler = munchExp(((harpoon.IR.Tree.THROW) stmArg).getHandler()); 
5774 
5775                         
5776    emitLineDebugInfo(ROOT);
5777    // ignore handler, as our runtime does clever things instead.
5778    declare( v0, code.getTreeDerivation(), ROOT.getRetex() );
5779    // What about functions that return long long?
5780    emitMOVE( ROOT, "move `d0, `s0", v0, val );
5781    declareCALLDefBuiltin();
5782    declare(a0, HClass.Void);
5783    declare(a1, HClass.Void);
5784    declare(a2, HClass.Void);
5785    declare(a3, HClass.Void);
5786    declare(t4, HClass.Void);
5787    // $31 contains the instruction after the return point
5788    // of the function that might have excepted
5789    emit( ROOT, "jal "+nameMap.c_function_name("_lookup_handler")+
5790          " # hi mom ",
5791          new Temp[] {a0, a1, a2, a3, t4, LR}, //clobbers
5792                  new Temp[] {FP}, true, null);  // v0 and FP are preserved
5793    // mark exit point.
5794    emit(new InstrEXIT( instrFactory, ROOT ));
5795                         return;                 }
5796                         }
5797                                  /* CALL(retval,retex,func,arglist,handler) */
5798                         if (true
5799                                 // check statement type
5800                                 && stmArg instanceof harpoon.IR.Tree.CALL 
5801                                 && (true
5802                                         // no check needed for ExpId children
5803                                 )
5804                         ){
5805                                 harpoon.Temp.Label handler = ((harpoon.IR.Tree.CALL)stmArg).getHandler().label;
5806                         harpoon.IR.Tree.CALL ROOT = (harpoon.IR.Tree.CALL) stmArg;
5807                                 _matched_ = true;
5808 
5809                                 if (_matched_) { // action code! : degree 1
5810                                                                 harpoon.Temp.Temp func = munchExp(((harpoon.IR.Tree.CALL) stmArg).getFunc()); 
5811                                 harpoon.Temp.Temp retval = (((harpoon.IR.Tree.CALL)stmArg).getRetval()==null) ? null : munchExp(((harpoon.IR.Tree.CALL)stmArg).getRetval());
5812                                 harpoon.Temp.Temp retex = munchExp(((harpoon.IR.Tree.CALL)stmArg).getRetex());
5813                                 /* munch argument ExpList into a TempList */
5814                                 harpoon.Temp.TempList arglist = new harpoon.Temp.TempList(null, null);
5815                                 { harpoon.Temp.TempList tl=arglist;
5816                                   for (harpoon.IR.Tree.ExpList el = ((harpoon.IR.Tree.CALL)stmArg).getArgs(); el!=null; el=el.tail, tl=tl.tail) 
5817                                     tl.tail = new harpoon.Temp.TempList(munchExp(el.head), null);
5818                                 }
5819                                 arglist = arglist.tail;
5820 
5821                         
5822    CallState cs = emitCallPrologue(ROOT, arglist, code.getTreeDerivation());
5823    Label rlabel = new Label(), elabel = new Label();
5824    emitLineDebugInfo(ROOT);
5825 
5826    declareCALLDefFull();
5827    emit2(ROOT, "la `d0, " + rlabel + " # funky call",
5828          new Temp[]{ LR }, null );
5829    // call uses 'func' as `s0
5830    cs.callUses.add(0, func);
5831    emitCallNoFall( ROOT, "j `s0 ",
5832                    call_def_full,
5833                    (Temp[]) cs.callUses.toArray(new Temp[cs.callUses.size()]),
5834                    new Label[] { rlabel, elabel } );
5835    // make handler stub.
5836    emitLABEL( ROOT, elabel+":", elabel);
5837    emitHandlerStub(ROOT, retex, handler);
5838    // normal return
5839    emitLABEL( ROOT, rlabel+":", rlabel);
5840    emitCallEpilogue(ROOT, false, retval,
5841                     ((ROOT.getRetval()==null)?null:
5842                      code.getTreeDerivation().typeMap(ROOT.getRetval())), cs);
5843    // emit fixup table.
5844    emitCallFixup(ROOT, rlabel, elabel);
5845                         return;                 }
5846                         }
5847                                  /* NATIVECALL(retval,func,arglist) */
5848                         if (true
5849                                 // check statement type
5850                                 && stmArg instanceof harpoon.IR.Tree.NATIVECALL
5851                                                                 && (true
5852                                         // no check needed for ExpId children
5853                                 )
5854                         ){
5855                         harpoon.IR.Tree.NATIVECALL ROOT = (harpoon.IR.Tree.NATIVECALL) stmArg;
5856                                 _matched_ = true;
5857 
5858                                 if (_matched_) { // action code! : degree 1
5859                                                                 harpoon.Temp.Temp func = munchExp(((harpoon.IR.Tree.NATIVECALL) stmArg).getFunc()); 
5860                                 harpoon.Temp.Temp retval = (((harpoon.IR.Tree.NATIVECALL)stmArg).getRetval()==null) ? null : munchExp(((harpoon.IR.Tree.NATIVECALL)stmArg).getRetval());
5861                                 /* munch argument ExpList into a TempList */
5862                                 harpoon.Temp.TempList arglist = new harpoon.Temp.TempList(null, null);
5863                                 { harpoon.Temp.TempList tl=arglist;
5864                                   for (harpoon.IR.Tree.ExpList el = ((harpoon.IR.Tree.NATIVECALL)stmArg).getArgs(); el!=null; el=el.tail, tl=tl.tail) 
5865                                     tl.tail = new harpoon.Temp.TempList(munchExp(el.head), null);
5866                                 }
5867                                 arglist = arglist.tail;
5868 
5869                         
5870    CallState cs = emitCallPrologue(ROOT, arglist,
5871                                    code.getTreeDerivation());
5872    emitLineDebugInfo(ROOT);
5873     // call uses 'func' as `s0
5874    cs.callUses.add(0, func);
5875    declareCALLDefFull();
5876    emitNativeCall( ROOT, "jal `s0",
5877                    call_def_full,
5878                    (Temp[]) cs.callUses.toArray(new Temp[cs.callUses.size()]),
5879                    true, null);
5880    // clean up.
5881    emitCallEpilogue(ROOT, true, retval, 
5882                     ((ROOT.getRetval()==null)?null:
5883                      code.getTreeDerivation().typeMap(ROOT.getRetval())), cs);
5884                         return;                 }
5885                         }
5886                                  /* RETURN<i,f,p>(val) */
5887                         if (true
5888                                 // check expression type
5889                                 && stmArg instanceof harpoon.IR.Tree.RETURN
5890                                 // check operand types
5891                                 && ( 
5892                                         ((harpoon.IR.Tree.RETURN)stmArg).type() == Type.FLOAT ||
5893                                         ((harpoon.IR.Tree.RETURN)stmArg).type() == Type.POINTER ||
5894                                 (       ((harpoon.IR.Tree.RETURN)stmArg).type() == Type.INT && !
5895                                  (((harpoon.IR.Tree.RETURN)stmArg) instanceof harpoon.IR.Tree.PreciselyTyped &&
5896                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.RETURN)stmArg)).isSmall())) ||
5897                                         false )
5898                                 // end check operand types
5899                                                                 && (true
5900                                         // no check needed for ExpId children
5901                                 )
5902                         ){
5903                         harpoon.IR.Tree.RETURN ROOT = (harpoon.IR.Tree.RETURN) stmArg;
5904                                 _matched_ = true;
5905 
5906                                 if (_matched_) { // action code! : degree 1
5907                                                                 harpoon.Temp.Temp val = munchExp(((harpoon.IR.Tree.RETURN) stmArg).getRetval()); 
5908 
5909                         
5910    emitLineDebugInfo(ROOT);
5911    declare( v0, code.getTreeDerivation(),  ROOT.getRetval() );
5912    emitMOVE( ROOT, "move `d0, `s0", v0, val );
5913    // mark exit point.
5914    emit(new InstrEXIT( instrFactory, ROOT ));
5915                         return;                 }
5916                         }
5917                                  /* RETURN<l,d>(val) */
5918                         if (true
5919                                 // check expression type
5920                                 && stmArg instanceof harpoon.IR.Tree.RETURN
5921                                 // check operand types
5922                                 && ( 
5923                                         ((harpoon.IR.Tree.RETURN)stmArg).type() == Type.DOUBLE ||
5924                                         ((harpoon.IR.Tree.RETURN)stmArg).type() == Type.LONG ||
5925                                         false )
5926                                 // end check operand types
5927                                                                 && (true
5928                                         // no check needed for ExpId children
5929                                 )
5930                         ){
5931                         harpoon.IR.Tree.RETURN ROOT = (harpoon.IR.Tree.RETURN) stmArg;
5932                                 _matched_ = true;
5933 
5934                                 if (_matched_) { // action code! : degree 1
5935                                                                 harpoon.Temp.Temp val = munchExp(((harpoon.IR.Tree.RETURN) stmArg).getRetval()); 
5936 
5937                         
5938    emitLineDebugInfo(ROOT);
5939    // InstrMOVEs do not handle longs
5940    declare( v0, HClass.Void );
5941    declare( v1, HClass.Void );
5942    emit( ROOT, "move `d0, `s0h", v0, val);
5943    emit( ROOT, "move `d0, `s0l", v1, val);
5944    // mark exit point.
5945    emit(new InstrEXIT( instrFactory, ROOT ));
5946                         return;                 }
5947                         }
5948                                  /* ALIGN(n) */
5949                         if (true
5950                                 // check statement type
5951                                 && stmArg instanceof harpoon.IR.Tree.ALIGN
5952                         ){
5953 int n = ((harpoon.IR.Tree.ALIGN)stmArg).alignment;                      harpoon.IR.Tree.ALIGN ROOT = (harpoon.IR.Tree.ALIGN) stmArg;
5954                                 _matched_ = true;
5955 
5956                                 if (_matched_) { // action code! : degree 1
5957                         
5958                         
5959    emitDIRECTIVE( ROOT, "\t.balign "+n);
5960                         return;                 }
5961                         }
5962                                  /* SEGMENT(CLASS) */
5963                         if (true
5964                                 // check statement type
5965                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
5966                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.CLASS
5967                         ){
5968                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
5969                                 _matched_ = true;
5970 
5971                                 if (_matched_) { // action code! : degree 1
5972                         
5973                         
5974    emitDIRECTIVE( ROOT, !is_elf?".data": (mipspro_assem ? ".data\n.section .flex.class,1, 3, 4, 16" : ".data\n.section .flex.class"));
5975 
5976                         return;                 }
5977                         }
5978                                  /* SEGMENT(CODE) */
5979                         if (true
5980                                 // check statement type
5981                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
5982                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.CODE
5983                         ){
5984                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
5985                                 _matched_ = true;
5986 
5987                                 if (_matched_) { // action code! : degree 1
5988                         
5989                         
5990    // gas 2.7 does not support naming the code section...not
5991    // sure what to do about this yet...
5992    // emitDIRECTIVE( ROOT, !is_elf?".code 32":".section code");
5993    emitDIRECTIVE( ROOT, !is_elf?".text ": (mipspro_assem ? ".text\n.section .flex.code,1, 7, 4, 16" : ".text\n.section .flex.code"));
5994                         return;                 }
5995                         }
5996                                  /* SEGMENT(GC) */
5997                         if (true
5998                                 // check statement type
5999                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6000                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.GC
6001                         ){
6002                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6003                                 _matched_ = true;
6004 
6005                                 if (_matched_) { // action code! : degree 1
6006                         
6007                         
6008    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".data\n.section .flex.gc,1, 3, 4, 16" : ".data\n.section .flex.gc"));
6009                         return;                 }
6010                         }
6011                                  /* SEGMENT(INIT_DATA) */
6012                         if (true
6013                                 // check statement type
6014                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6015                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.INIT_DATA
6016                         ){
6017                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6018                                 _matched_ = true;
6019 
6020                                 if (_matched_) { // action code! : degree 1
6021                         
6022                         
6023    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.init_data,1, 3, 4, 16" : ".section .flex.init_data"));
6024                         return;                 }
6025                         }
6026                                  /* SEGMENT(STATIC_OBJECTS) */
6027                         if (true
6028                                 // check statement type
6029                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6030                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STATIC_OBJECTS
6031                         ){
6032                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6033                                 _matched_ = true;
6034 
6035                                 if (_matched_) { // action code! : degree 1
6036                         
6037                         
6038    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.static_objects,1, 3, 4, 16" : ".section .flex.static_objects"));
6039                         return;                 }
6040                         }
6041                                  /* SEGMENT(STATIC_PRIMITIVES) */
6042                         if (true
6043                                 // check statement type
6044                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6045                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STATIC_PRIMITIVES
6046                         ){
6047                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6048                                 _matched_ = true;
6049 
6050                                 if (_matched_) { // action code! : degree 1
6051                         
6052                         
6053    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.static_primitives,1, 3, 4, 16" : ".section .flex.static_primitives"));
6054                         return;                 }
6055                         }
6056                                  /* SEGMENT(STRING_CONSTANTS) */
6057                         if (true
6058                                 // check statement type
6059                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6060                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STRING_CONSTANTS
6061                         ){
6062                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6063                                 _matched_ = true;
6064 
6065                                 if (_matched_) { // action code! : degree 1
6066                         
6067                         
6068    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.string_constants,1, 3, 4, 16" : ".section .flex.string_constants" ));
6069                         return;                 }
6070                         }
6071                                  /* SEGMENT(STRING_DATA) */
6072                         if (true
6073                                 // check statement type
6074                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6075                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STRING_DATA
6076                         ){
6077                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6078                                 _matched_ = true;
6079 
6080                                 if (_matched_) { // action code! : degree 1
6081                         
6082                         
6083    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.string_data,1, 3, 4, 16" : ".section .flex.string_data" ));
6084                         return;                 }
6085                         }
6086                                  /* SEGMENT(REFLECTION_OBJECTS) */
6087                         if (true
6088                                 // check statement type
6089                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6090                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.REFLECTION_OBJECTS
6091                         ){
6092                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6093                                 _matched_ = true;
6094 
6095                                 if (_matched_) { // action code! : degree 1
6096                         
6097                         
6098    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.reflection_objects,1, 3, 4, 16" : ".section .flex.reflection_objects"));
6099                         return;                 }
6100                         }
6101                                  /* SEGMENT(REFLECTION_DATA) */
6102                         if (true
6103                                 // check statement type
6104                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6105                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.REFLECTION_DATA
6106                         ){
6107                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6108                                 _matched_ = true;
6109 
6110                                 if (_matched_) { // action code! : degree 1
6111                         
6112                         
6113    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.reflection_data,1, 3, 4, 16" : ".section .flex.reflection_data"));
6114                         return;                 }
6115                         }
6116                                  /* SEGMENT(GC_INDEX) */
6117                         if (true
6118                                 // check statement type
6119                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6120                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.GC_INDEX
6121                         ){
6122                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6123                                 _matched_ = true;
6124 
6125                                 if (_matched_) { // action code! : degree 1
6126                         
6127                         
6128    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.gc_index,1, 3, 4, 16" : ".section .flex.gc_index"));
6129                         return;                 }
6130                         }
6131                                  /* SEGMENT(TEXT) */
6132                         if (true
6133                                 // check statement type
6134                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6135                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.TEXT
6136                         ){
6137                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6138                                 _matched_ = true;
6139 
6140                                 if (_matched_) { // action code! : degree 1
6141                         
6142                         
6143    emitDIRECTIVE( ROOT, !is_elf?".text": (mipspro_assem ? ".section .text,1, 7, 4, 16" : ".section .text"));
6144                         return;                 }
6145                         }
6146                                  /* SEGMENT(ZERO_DATA) */
6147                         if (true
6148                                 // check statement type
6149                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6150                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.ZERO_DATA
6151                         ){
6152                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6153                                 _matched_ = true;
6154 
6155                                 if (_matched_) { // action code! : degree 1
6156                         
6157                         
6158    // gas 2.7 does not allow BSS subsections...use .comm and .lcomm
6159    // for the variables to be initialized to zero
6160    // emitDIRECTIVE( ROOT, ".bss   \t#.section zero");
6161    emitDIRECTIVE(ROOT, !is_elf?".bss": (mipspro_assem ? ".section .flex.zero,1, 3, 4, 16" : ".section .flex.zero"));
6162                         return;                 }
6163                         }
6164                 assert _matched_ : "Uh oh...\nmaximal munch didn't match anything...SPEC file\nis not complete enough for this program\nDied on "+prettyPrint(stmArg)+" in " + prettyPrint(globalStmArg);
6165                 } // end munchStm
6166                 public void visit(harpoon.IR.Tree.Tree treee){
6167                         assert false : "Should never visit generic harpoon.IR.Tree.Treein CggVisitor";
6168                 } // end visit(harpoon.IR.Tree.Tree)
6169                 public void visit(harpoon.IR.Tree.Stm treee){
6170                         debug("munching "+treee+"       ");
6171                         munchStm(treee);
6172                 } // end visit(harpoon.IR.Tree.Stm)
6173                 public void visit(harpoon.IR.Tree.SEQ treee){
6174                         treee.getLeft().accept(this);
6175                         treee.getRight().accept(this);
6176                 }
6177         }
6178         CggVisitor visitor = new CggVisitor();
6179         harpoon.IR.Tree.Tree t = (harpoon.IR.Tree.Tree) code.getRootElement();
6180         t.accept(visitor);
6181                         clearDecl(); // reset temp type mappings
6182 
6183        // *** METHOD EPILOGUE *** 
6184    
6185 
6186         assert first != null : "Should always generate some instrs";
6187         return net.cscott.jutil.Default.pair(first, getDerivation());
6188         }
6189         /** Generates assembly code from a <code>harpoon.IR.Tree.Data</code>.
6190             <BR> <B>modifies:</B> <code>this</code>
6191             <BR> <B>effects:</B>
6192                  Scans <code>tree</code> to define a layout of 
6193                  Instructions, calling auxillary methods
6194                  and data structures as defined in the .Spec file
6195             @param tree Set of abstract <code>Tree</code> instructions 
6196                         that form the body of the data structure being compiled.
6197         */
6198         public final harpoon.IR.Assem.Instr cgg_genData(harpoon.IR.Tree.Data code, final harpoon.IR.Assem.InstrFactory inf) {
6199         _methodPrologue_(inf);
6200 
6201         // *** METHOD PROLOGUE ***
6202         this.instrFactory = inf; // XXX this should probably move to superclass
6203     // Create a stack object and let it know about all calls made by
6204     // this method.  Shouldn't this be in the constructor?
6205     this.stack = new StackInfo(regfile);
6206     collectCallInfo(code);
6207 
6208         final class CggVisitor extends harpoon.IR.Tree.TreeVisitor {
6209                  harpoon.Temp.Temp munchExp(harpoon.IR.Tree.Exp expArg) {
6210                         boolean _matched_ = false;
6211                         clearDecl(); // reset temp type mappings
6212                 assert false : "Uh oh...\nmaximal munch didn't match anything...SPEC file\nis not complete enough for this program\nDied on "+prettyPrint(expArg)+" in " + prettyPrint(globalStmArg);
6213                 return null; // doesn't matter, we're dead if we didn't match...
6214                  } // end munchExp
6215         harpoon.IR.Tree.Stm globalStmArg=null;
6216                  void munchStm(harpoon.IR.Tree.Stm stmArg) {
6217                          globalStmArg = stmArg;
6218                         boolean _matched_ = false;
6219                         clearDecl(); // reset temp type mappings
6220                                  /* DATUM(CONST<i,f>(exp)) */
6221                         if (true
6222                                 // check statement type
6223                                 && stmArg instanceof harpoon.IR.Tree.DATUM
6224                                 && (true
6225                                         // check expression type
6226                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
6227                                         // check operand types
6228                                         && ( 
6229                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.FLOAT ||
6230                                         (       ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.INT && !
6231                                          (((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.PreciselyTyped &&
6232                                           ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).isSmall())) ||
6233                                                 false )
6234                                         // end check operand types
6235                                 )
6236                         ){
6237                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
6238                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
6239                                 _matched_ = true;
6240 
6241                                 if (_matched_) { // action code! : degree 2
6242                         
6243                         
6244    int i = (ROOT.getData().type()==Type.INT) ? exp.intValue()
6245       : Float.floatToIntBits(exp.floatValue());
6246    String lo = "0x"+Integer.toHexString(i);
6247    emitDIRECTIVE( ROOT, "\t.word "+lo+" # "+exp);
6248                         return;                 }
6249                         }
6250                                  /* DATUM(CONST<l,d>(exp)) */
6251                         if (true
6252                                 // check statement type
6253                                 && stmArg instanceof harpoon.IR.Tree.DATUM
6254                                 && (true
6255                                         // check expression type
6256                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
6257                                         // check operand types
6258                                         && ( 
6259                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.DOUBLE ||
6260                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.LONG ||
6261                                                 false )
6262                                         // end check operand types
6263                                 )
6264                         ){
6265                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
6266                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
6267                                 _matched_ = true;
6268 
6269                                 if (_matched_) { // action code! : degree 2
6270                         
6271                         
6272    long l = (ROOT.getData().type()==Type.LONG) ? exp.longValue()
6273       : Double.doubleToLongBits(exp.doubleValue());
6274    String lo = "0x"+Integer.toHexString((int)l);
6275    String hi = "0x"+Integer.toHexString((int)(l>>32));
6276    // Store doubles and longs big endian
6277    emitDIRECTIVE( ROOT, "\t.word "+hi+" # hi("+exp+")");
6278    emitDIRECTIVE( ROOT, "\t.word "+lo+" # lo("+exp+")");
6279                         return;                 }
6280                         }
6281                                  /* DATUM(CONST<p>(exp)) */
6282                         if (true
6283                                 // check statement type
6284                                 && stmArg instanceof harpoon.IR.Tree.DATUM
6285                                 && (true
6286                                         // check expression type
6287                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
6288                                         // check operand types
6289                                         && ( 
6290                                                 ((harpoon.IR.Tree.DATUM)stmArg).getData().type() == Type.POINTER ||
6291                                                 false )
6292                                         // end check operand types
6293                                 )
6294                         ){
6295                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
6296                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
6297                                 _matched_ = true;
6298 
6299                                 if (_matched_) { // action code! : degree 2
6300                         
6301                         
6302    emitDIRECTIVE( ROOT, "\t.word 0 # null pointer constant");
6303                         return;                 }
6304                         }
6305                                  /* DATUM(CONST<u:8,s:8>(exp)) */
6306                         if (true
6307                                 // check statement type
6308                                 && stmArg instanceof harpoon.IR.Tree.DATUM
6309                                 && (true
6310                                         // check expression type
6311                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
6312                                         // check operand types
6313                                         && ( 
6314                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).isSmall() && (
6315                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).signed() ? (
6316                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==8 ||
6317                                                   false) : (
6318                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==8 ||
6319                                                   false) ) ) ||
6320                                                 false )
6321                                         // end check operand types
6322                                 )
6323                         ){
6324                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
6325                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
6326                                 _matched_ = true;
6327 
6328                                 if (_matched_) { // action code! : degree 2
6329                         
6330                         
6331    String chardesc = (exp.intValue()>=32 && exp.intValue()<127 
6332                       && exp.intValue()!=96 /* backquotes cause problems */
6333                       && exp.intValue()!=34 /* so do double quotes */) ?
6334       ("\t# char "+((char)exp.intValue())) : "";
6335    emitDIRECTIVE( ROOT, "\t.byte "+exp+chardesc);
6336                         return;                 }
6337                         }
6338                                  /* DATUM(CONST<u:16,s:16>(exp)) */
6339                         if (true
6340                                 // check statement type
6341                                 && stmArg instanceof harpoon.IR.Tree.DATUM
6342                                 && (true
6343                                         // check expression type
6344                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.CONST 
6345                                         // check operand types
6346                                         && ( 
6347                                                 (((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).isSmall() && (
6348                                                  ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).signed() ? (
6349                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==16 ||
6350                                                   false) : (
6351                                                   ((harpoon.IR.Tree.PreciselyTyped)((harpoon.IR.Tree.DATUM)stmArg).getData()).bitwidth()==16 ||
6352                                                   false) ) ) ||
6353                                                 false )
6354                                         // end check operand types
6355                                 )
6356                         ){
6357                                         Number exp = ((harpoon.IR.Tree.CONST) ((harpoon.IR.Tree.DATUM)stmArg).getData()).value;
6358                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
6359                                 _matched_ = true;
6360 
6361                                 if (_matched_) { // action code! : degree 2
6362                         
6363                         
6364    String chardesc = (exp.intValue()>=32 && exp.intValue()<127
6365                       && exp.intValue()!=96 /* backquotes cause problems */
6366                       && exp.intValue()!=34 /* so do double quotes */) ?
6367       ("\t# char "+((char)exp.intValue())) : "";
6368    emitDIRECTIVE( ROOT, "\t.short "+exp+chardesc);
6369                         return;                 }
6370                         }
6371                                  /* DATUM(NAME(l)) */
6372                         if (true
6373                                 // check statement type
6374                                 && stmArg instanceof harpoon.IR.Tree.DATUM
6375                                 && (true
6376                                         // check expression type
6377                                         && ((harpoon.IR.Tree.DATUM)stmArg).getData() instanceof harpoon.IR.Tree.NAME 
6378                                 )
6379                         ){
6380                                         harpoon.Temp.Label l = ((harpoon.IR.Tree.NAME)((harpoon.IR.Tree.DATUM)stmArg).getData()).label;
6381                         harpoon.IR.Tree.DATUM ROOT = (harpoon.IR.Tree.DATUM) stmArg;
6382                                 _matched_ = true;
6383 
6384                                 if (_matched_) { // action code! : degree 2
6385                         
6386                         
6387    emitDIRECTIVE( ROOT, "\t.word "+l);
6388                         return;                 }
6389                         }
6390                                  /* LABEL(id) */
6391                         if (true
6392                                 // check statement type
6393                                 && stmArg instanceof harpoon.IR.Tree.LABEL 
6394                         ){
6395                                 String id = ((harpoon.IR.Tree.LABEL)stmArg).label.toString();
6396 
6397                         harpoon.IR.Tree.LABEL ROOT = (harpoon.IR.Tree.LABEL) stmArg;
6398                                 _matched_ = true;
6399 
6400                                 if (_matched_) { // action code! : degree 1
6401                         
6402                         
6403     if (ROOT.exported) {
6404       emitLABEL( ROOT, "\t.globl "+ROOT.label+"\n"+
6405                     ROOT.label + ":", ROOT.label);
6406     } else {
6407       emitLABEL( ROOT, ROOT.label + ":", ROOT.label);
6408     }
6409                         return;                 }
6410                         }
6411                                  /* ALIGN(n) */
6412                         if (true
6413                                 // check statement type
6414                                 && stmArg instanceof harpoon.IR.Tree.ALIGN
6415                         ){
6416 int n = ((harpoon.IR.Tree.ALIGN)stmArg).alignment;                      harpoon.IR.Tree.ALIGN ROOT = (harpoon.IR.Tree.ALIGN) stmArg;
6417                                 _matched_ = true;
6418 
6419                                 if (_matched_) { // action code! : degree 1
6420                         
6421                         
6422    emitDIRECTIVE( ROOT, "\t.balign "+n);
6423                         return;                 }
6424                         }
6425                                  /* SEGMENT(CLASS) */
6426                         if (true
6427                                 // check statement type
6428                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6429                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.CLASS
6430                         ){
6431                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6432                                 _matched_ = true;
6433 
6434                                 if (_matched_) { // action code! : degree 1
6435                         
6436                         
6437    emitDIRECTIVE( ROOT, !is_elf?".data": (mipspro_assem ? ".data\n.section .flex.class,1, 3, 4, 16" : ".data\n.section .flex.class"));
6438 
6439                         return;                 }
6440                         }
6441                                  /* SEGMENT(CODE) */
6442                         if (true
6443                                 // check statement type
6444                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6445                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.CODE
6446                         ){
6447                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6448                                 _matched_ = true;
6449 
6450                                 if (_matched_) { // action code! : degree 1
6451                         
6452                         
6453    // gas 2.7 does not support naming the code section...not
6454    // sure what to do about this yet...
6455    // emitDIRECTIVE( ROOT, !is_elf?".code 32":".section code");
6456    emitDIRECTIVE( ROOT, !is_elf?".text ": (mipspro_assem ? ".text\n.section .flex.code,1, 7, 4, 16" : ".text\n.section .flex.code"));
6457                         return;                 }
6458                         }
6459                                  /* SEGMENT(GC) */
6460                         if (true
6461                                 // check statement type
6462                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6463                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.GC
6464                         ){
6465                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6466                                 _matched_ = true;
6467 
6468                                 if (_matched_) { // action code! : degree 1
6469                         
6470                         
6471    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".data\n.section .flex.gc,1, 3, 4, 16" : ".data\n.section .flex.gc"));
6472                         return;                 }
6473                         }
6474                                  /* SEGMENT(INIT_DATA) */
6475                         if (true
6476                                 // check statement type
6477                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6478                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.INIT_DATA
6479                         ){
6480                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6481                                 _matched_ = true;
6482 
6483                                 if (_matched_) { // action code! : degree 1
6484                         
6485                         
6486    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.init_data,1, 3, 4, 16" : ".section .flex.init_data"));
6487                         return;                 }
6488                         }
6489                                  /* SEGMENT(STATIC_OBJECTS) */
6490                         if (true
6491                                 // check statement type
6492                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6493                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STATIC_OBJECTS
6494                         ){
6495                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6496                                 _matched_ = true;
6497 
6498                                 if (_matched_) { // action code! : degree 1
6499                         
6500                         
6501    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.static_objects,1, 3, 4, 16" : ".section .flex.static_objects"));
6502                         return;                 }
6503                         }
6504                                  /* SEGMENT(STATIC_PRIMITIVES) */
6505                         if (true
6506                                 // check statement type
6507                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6508                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STATIC_PRIMITIVES
6509                         ){
6510                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6511                                 _matched_ = true;
6512 
6513                                 if (_matched_) { // action code! : degree 1
6514                         
6515                         
6516    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.static_primitives,1, 3, 4, 16" : ".section .flex.static_primitives"));
6517                         return;                 }
6518                         }
6519                                  /* SEGMENT(STRING_CONSTANTS) */
6520                         if (true
6521                                 // check statement type
6522                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6523                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STRING_CONSTANTS
6524                         ){
6525                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6526                                 _matched_ = true;
6527 
6528                                 if (_matched_) { // action code! : degree 1
6529                         
6530                         
6531    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.string_constants,1, 3, 4, 16" : ".section .flex.string_constants" ));
6532                         return;                 }
6533                         }
6534                                  /* SEGMENT(STRING_DATA) */
6535                         if (true
6536                                 // check statement type
6537                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6538                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.STRING_DATA
6539                         ){
6540                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6541                                 _matched_ = true;
6542 
6543                                 if (_matched_) { // action code! : degree 1
6544                         
6545                         
6546    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.string_data,1, 3, 4, 16" : ".section .flex.string_data" ));
6547                         return;                 }
6548                         }
6549                                  /* SEGMENT(REFLECTION_OBJECTS) */
6550                         if (true
6551                                 // check statement type
6552                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6553                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.REFLECTION_OBJECTS
6554                         ){
6555                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6556                                 _matched_ = true;
6557 
6558                                 if (_matched_) { // action code! : degree 1
6559                         
6560                         
6561    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.reflection_objects,1, 3, 4, 16" : ".section .flex.reflection_objects"));
6562                         return;                 }
6563                         }
6564                                  /* SEGMENT(REFLECTION_DATA) */
6565                         if (true
6566                                 // check statement type
6567                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6568                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.REFLECTION_DATA
6569                         ){
6570                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6571                                 _matched_ = true;
6572 
6573                                 if (_matched_) { // action code! : degree 1
6574                         
6575                         
6576    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.reflection_data,1, 3, 4, 16" : ".section .flex.reflection_data"));
6577                         return;                 }
6578                         }
6579                                  /* SEGMENT(GC_INDEX) */
6580                         if (true
6581                                 // check statement type
6582                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6583                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.GC_INDEX
6584                         ){
6585                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6586                                 _matched_ = true;
6587 
6588                                 if (_matched_) { // action code! : degree 1
6589                         
6590                         
6591    emitDIRECTIVE( ROOT, !is_elf?".data ": (mipspro_assem ? ".section .flex.gc_index,1, 3, 4, 16" : ".section .flex.gc_index"));
6592                         return;                 }
6593                         }
6594                                  /* SEGMENT(TEXT) */
6595                         if (true
6596                                 // check statement type
6597                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6598                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.TEXT
6599                         ){
6600                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6601                                 _matched_ = true;
6602 
6603                                 if (_matched_) { // action code! : degree 1
6604                         
6605                         
6606    emitDIRECTIVE( ROOT, !is_elf?".text": (mipspro_assem ? ".section .text,1, 7, 4, 16" : ".section .text"));
6607                         return;                 }
6608                         }
6609                                  /* SEGMENT(ZERO_DATA) */
6610                         if (true
6611                                 // check statement type
6612                                 && stmArg instanceof harpoon.IR.Tree.SEGMENT
6613                                 && ((harpoon.IR.Tree.SEGMENT)stmArg).segtype == harpoon.IR.Tree.SEGMENT.ZERO_DATA
6614                         ){
6615                         harpoon.IR.Tree.SEGMENT ROOT = (harpoon.IR.Tree.SEGMENT) stmArg;
6616                                 _matched_ = true;
6617 
6618                                 if (_matched_) { // action code! : degree 1
6619                         
6620                         
6621    // gas 2.7 does not allow BSS subsections...use .comm and .lcomm
6622    // for the variables to be initialized to zero
6623    // emitDIRECTIVE( ROOT, ".bss   \t#.section zero");
6624    emitDIRECTIVE(ROOT, !is_elf?".bss": (mipspro_assem ? ".section .flex.zero,1, 3, 4, 16" : ".section .flex.zero"));
6625                         return;                 }
6626                         }
6627                 assert _matched_ : "Uh oh...\nmaximal munch didn't match anything...SPEC file\nis not complete enough for this program\nDied on "+prettyPrint(stmArg)+" in " + prettyPrint(globalStmArg);
6628                 } // end munchStm
6629                 public void visit(harpoon.IR.Tree.Tree treee){
6630                         assert false : "Should never visit generic harpoon.IR.Tree.Treein CggVisitor";
6631                 } // end visit(harpoon.IR.Tree.Tree)
6632                 public void visit(harpoon.IR.Tree.Stm treee){
6633                         debug("munching "+treee+"       ");
6634                         munchStm(treee);
6635                 } // end visit(harpoon.IR.Tree.Stm)
6636                 public void visit(harpoon.IR.Tree.SEQ treee){
6637                         treee.getLeft().accept(this);
6638                         treee.getRight().accept(this);
6639                 }
6640         }
6641         CggVisitor visitor = new CggVisitor();
6642         harpoon.IR.Tree.Tree t = (harpoon.IR.Tree.Tree) code.getRootElement();
6643         t.accept(visitor);
6644                         clearDecl(); // reset temp type mappings
6645 
6646        // *** METHOD EPILOGUE *** 
6647    
6648 
6649         assert first != null : "Should always generate some instrs";
6650         return first;
6651         }
6652 }