Program: 150047
Project: 150047
Buggy source:
/** 
 * Explicitly copy parameters to a system call into the appropriate physical registers as defined by the calling convention.  Note that for a system call (ie., a call to C), the order of parameters on the stack is <em> reversed </em> compared to the normal RVM calling convention TODO: much of this code is exactly the same as in expandParametersToCall(). factor out the common code. Note: Assumes that ESP points to the word before the slot where the first parameter should be stored.
 */
private static int expandParametersToSysCall(OPT_Instruction call,OPT_IR ir){
  int nGPRParams=0;
  int nFPRParams=0;
  int parameterBytes=0;
  OPT_PhysicalRegisterSet phys=ir.regpool.getPhysicalRegisterSet();
  OPT_Register ESP=phys.getESP();
  int FPRRegisterParams=countFPRParams(call);
  FPRRegisterParams=Math.min(FPRRegisterParams,OPT_PhysicalRegisterSet.getNumberOfFPRParams());
  int numParams=MIR_Call.getNumberOfParams(call);
  for (int i=numParams - 1; i >= 0; i--) {
    OPT_Operand param=MIR_Call.getClearParam(call,i);
    MIR_Call.setParam(call,i,null);
    VM_TypeReference paramType=param.getType();
    if (paramType.isFloatType() || paramType.isDoubleType()) {
      nFPRParams++;
      int size=paramType.isFloatType() ? 4 : 8;
      parameterBytes-=size;
      OPT_Operand M=new OPT_StackLocationOperand(false,parameterBytes,size);
      call.insertBefore(MIR_Move.create(IA32_FMOV,M,param));
    }
 else {
      nGPRParams++;
      parameterBytes-=4;
      call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP,IC(parameterBytes + 4)));
      call.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH,param));
    }
  }
  return parameterBytes;
}

Fixed version (ground truth):
/** 
 * Explicitly copy parameters to a system call into the appropriate physical registers as defined by the calling convention.  Note that for a system call (ie., a call to C), the order of parameters on the stack is <em> reversed </em> compared to the normal RVM calling convention TODO: much of this code is exactly the same as in expandParametersToCall(). factor out the common code. Note: Assumes that ESP points to the word before the slot where the first parameter should be stored.
 */
private static int expandParametersToSysCall(OPT_Instruction call,OPT_IR ir){
  int nGPRParams=0;
  int nFPRParams=0;
  int parameterBytes=0;
  OPT_PhysicalRegisterSet phys=ir.regpool.getPhysicalRegisterSet();
  int numParams=MIR_Call.getNumberOfParams(call);
  for (int i=numParams - 1; i >= 0; i--) {
    OPT_Operand param=MIR_Call.getClearParam(call,i);
    MIR_Call.setParam(call,i,null);
    VM_TypeReference paramType=param.getType();
    if (paramType.isFloatType() || paramType.isDoubleType()) {
      nFPRParams++;
      int size=paramType.isFloatType() ? 4 : 8;
      parameterBytes-=size;
      OPT_Operand M=new OPT_StackLocationOperand(false,parameterBytes,size);
      call.insertBefore(MIR_Move.create(IA32_FMOV,M,param));
    }
 else {
      nGPRParams++;
      parameterBytes-=4;
      call.insertBefore(MIR_UnaryNoRes.create(REQUIRE_ESP,IC(parameterBytes + 4)));
      call.insertBefore(MIR_UnaryNoRes.create(IA32_PUSH,param));
    }
  }
  return parameterBytes;
}