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 }