loword = addr.loadWord();
int loword = addr.loadInt();
  static Object[] packageParameterFromVarArg(VM_Method targetMethod, Address argAddress) {    VM_TypeReference[] argTypes = targetMethod.getParameterTypes();    int argCount = argTypes.length;    Object[] argObjectArray = new Object[argCount];    // get the VM_JNIEnvironment for this thread in case we need to dereference any object arg    VM_JNIEnvironment env = VM_Thread.getCurrentThread().getJNIEnv();    // VM.sysWrite("JNI packageParameterFromVarArg: packaging " + argCount + " arguments\n");    Address addr = argAddress;    for (int i=0; i<argCount; i++) {      Word loword, hiword;      hiword = addr.loadWord();      // VM.sysWrite("JNI packageParameterFromVarArg:  arg " + i + " = " + hiword +       // " or " + VM.intAsHexString(hiword) + "\n");      addr = addr.add(BYTES_IN_ADDRESS);      // convert and wrap the argument according to the expected type      if (argTypes[i].isFloatType()) {        // NOTE:  in VarArg convention, C compiler will expand a float to a double that occupy 2 words        // so we have to extract it as a double and convert it back to a float        if (VM.BuildFor32Addr) {          loword = addr.loadWord();          addr = addr.add(BYTES_IN_ADDRESS);                                 long doubleBits = (((long) hiword.toInt()) << BITS_IN_INT) | (loword.toInt() & 0xFFFFFFFFL);          argObjectArray[i] = VM_Reflection.wrapFloat((float) (Double.longBitsToDouble(doubleBits)));        } else {          argObjectArray[i] = VM_Reflection.wrapFloat((float) (Double.longBitsToDouble(hiword.toLong())));        }      } else if (argTypes[i].isDoubleType()) {        if (VM.BuildFor32Addr) {          loword = addr.loadWord();          addr = addr.add(BYTES_IN_ADDRESS);          long doubleBits = (((long) hiword.toInt()) << BITS_IN_INT) | (loword.toInt() & 0xFFFFFFFFL);          argObjectArray[i] = VM_Reflection.wrapDouble(Double.longBitsToDouble(doubleBits));        } else {          argObjectArray[i] = VM_Reflection.wrapDouble(Double.longBitsToDouble(hiword.toLong()));        }      } else if (argTypes[i].isLongType()) {         if (VM.BuildFor32Addr) {          loword = addr.loadWord();          addr = addr.add(BYTES_IN_ADDRESS);          long longValue = (((long) hiword.toInt()) << BITS_IN_INT) | (loword.toInt() & 0xFFFFFFFFL);          argObjectArray[i] = VM_Reflection.wrapLong(longValue);        } else {          argObjectArray[i] = VM_Reflection.wrapLong(hiword.toLong());        }      } else if (argTypes[i].isBooleanType()) {        // the 0/1 bit is stored in the high byte               argObjectArray[i] = VM_Reflection.wrapBoolean(hiword.toInt());      } else if (argTypes[i].isByteType()) {        // the target byte is stored in the high byte        argObjectArray[i] = VM_Reflection.wrapByte((byte) hiword.toInt());      } else if (argTypes[i].isCharType()) {        // char is stored in the high 2 bytes        argObjectArray[i] = VM_Reflection.wrapChar((char) hiword.toInt());      } else if (argTypes[i].isShortType()) {        // short is stored in the high 2 bytes        argObjectArray[i] = VM_Reflection.wrapShort((short) hiword.toInt());      } else if (argTypes[i].isReferenceType()) {        // for object, the arg is a JREF index, dereference to get the real object        argObjectArray[i] =  env.getJNIRef(hiword.toInt());         } else if (argTypes[i].isIntType()) {        argObjectArray[i] = VM_Reflection.wrapInt(hiword.toInt());      } else {        return null;      }    }    return argObjectArray;  }