ir.MIRInfo.fpStackHeight = Math.max(ir.MIRInfo.fpStackHeight, FPRRegisterParams);
  private static void expandPrologue(OPT_IR ir) {    if (ir.options.SIMPLE_OPT) {      // set up register lists for dead code elimination.      OPT_DefUse.computeDU(ir);    }        OPT_Instruction p = ir.firstInstructionInCodeOrder().      nextInstructionInCodeOrder();    if (VM.VerifyAssertions) VM.assert(p.operator == IR_PROLOGUE);    OPT_Instruction start = p.nextInstructionInCodeOrder();    OPT_PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();    int gprIndex = 0;     int fprIndex = 0;     int paramByteOffset = ir.incomingParameterBytes() + 8;    // count the number of FPR params in a pre-pass    int FPRRegisterParams= countFPRParamsInPrologue(p);    FPRRegisterParams = Math.min(FPRRegisterParams, phys.getNumberOfFPRParams());    // deal with each parameter    for (OPT_OperandEnumeration e = p.getDefs(); e.hasMoreElements(); ) {      OPT_RegisterOperand symbOp = (OPT_RegisterOperand)e.nextElement();      VM_Type rType = symbOp.type;      if (rType.isFloatType() || rType.isDoubleType()) {	int size = rType.isFloatType() ? 4 : 8;	paramByteOffset -= size;        // if optimizing, only define the register if it has uses        if (!ir.options.SIMPLE_OPT || symbOp.register.useList != null) {          if (fprIndex < phys.getNumberOfFPRParams()) {            // insert a MOVE symbolic register = parameter            // Note that if k FPRs are passed in registers,             // the 1st goes in F(k-1),            // the 2nd goes in F(k-2), etc...            OPT_Register param = 	      phys.getFPRParam(FPRRegisterParams - fprIndex - 1);            start.insertBefore(MIR_Move.create(IA32_FMOV,symbOp.copyRO(),					       D(param)));          } else {	    OPT_Operand M = 	      new OPT_StackLocationOperand(true, paramByteOffset, size);	    start.insertBefore(MIR_Move.create(IA32_FMOV, symbOp.copyRO(), M));          }        }        fprIndex++;      } else {        // if optimizing, only define the register if it has uses	paramByteOffset -= 4;        if (!ir.options.SIMPLE_OPT || symbOp.register.useList != null) {          // t is object, 1/2 of a long, int, short, char, byte, or boolean          if (gprIndex < phys.getNumberOfGPRParams()) {	    // to give the register allocator more freedom, we	    // insert two move instructions to get the physical into	    // the symbolic.  First a move from the physical to a fresh temp 	    // before start and second a move from the temp to the	    // 'real' parameter symbolic after start.	    OPT_RegisterOperand tmp = ir.gc.temps.makeTemp(rType);            OPT_Register param = phys.getGPRParam(gprIndex);	    OPT_RegisterOperand pOp = new OPT_RegisterOperand(param, rType);            start.insertBefore(OPT_PhysicalRegisterTools.makeMoveInstruction(tmp,pOp));	    OPT_Instruction m2 = OPT_PhysicalRegisterTools.makeMoveInstruction(symbOp.copyRO(),tmp.copyD2U());	    start.insertBefore(m2);	    start = m2;          } else {	    OPT_Operand M = 	      new OPT_StackLocationOperand(true, paramByteOffset, 4);	    start.insertBefore(MIR_Move.create(IA32_MOV, symbOp.copyRO(), M));          }        }        gprIndex++;      }    }    if (VM.VerifyAssertions) VM.assert(paramByteOffset == 8, "pb = "+paramByteOffset);        // Now that we've made the calling convention explicit in the prologue,    // set IR_PROLOGUE to have no defs.    p.replace(Prologue.create(IR_PROLOGUE, 0));  }