// Ranjay but needs to be optimized
 private static Instruction handleArguments(CallIR call, TempTable tTable) {
   Instruction inst = new Instruction();
   // Now that we have saved the caller-saved registers we get the tilings
   // for the arguments given to the function
   ArrayList<ExpressionInstruction> argumentTileLists = new ArrayList<ExpressionInstruction>();
   for (int i = 1; i < call.getChildren().size(); i++) {
     argumentTileLists.add(
         (ExpressionInstruction) generateTile((SyntaxIR) call.getChildren().get(i), tTable));
   }
   // Now that we have the arguments we must push them on the stack and or registers
   AddressingMode addr12 = new AddressingMode("r12");
   AddressingMode addrR9 = new AddressingMode("r9");
   AddressingMode addrR8 = new AddressingMode("r8");
   AddressingMode addrRDX = new AddressingMode("rdx");
   AddressingMode addrRCX = new AddressingMode("rcx");
   AddressingMode addrRSI = new AddressingMode("rsi");
   AddressingMode addrRDI = new AddressingMode("rdi");
   int retsize = call.getretsize();
   if (retsize > 1) {
     CallIR c = new CallIR(new NameIR("_I_alloc_i"), new ConstIR(8 * (retsize + 1)));
     c.setretsize(1);
     ExpressionInstruction ex = (ExpressionInstruction) generateTile(c, tTable);
     inst.addAll(ex.getTiles());
     inst.add(new Tile(1, "movq", ex.getAddr(), new AddressingMode("rcx")));
     inst.add(new Tile(1, "movq", new AddressingMode(retsize), new AddressingMode(0, "rcx")));
     inst.add(new Tile(1, "add", new AddressingMode(8), new AddressingMode("rcx")));
   }
   if ((argumentTileLists.size() <= 4 && retsize <= 1)
       || (argumentTileLists.size() <= 3 && retsize > 1)) {
     for (int i = 0; i < argumentTileLists.size(); i++) {
       inst.addAll(argumentTileLists.get(i).getTiles());
       inst.add(new Tile(1, "pushq", argumentTileLists.get(i).getAddr(), null));
     }
   } else {
     if (retsize > 1) {
       for (int i = argumentTileLists.size() - 1; i >= 3; i--) {
         inst.addAll(argumentTileLists.get(i).getTiles());
         inst.add(new Tile(1, "pushq", argumentTileLists.get(i).getAddr(), null));
       }
       for (int i = 0; i < 3; i++) {
         inst.addAll(argumentTileLists.get(i).getTiles());
         inst.add(new Tile(1, "pushq", argumentTileLists.get(i).getAddr(), null));
       }
     } else {
       for (int i = argumentTileLists.size() - 1; i >= 4; i--) {
         inst.addAll(argumentTileLists.get(i).getTiles());
         inst.add(new Tile(1, "pushq", argumentTileLists.get(i).getAddr(), null));
       }
       for (int i = 0; i < 4; i++) {
         inst.addAll(argumentTileLists.get(i).getTiles());
         inst.add(new Tile(1, "pushq", argumentTileLists.get(i).getAddr(), null));
       }
     }
   }
   switch (argumentTileLists.size()) {
     case 4:
       if (retsize <= 1) {
         inst.add(new Tile(1, "popq", addrR9, null));
       }
     case 3:
       if (retsize > 1) {
         inst.add(new Tile(1, "popq", addrR9, null));
       } else {
         inst.add(new Tile(1, "popq", addrR8, null));
       }
     case 2:
       if (retsize > 1) {
         inst.add(new Tile(1, "popq", addrR8, null));
       } else {
         inst.add(new Tile(1, "popq", addrRDX, null));
       }
     case 1:
       if (retsize > 1) {
         inst.add(new Tile(1, "popq", addrRDX, null));
       } else {
         inst.add(new Tile(1, "popq", addrRCX, null));
       }
     case 0:
       // Do nothing
       break;
     default: // we have more than five arguments
       // push the first 6 arguments to registers
       // and we're not using RDI (not returning a tuple)
       if (retsize <= 1) {
         inst.add(new Tile(1, "popq", addrR9, null));
         inst.add(new Tile(1, "popq", addrR8, null));
         inst.add(new Tile(1, "popq", addrRDX, null));
         inst.add(new Tile(1, "popq", addrRCX, null));
       }
       // we're returning a tuple
       else {
         inst.add(new Tile(1, "popq", addrR9, null));
         inst.add(new Tile(1, "popq", addrR8, null));
         inst.add(new Tile(1, "popq", addrRDX, null));
       }
   }
   return inst;
 }
 // Ranjay
 public static ExpressionInstruction generateTile(OpIR op, TempTable tTable) {
   ExpressionInstruction inst = new ExpressionInstruction();
   if (op.getChildren().size() > 1) {
     ExpressionInstruction child1 =
         (ExpressionInstruction) generateTile((SyntaxIR) op.getChildren().get(0), tTable);
     ExpressionInstruction child2 =
         (ExpressionInstruction) generateTile((SyntaxIR) op.getChildren().get(1), tTable);
     inst.addAll(child1.getTiles());
     inst.add(new Tile(1, "pushq", child1.getAddr(), null));
     inst.addAll(child2.getTiles());
     inst.add(new Tile(1, "movq", child2.getAddr(), new AddressingMode("r12")));
     inst.add(new Tile(1, "popq", new AddressingMode("r13"), null));
     if (op.getOp() == opEnum.DIVIDE || op.getOp() == opEnum.MODULO) {
       inst.add(new Tile(1, "pushq", new AddressingMode("rdx"), null));
       inst.add(new Tile(1, "pushq", new AddressingMode("rax"), null));
       inst.add(new Tile(1, "movq", new AddressingMode("r13"), new AddressingMode("rax")));
       // we need to sign extend r13 into rdx
       inst.add(new Tile(1, "cmp", new AddressingMode(0), new AddressingMode("r13")));
       // if r12 is less than 0 we move FFFFFFFFFFFFFFFF to rdx otherwise move zero
       int div = tTable.getNewJumpLabel();
       inst.add(new Tile(1, "jl", new AddressingMode("div" + div, true), null));
       // fall through to moving zero
       inst.add(new Tile(1, "movq", new AddressingMode(0), new AddressingMode("rdx")));
       inst.add(new Tile(1, "jmp", new AddressingMode("divEnd" + div, true), null));
       inst.add(new Tile(1, "div" + div + ":", null, null));
       inst.add(new Tile(1, "movq", new AddressingMode(-1), new AddressingMode("rdx")));
       inst.add(new Tile(1, "divEnd" + div + ":", null, null));
       inst.add(new Tile(1, "idiv", new AddressingMode("r12"), null));
       // The result is put in RAX so we need to push that on the stack
       if (op.getOp() == opEnum.DIVIDE)
         inst.add(new Tile(1, "movq", new AddressingMode("rax"), new AddressingMode("r12")));
       else inst.add(new Tile(1, "movq", new AddressingMode("rdx"), new AddressingMode("r12")));
       inst.add(new Tile(1, "popq", new AddressingMode("rax"), null));
       inst.add(new Tile(1, "popq", new AddressingMode("rdx"), null));
       inst.setAddr(new AddressingMode("r12"));
     } else if (op.returnsBool() && op.getOp() != opEnum.AND && op.getOp() != opEnum.OR) {
       int x = tTable.getNewJumpLabel();
       inst.add(new Tile(1, "cmp", new AddressingMode("r12"), new AddressingMode("r13")));
       inst.add(new Tile(1, op.opToAssembly(), new AddressingMode("_true" + x, true), null));
       inst.add(new Tile(1, "movq", new AddressingMode(0), new AddressingMode("r12")));
       inst.add(new Tile(1, "jmp", new AddressingMode("_end" + x, true), null));
       inst.add(new Tile(1, "_true" + x + ": ", null, null));
       inst.add(new Tile(1, "movq", new AddressingMode(1), new AddressingMode("r12")));
       inst.add(new Tile(1, "_end" + x + ": ", null, null));
       inst.setAddr(new AddressingMode("r12"));
     } else if (op.getOp() == opEnum.LSHIFT || op.getOp() == opEnum.RSHIFT) {
       inst.add(new Tile(1, op.opToAssembly(), new AddressingMode(3), new AddressingMode("r13")));
       inst.setAddr(new AddressingMode("r13"));
     } else {
       inst.add(
           new Tile(1, op.opToAssembly(), new AddressingMode("r12"), new AddressingMode("r13")));
       inst.setAddr(new AddressingMode("r13"));
     }
   } else {
     ExpressionInstruction child =
         (ExpressionInstruction) generateTile((SyntaxIR) op.getChildren().get(0), tTable);
     inst.addAll(child.getTiles());
     switch (op.getOp()) {
       case NOT:
         inst.add(new Tile(1, "btc", new AddressingMode(0), child.getAddr()));
         inst.setAddr(child.getAddr());
         break;
       case UNARY_MINUS:
         inst.add(new Tile(1, "neg", child.getAddr(), null));
         inst.setAddr(child.getAddr());
         break;
     }
   }
   return inst;
 }