asm.emitLWZ (T2, VM_Entrypoints.JNIRefsSavedFPField.getOffset(), S0);
asm.emitLInt (T2, VM_Entrypoints.JNIRefsSavedFPField.getOffset(), S0);
  public static synchronized VM_CompiledMethod compile (VM_NativeMethod method) {    VM_JNICompiledMethod cm = (VM_JNICompiledMethod)VM_CompiledMethods.createCompiledMethod(method, VM_CompiledMethod.JNI);    int compiledMethodId = cm.getId();    VM_Assembler asm	= new VM_Assembler(0);    int frameSize	= VM_Compiler.getFrameSize(method);    VM_Class klass	= method.getDeclaringClass();    /* initialization */    if (VM.VerifyAssertions) VM._assert(T3 <= LAST_VOLATILE_GPR);           // need 4 gp temps    if (VM.VerifyAssertions) VM._assert(F3 <= LAST_VOLATILE_FPR);           // need 4 fp temps    if (VM.VerifyAssertions) VM._assert(S0 < S1 && S1 <= LAST_SCRATCH_GPR); // need 2 scratch    VM_Address nativeIP  = method.getNativeIP();    VM_Address nativeTOC = method.getNativeTOC();    // NOTE:  this must be done before the condition VM_Thread.hasNativeStackFrame() become true    // so that the first Java to C transition will be allowed to resize the stack    // (currently, this is true when the JNIRefsTop index has been incremented from 0)    asm.emitNativeStackOverflowCheck(frameSize + 14);   // add at least 14 for C frame (header + spill)    int parameterAreaSize = method.getParameterWords() <<LOG_BYTES_IN_STACKSLOT;   // number of bytes of arguments    asm.emitMFLR(0);                                // save return address in caller frame    asm.emitSTAddr(0, STACKFRAME_NEXT_INSTRUCTION_OFFSET, FP);	// this was set up the first time by DynamicBridgeTo()      //-#if RVM_FOR_LINUX || RVM_FOR_OSX    // buy mini frame (2)    asm.emitSTAddrU   (FP, -JNI_SAVE_AREA_SIZE, FP);    asm.emitLVAL  (S0, compiledMethodId);                // save jni method id at mini frame (2)    asm.emitSTW   (S0, STACKFRAME_METHOD_ID_OFFSET, FP);    // buy mini frame (1), the total size equals to frameSize    asm.emitSTAddrU   (FP, -frameSize + JNI_SAVE_AREA_SIZE, FP);    //-#endif	    //-#if RVM_FOR_AIX    asm.emitSTAddrU   (FP,  -frameSize, FP);             // get transition frame on stack    asm.emitLVAL  (S0, compiledMethodId);                // save jni method id    asm.emitSTW   (S0, STACKFRAME_METHOD_ID_OFFSET, FP);    //-#endif    asm.emitSTAddr (JTOC, frameSize - JNI_JTOC_OFFSET, FP);    // save RVM JTOC in frame    asm.emitSTAddr(PROCESSOR_REGISTER, frameSize - JNI_PR_OFFSET, FP);  // save PR in frame //Kris Venstermans :Correct? is Address?     // establish S1 -> VM_Thread, S0 -> threads JNIEnv structure          asm.emitLAddr(S1, VM_Entrypoints.activeThreadField.getOffset(), PROCESSOR_REGISTER);    asm.emitLAddr(S0, VM_Entrypoints.jniEnvField.getOffset(), S1);    // save the TI & PR registers in the JNIEnvironment object for possible calls back into Java    asm.emitSTAddr(TI, VM_Entrypoints.JNIEnvSavedTIField.getOffset(), S0);               asm.emitSTAddr(PROCESSOR_REGISTER, VM_Entrypoints.JNIEnvSavedPRField.getOffset(), S0);       // save current frame pointer in JNIEnv, JNITopJavaFP, which will be the frame    // to start scanning this stack during GC, if top of stack is still executing in C    //-#if RVM_FOR_LINUX || RVM_FOR_OSX    // for Linux, save mini (2) frame pointer, which has method id    asm.emitLAddr (PROCESSOR_REGISTER, 0, FP);    asm.emitSTAddr(PROCESSOR_REGISTER, VM_Entrypoints.JNITopJavaFPField.getOffset(), S0);    //-#elif RVM_FOR_AIX    asm.emitSTAddr(FP, VM_Entrypoints.JNITopJavaFPField.getOffset(), S0);               //-#endif	    // save the RVM nonvolatile registers, to be scanned by GC stack mapper    // remember to skip past the saved JTOC  by starting with offset = JNI_RVM_NONVOLATILE_OFFSET    //    for (int i = LAST_NONVOLATILE_GPR, offset = JNI_RVM_NONVOLATILE_OFFSET;	 i >= FIRST_NONVOLATILE_GPR; --i, offset+=BYTES_IN_STACKSLOT) {      asm.emitSTAddr(i, frameSize - offset, FP);    }    // clear the GC flag on entry to native code    asm.emitLVAL(PROCESSOR_REGISTER,0);          // use PR as scratch    asm.emitSTW(PROCESSOR_REGISTER, frameSize-JNI_GC_FLAG_OFFSET, FP); //Kris Venstermans : How big is flag?     // generate the code to map the parameters to AIX convention and add the    // second parameter 2 (either the "this" ptr or class if a static method).    // The JNI Function ptr first parameter is set before making the call.    // Opens a new frame in the JNIRefs table to register the references    // Assumes S0 set to JNIEnv, kills TI, S1 & PROCESSOR_REGISTER    // On return, S0 is still valid.    //-#if RVM_FOR_LINUX    storeParametersForLinux(asm, frameSize, method, klass);    //-#elif RVM_FOR_OSX    storeParametersForOSX(asm, frameSize, method, klass);    //-#elif RVM_FOR_AIX    storeParametersForAIX(asm, frameSize, method, klass);    //-#endif	    // Get address of out_of_line prolog into S1, before setting TOC reg.    asm.emitLAddr (S1, VM_Entrypoints.invokeNativeFunctionInstructionsField.getOffset(), JTOC);    asm.emitMTLR  (S1);    // set the TOC and IP for branch to out_of_line code    asm.emitLVALAddr (JTOC,  nativeTOC);         // load TOC for native function into TOC reg    asm.emitLVALAddr (TI,    nativeIP);	      // load TI with address of native code    // go to part of prologue that is in the boot image. It will change the Processor    // status to "in_native" and transfer to the native code.  On return it will    // change the state back to "in_java" (waiting if blocked).    //    // The native address entrypoint is in register TI    // The native TOC has been loaded into the TOC register    // S0 still points to threads JNIEnvironment    //    asm.emitBCLRL  ();    // restore PR, saved in this glue frame before the call. If GC occurred, this saved    // VM_Processor reference was relocated while scanning this stack.    //    asm.emitLAddr(PROCESSOR_REGISTER, frameSize - JNI_PR_OFFSET, FP);      // check if GC has occurred, If GC did not occur, then     // VM NON_VOLATILE regs were restored by AIX and are valid.  If GC did occur    // objects referenced by these restored regs may have moved, in this case we    // restore the nonvolatile registers from our savearea,    // where any object references would have been relocated during GC.    // use T2 as scratch (not needed any more on return from call)    //    asm.emitLWZ(T2, frameSize - JNI_GC_FLAG_OFFSET, FP);    asm.emitCMPI(T2,0);    VM_ForwardReference fr1 = asm.emitForwardBC(EQ);    for (int i = LAST_NONVOLATILE_GPR, offset = JNI_RVM_NONVOLATILE_OFFSET;	 i >= FIRST_NONVOLATILE_GPR; --i, offset+=BYTES_IN_STACKSLOT) {      asm.emitLAddr(i, frameSize - offset, FP);    }    fr1.resolve(asm);    asm.emitLAddr(S0, VM_Entrypoints.activeThreadField.getOffset(), PROCESSOR_REGISTER);  // S0 holds thread pointer    // reestablish S0 to hold jniEnv pointer    asm.emitLAddr(S0, VM_Entrypoints.jniEnvField.getOffset(), S0);           // pop jrefs frame off the JNIRefs stack, "reopen" the previous top jref frame    // use S1 as scratch before it's restored, also use T2, T3 for scratch which are no longer needed    asm.emitLAddr(S1, VM_Entrypoints.JNIRefsField.getOffset(), S0);          // load base of JNIRefs array    asm.emitLWZ (T2, VM_Entrypoints.JNIRefsSavedFPField.getOffset(), S0);   // get saved offset for JNIRefs frame ptr previously pushed onto JNIRefs array    asm.emitADDI(T3, -BYTES_IN_STACKSLOT, T2);                                    // compute offset for new TOP    asm.emitSTW(T3, VM_Entrypoints.JNIRefsTopField.getOffset(), S0);       // store new offset for TOP into JNIEnv    asm.emitLAddrX (T2, S1, T2);                                    // retrieve the previous frame ptr    asm.emitSTW(T2, VM_Entrypoints.JNIRefsSavedFPField.getOffset(), S0);   // store new offset for JNIRefs frame ptr into JNIEnv    // Restore the return value R3-R4 saved in the glue frame spill area before the migration    if (VM.BuildFor64Addr) {      asm.emitLD(T0, NATIVE_FRAME_HEADER_SIZE, FP);    } else {      asm.emitLWZ(T0, NATIVE_FRAME_HEADER_SIZE, FP);      asm.emitLWZ(T1, NATIVE_FRAME_HEADER_SIZE+BYTES_IN_STACKSLOT, FP);    }          // if the the return type is a reference, the native C is returning a jref    // which is a byte offset from the beginning of the threads JNIRefs stack/array    // of the corresponding ref.  In this case, emit code to replace the returned    // offset (in R3) with the ref from the JNIRefs array    VM_TypeReference returnType = method.getReturnType();    if (returnType.isReferenceType()) {      // use returned offset to load ref from JNIRefs into R3      asm.emitLAddrX (3, S1, 3);         // S1 is still the base of the JNIRefs array    }    // reload TI ref saved in JNIEnv    asm.emitLAddr(TI, VM_Entrypoints.JNIEnvSavedTIField.getOffset(), S0);               // pop the glue stack frame, restore the Java caller frame    asm.emitADDI (FP,  +frameSize, FP);              // remove linkage area    // C return value is already where caller expected it (R3, R4 or F0)    // and S1 is a scratch register, so we actually don't have to     // restore it and/or pop arguments off it.    // So, just restore the return address to the link register.    asm.emitLAddr(0, STACKFRAME_NEXT_INSTRUCTION_OFFSET, FP);     asm.emitMTLR(0);                           // restore return address    // CHECK EXCEPTION AND BRANCH TO ATHROW CODE OR RETURN NORMALLY    asm.emitLWZ (T2, VM_Entrypoints.JNIPendingExceptionField.getOffset(), S0);   // get pending exception from JNIEnv    asm.emitLVAL(T3, 0);                   // get a null value to compare    asm.emitSTW (T3, VM_Entrypoints.JNIPendingExceptionField.getOffset(), S0); // clear the current pending exception    asm.emitCMP (T2, T3);                      // check for pending exception on return from native    VM_ForwardReference fr3 = asm.emitForwardBC(NE);    asm.emitBCLR();                             // if no pending exception, proceed to return to caller    fr3.resolve(asm);    // An exception is pending, deliver the exception to the caller as if executing an athrow in the caller    // at the location of the call to the native method    asm.emitLAddrToc(T3, VM_Entrypoints.athrowMethod.getOffset());    asm.emitMTCTR(T3);                         // point LR to the exception delivery code    asm.emitMR (T0, T2);                       // copy the saved exception to T0    asm.emitBCCTR();                            // then branch to the exception delivery code, does not return    VM_MachineCode machineCode = asm.makeMachineCode();    cm.compileComplete(machineCode.getInstructions());//     if (XXX_TRACE) {//       VM_CodeArray xxxinstructions = machineCode.getInstructions();//       for (int xxxi=0;  xxxi < xxxinstructions.length; xxxi++)//         VM.sysWrite(""+java.lang.Integer.toHexString(xxxinstructions[xxxi])+"\n");//     }    return cm;  } 