* src/vm/jit/powerpc/md.c (md_patch_replacement_point): Added.
authoredwin <none@none>
Sat, 18 Mar 2006 04:14:17 +0000 (04:14 +0000)
committeredwin <none@none>
Sat, 18 Mar 2006 04:14:17 +0000 (04:14 +0000)
* src/vm/jit/powerpc/codegen.c (codegen): Handle replacement points.

* src/vm/jit/powerpc/asmpart.S (asm_replacement_out): Added.
(asm_replacement_in): Likewise.

* src/vm/jit/alpha/codegen.c (codegen): Added missing initialization
of `replacementpoint`.

* src/vm/jit/alpha/asmpart.S (asm_replacement_out): Store PV register.

* src/vm/jit/code.c (code_get_sync_slot_count): Ported to PowerPC.
(code_get_stack_frame_size): Likewise.

* src/vm/jit/replace.c (replace_activate_replacement_point)
(replace_deactivate_replacement_poin): Activated for PowerPC.
(replace_read_value, replace_write_value): Added.
(replace_read_executionstate): Ported to PowerPC, more complete
data type handling.
(replace_write_executionstate): Ported to Ported, more complete
data type handling, fixed missing initialization of `topslot`.
(replace_me): Activated for PowerPC.

src/vm/jit/alpha/asmpart.S
src/vm/jit/alpha/codegen.c
src/vm/jit/code.c
src/vm/jit/powerpc/asmpart.S
src/vm/jit/powerpc/codegen.c
src/vm/jit/powerpc/md.c
src/vm/jit/replace.c

index c555674cbcfc06298a61ffe6fc264884a6ac5425..941195a83007ada5449ab1cadc902de74f0fba07 100644 (file)
@@ -31,7 +31,7 @@
             Christian Thalinger
                Edwin Steiner
 
-   $Id: asmpart.S 4649 2006-03-16 20:31:54Z edwin $
+   $Id: asmpart.S 4653 2006-03-18 04:14:17Z edwin $
 
 */
 
@@ -659,6 +659,9 @@ asm_replacement_out:
        lda     itmp1,(sizeexecutionstate + REPLACEMENT_ROOM + 8)(sp)
        stq     itmp1,(offes_sp)(sp)
 
+       /* store pv */
+       stq     pv,(offes_pv)(sp)
+
        /* call replace_me */
        ldq     a0,-8(itmp1)                /* arg0: rplpoint *                   */
     mov     sp,a1                       /* arg1: execution state              */
index d3cf23b399584235cae28dfc14315daaa693bd5a..5ac5add885f650580b394e4fe8dae0fce8df3d86 100644 (file)
@@ -32,7 +32,7 @@
             Christian Ullrich
             Edwin Steiner
 
-   $Id: codegen.c 4652 2006-03-16 23:32:17Z edwin $
+   $Id: codegen.c 4653 2006-03-18 04:14:17Z edwin $
 
 */
 
@@ -356,6 +356,8 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        /* end of header generation */
 
+       replacementpoint = cd->code->rplpoints;
+
        /* walk through all basic blocks */
 
        for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
index 0ff3a43502561a85186955a3692badb7814a0be0..5297c32e032676a7e5bff3052e2010eda90ab4bc 100644 (file)
@@ -91,23 +91,36 @@ codeinfo *code_codeinfo_new(methodinfo *m)
 
 int code_get_sync_slot_count(codeinfo *code)
 {
+#ifdef USE_THREADS
+       int count;
+       
        assert(code);
 
-#ifdef USE_THREADS
        if (!checksync)
                return 0;
 
        if (!(code->m->flags & ACC_SYNCHRONIZED))
                return 0;
 
-       /* XXX generalize to all archs */
+       count = 1;
+
 #ifdef HAS_4BYTE_STACKSLOT
-       return (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type)) ? 2 : 1;
-#else
-       return 1;
+       /* long and double need 2 4-byte slots */
+       if (IS_2_WORD_TYPE(code->m->parseddesc->returntype.type))
+               count++;
+#endif
+
+#if defined(__POWERPC__)
+       /* powerpc needs an extra slot */
+       count++;
 #endif
+
+       return count;
+
 #else /* !USE_THREADS */
+       
        return 0;
+
 #endif /* USE_THREADS */
 }
 
@@ -138,19 +151,24 @@ int code_get_stack_frame_size(codeinfo *code)
        
        assert(code);
 
-       /* XXX generalize to all archs */
 #ifdef HAS_4BYTE_STACKSLOT
        count = code->memuse + code->savedintcount + 2*code->savedfltcount;
 #else
        count = code->memuse + code->savedintcount + code->savedfltcount;
 #endif
 
+       /* add slots needed in synchronized methods */
        count += code_get_sync_slot_count(code);
 
 #if defined(__X86_64__)
        /* keep stack 16-byte aligned */
        if (!code->isleafmethod || opt_verbosecall)
-               count |= 1;
+               count |= 1; /* even when return address is added */
+#endif
+
+#if defined(__POWERPC__)
+       /* keep stack 16-byte aligned */
+       count = (count + 3) & ~3;
 #endif
 
        return count;
index fc01fcf2173a8f8e5f5d2c37616237df5749a743..e556950c5c50d091348df4c2a6bd5424a7314e32 100644 (file)
@@ -29,8 +29,9 @@
             Stefan Ring
 
    Changes: Christian Thalinger
+                       Edwin Steiner
 
-   $Id: asmpart.S 4562 2006-03-06 00:30:36Z twisti $
+   $Id: asmpart.S 4653 2006-03-18 04:14:17Z edwin $
 
 */
 
@@ -65,6 +66,9 @@
 
        .globl asm_wrapper_patcher
 
+       .globl asm_replacement_out
+       .globl asm_replacement_in
+
        .globl asm_cacheflush
        .globl asm_initialize_thread_stack
        .globl asm_perform_threadswitch
@@ -847,6 +851,221 @@ L_asm_wrapper_patcher_exception:
        b       L_asm_handle_exception
 
 
+/* asm_replacement_out *********************************************************
+
+   This code is jumped to from the replacement-out stubs that are executed
+   when a thread reaches an activated replacement point.
+
+   The purpose of asm_replacement_out is to read out the parts of the
+   execution state that cannot be accessed from C code, store this state,
+   and then call the C function replace_me.
+
+   Stack layout:
+      8                 start of stack inside method to replace
+      0   rplpoint *    info on the replacement point that was reached
+
+   NOTE: itmp3 has been clobbered by the replacement-out stub!
+
+*******************************************************************************/
+
+/* some room to accomodate changes of the stack frame size during replacement */
+       /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM  512
+
+asm_replacement_out:
+    /* create stack frame */
+       addi    sp,sp,-(sizeexecutionstate + REPLACEMENT_ROOM) /* XXX align */
+
+       /* save link register */
+       mflr    r16
+
+       /* save registers in execution state */
+       stw     r0 ,( 0*8+offes_intregs)(sp)
+       stw     r1 ,( 1*8+offes_intregs)(sp)
+       stw     r2 ,( 2*8+offes_intregs)(sp)
+       stw     r3 ,( 3*8+offes_intregs)(sp)
+       stw     r4 ,( 4*8+offes_intregs)(sp)
+       stw     r5 ,( 5*8+offes_intregs)(sp)
+       stw     r6 ,( 6*8+offes_intregs)(sp)
+       stw     r7 ,( 7*8+offes_intregs)(sp)
+       stw     r8 ,( 8*8+offes_intregs)(sp)
+       stw     r9 ,( 9*8+offes_intregs)(sp)
+       stw     r10,(10*8+offes_intregs)(sp)
+       stw     r11,(11*8+offes_intregs)(sp)
+       stw     r12,(12*8+offes_intregs)(sp)
+       stw     r13,(13*8+offes_intregs)(sp)
+       stw     r14,(14*8+offes_intregs)(sp)
+       stw     r15,(15*8+offes_intregs)(sp)
+       stw     r16,(16*8+offes_intregs)(sp) /* link register */
+       stw     r17,(17*8+offes_intregs)(sp)
+       stw     r18,(18*8+offes_intregs)(sp)
+       stw     r19,(19*8+offes_intregs)(sp)
+       stw     r20,(20*8+offes_intregs)(sp)
+       stw     r21,(21*8+offes_intregs)(sp)
+       stw     r22,(22*8+offes_intregs)(sp)
+       stw     r23,(23*8+offes_intregs)(sp)
+       stw     r24,(24*8+offes_intregs)(sp)
+       stw     r25,(25*8+offes_intregs)(sp)
+       stw     r26,(26*8+offes_intregs)(sp)
+       stw     r27,(27*8+offes_intregs)(sp)
+       stw     r28,(28*8+offes_intregs)(sp)
+       stw     r29,(29*8+offes_intregs)(sp)
+       stw     r30,(30*8+offes_intregs)(sp)
+       stw     r31,(31*8+offes_intregs)(sp)
+       
+       stfd    fr0 ,( 0*8+offes_fltregs)(sp)
+       stfd    fr1 ,( 1*8+offes_fltregs)(sp)
+       stfd    fr2 ,( 2*8+offes_fltregs)(sp)
+       stfd    fr3 ,( 3*8+offes_fltregs)(sp)
+       stfd    fr4 ,( 4*8+offes_fltregs)(sp)
+       stfd    fr5 ,( 5*8+offes_fltregs)(sp)
+       stfd    fr6 ,( 6*8+offes_fltregs)(sp)
+       stfd    fr7 ,( 7*8+offes_fltregs)(sp)
+       stfd    fr8 ,( 8*8+offes_fltregs)(sp)
+       stfd    fr9 ,( 9*8+offes_fltregs)(sp)
+       stfd    fr10,(10*8+offes_fltregs)(sp)
+       stfd    fr11,(11*8+offes_fltregs)(sp)
+       stfd    fr12,(12*8+offes_fltregs)(sp)
+       stfd    fr13,(13*8+offes_fltregs)(sp)
+       stfd    fr14,(14*8+offes_fltregs)(sp)
+       stfd    fr15,(15*8+offes_fltregs)(sp)
+       stfd    fr16,(16*8+offes_fltregs)(sp)
+       stfd    fr17,(17*8+offes_fltregs)(sp)
+       stfd    fr18,(18*8+offes_fltregs)(sp)
+       stfd    fr19,(19*8+offes_fltregs)(sp)
+       stfd    fr20,(20*8+offes_fltregs)(sp)
+       stfd    fr21,(21*8+offes_fltregs)(sp)
+       stfd    fr22,(22*8+offes_fltregs)(sp)
+       stfd    fr23,(23*8+offes_fltregs)(sp)
+       stfd    fr24,(24*8+offes_fltregs)(sp)
+       stfd    fr25,(25*8+offes_fltregs)(sp)
+       stfd    fr26,(26*8+offes_fltregs)(sp)
+       stfd    fr27,(27*8+offes_fltregs)(sp)
+       stfd    fr28,(28*8+offes_fltregs)(sp)
+       stfd    fr29,(29*8+offes_fltregs)(sp)
+       stfd    fr30,(30*8+offes_fltregs)(sp)
+       stfd    fr31,(31*8+offes_fltregs)(sp)
+       
+       /* calculate sp of method */
+       addi    itmp1,sp,(sizeexecutionstate + REPLACEMENT_ROOM + 4*4)
+       stw     itmp1,(offes_sp)(sp)
+
+       /* store pv */
+       stw     pv,(offes_pv)(sp)
+
+       /* call replace_me */
+       lwz     a0,-(4*4)(itmp1)            /* arg0: rplpoint *                   */
+    mr      a1,sp                       /* arg1: execution state              */
+       addi    sp,sp,-(LA_SIZE_ALIGNED)
+    b       replace_me                  /* call C function replace_me         */
+
+/* asm_replacement_in **********************************************************
+
+   This code writes the given execution state and jumps to the replacement
+   code.
+
+   This function never returns!
+
+   NOTE: itmp3 is not restored!
+
+   C prototype:
+      void asm_replacement_in(executionstate *es);
+
+*******************************************************************************/
+
+asm_replacement_in:
+       /* a0 == executionstate *es */
+
+       /* set new sp and pv */
+       lwz     sp,(offes_sp)(a0)
+       lwz     pv,(offes_pv)(a0)
+       
+       /* copy registers from execution state */
+       lwz     r0 ,( 0*8+offes_intregs)(a0)
+       /* r1 is sp                       */
+       /* r2 is reserved                 */
+       /* a0 is loaded below             */
+       lwz     r4 ,( 4*8+offes_intregs)(a0)
+       lwz     r5 ,( 5*8+offes_intregs)(a0)
+       lwz     r6 ,( 6*8+offes_intregs)(a0)
+       lwz     r7 ,( 7*8+offes_intregs)(a0)
+       lwz     r8 ,( 8*8+offes_intregs)(a0)
+       lwz     r9 ,( 9*8+offes_intregs)(a0)
+       lwz     r10,(10*8+offes_intregs)(a0)
+       lwz     r11,(11*8+offes_intregs)(a0)
+       lwz     r12,(12*8+offes_intregs)(a0)
+       /* r13 is pv                      */
+       lwz     r14,(14*8+offes_intregs)(a0)
+       lwz     r15,(15*8+offes_intregs)(a0)
+       lwz     r16,(16*8+offes_intregs)(a0) /* link register */
+       lwz     r17,(17*8+offes_intregs)(a0)
+       lwz     r18,(18*8+offes_intregs)(a0)
+       lwz     r19,(19*8+offes_intregs)(a0)
+       lwz     r20,(20*8+offes_intregs)(a0)
+       lwz     r21,(21*8+offes_intregs)(a0)
+       lwz     r22,(22*8+offes_intregs)(a0)
+       lwz     r23,(23*8+offes_intregs)(a0)
+       lwz     r24,(24*8+offes_intregs)(a0)
+       lwz     r25,(25*8+offes_intregs)(a0)
+       lwz     r26,(26*8+offes_intregs)(a0)
+       lwz     r27,(27*8+offes_intregs)(a0)
+       lwz     r28,(28*8+offes_intregs)(a0)
+       lwz     r29,(29*8+offes_intregs)(a0)
+       lwz     r30,(30*8+offes_intregs)(a0)
+       lwz     r31,(31*8+offes_intregs)(a0)
+       
+       lfd     fr0 ,( 0*8+offes_fltregs)(a0)
+       lfd     fr1 ,( 1*8+offes_fltregs)(a0)
+       lfd     fr2 ,( 2*8+offes_fltregs)(a0)
+       lfd     fr3 ,( 3*8+offes_fltregs)(a0)
+       lfd     fr4 ,( 4*8+offes_fltregs)(a0)
+       lfd     fr5 ,( 5*8+offes_fltregs)(a0)
+       lfd     fr6 ,( 6*8+offes_fltregs)(a0)
+       lfd     fr7 ,( 7*8+offes_fltregs)(a0)
+       lfd     fr8 ,( 8*8+offes_fltregs)(a0)
+       lfd     fr9 ,( 9*8+offes_fltregs)(a0)
+       lfd     fr10,(10*8+offes_fltregs)(a0)
+       lfd     fr11,(11*8+offes_fltregs)(a0)
+       lfd     fr12,(12*8+offes_fltregs)(a0)
+       lfd     fr13,(13*8+offes_fltregs)(a0)
+       lfd     fr14,(14*8+offes_fltregs)(a0)
+       lfd     fr15,(15*8+offes_fltregs)(a0)
+       lfd     fr16,(16*8+offes_fltregs)(a0)
+       lfd     fr17,(17*8+offes_fltregs)(a0)
+       lfd     fr18,(18*8+offes_fltregs)(a0)
+       lfd     fr19,(19*8+offes_fltregs)(a0)
+       lfd     fr20,(20*8+offes_fltregs)(a0)
+       lfd     fr21,(21*8+offes_fltregs)(a0)
+       lfd     fr22,(22*8+offes_fltregs)(a0)
+       lfd     fr23,(23*8+offes_fltregs)(a0)
+       lfd     fr24,(24*8+offes_fltregs)(a0)
+       lfd     fr25,(25*8+offes_fltregs)(a0)
+       lfd     fr26,(26*8+offes_fltregs)(a0)
+       lfd     fr27,(27*8+offes_fltregs)(a0)
+       lfd     fr28,(28*8+offes_fltregs)(a0)
+       lfd     fr29,(29*8+offes_fltregs)(a0)
+       lfd     fr30,(30*8+offes_fltregs)(a0)
+       lfd     fr31,(31*8+offes_fltregs)(a0)
+
+       /* restore link register */
+
+       mtlr    r16
+       
+       /* load new pc */
+
+       lwz     itmp3,offes_pc(a0)
+
+       /* load a0 */
+       
+       lwz     a0,(3*8+offes_intregs)(a0)
+
+       /* jump to new code */
+
+       mtctr   itmp3
+       bctr
+
+/*********************************************************************/
+
 asm_cacheflush:
        add     r4,r3,r4
        rlwinm  r3,r3,0,0,26
@@ -1088,4 +1307,5 @@ asm_criticalsections:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */
index afbd69c77593d0bd1018269fc7aed5cd6801809c..27cdc9ef8deaaa81b96d55f8021245735c2aa275 100644 (file)
@@ -31,7 +31,7 @@
             Christian Ullrich
                        Edwin Steiner
 
-   $Id: codegen.c 4631 2006-03-16 14:19:52Z twisti $
+   $Id: codegen.c 4653 2006-03-18 04:14:17Z edwin $
 
 */
 
@@ -64,6 +64,7 @@
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher.h"
 #include "vm/jit/reg.h"
+#include "vm/jit/replace.h"
 
 #if defined(ENABLE_LSRA)
 # include "vm/jit/allocator/lsra.h"
@@ -96,6 +97,7 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
        methodinfo         *lm;             /* local methodinfo for ICMD_INVOKE*  */
        builtintable_entry *bte;
        methoddesc         *md;
+       rplpoint           *replacementpoint;
 
        /* prevent compiler warnings */
 
@@ -361,6 +363,8 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
 
        /* end of header generation */
 
+       replacementpoint = cd->code->rplpoints;
+
        /* walk through all basic blocks */
        for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
 
@@ -379,6 +383,14 @@ bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
                        }
                }
 
+               /* handle replacement points */
+
+               if (bptr->bitflags & BBFLAG_REPLACEMENT) {
+                       replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
+                       
+                       replacementpoint++;
+               }
+
                /* copy interface registers to their destination */
 
                src = bptr->instack;
@@ -3508,6 +3520,50 @@ gen_method:
                        M_MTCTR(REG_ITMP3);
                        M_RTS;
                }
+
+               /* generate replacement-out stubs */
+
+               {
+                       int i;
+
+                       replacementpoint = cd->code->rplpoints;
+                       for (i=0; i<cd->code->rplpointcount; ++i, ++replacementpoint) {
+                               /* check code segment size */
+
+                               MCODECHECK(100);
+
+                               /* note start of stub code */
+
+                               replacementpoint->outcode = (u1*) (ptrint)((u1*)mcodeptr - cd->mcodebase);
+
+                               /* make machine code for patching */
+
+                               tmpmcodeptr = mcodeptr;
+                               mcodeptr = (s4*) &(replacementpoint->mcode) + 1 /* big-endian */;
+
+                               disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
+                               M_BR(disp);
+
+                               mcodeptr = tmpmcodeptr;
+
+                               /* create stack frame - keep 16-byte aligned */
+
+                               M_AADD_IMM(REG_SP, -4 * 4, REG_SP);
+
+                               /* push address of `rplpoint` struct */
+
+                               disp = dseg_addaddress(cd, replacementpoint);
+                               M_ALD(REG_ITMP3, REG_PV, disp);
+                               M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 4);
+
+                               /* jump to replacement function */
+
+                               disp = dseg_addaddress(cd, asm_replacement_out);
+                               M_ALD(REG_ITMP3, REG_PV, disp);
+                               M_MTCTR(REG_ITMP3);
+                               M_RTS;
+                       }
+               }
        }
 
        codegen_finish(m, cd, (ptrint) ((u1 *) mcodeptr - cd->mcodebase));
index b86859d67f87030c8d24c734c59aa3628b0f6ce9..238f3ba34b0a6fbe1b0948e07821c90314721119 100644 (file)
@@ -26,9 +26,9 @@
 
    Authors: Christian Thalinger
 
-   Changes:
+   Changes: Edwin Steiner
 
-   $Id: md.c 4631 2006-03-16 14:19:52Z twisti $
+   $Id: md.c 4653 2006-03-18 04:14:17Z edwin $
 
 */
 
@@ -42,6 +42,8 @@
 
 #include "vm/global.h"
 #include "vm/jit/asmpart.h"
+#include "vm/options.h" /* XXX debug */
+#include "vm/jit/disass.h" /* XXX debug */
 
 
 /* md_init *********************************************************************
@@ -172,6 +174,35 @@ void md_dcacheflush(u1 *addr, s4 nbytes)
 }
 
 
+/* md_patch_replacement_point **************************************************
+
+   Patch the given replacement point.
+
+*******************************************************************************/
+
+void md_patch_replacement_point(rplpoint *rp)
+{
+    u8 mcode;
+
+       /* save the current machine code */
+       mcode = *(u4*)rp->pc;
+
+       /* write the new machine code */
+    *(u4*)(rp->pc) = (u4) rp->mcode;
+
+       /* store saved mcode */
+       rp->mcode = mcode;
+       
+       {
+               u1* u1ptr = rp->pc;
+               DISASSINSTR(u1ptr);
+               fflush(stdout);
+       }
+                       
+       /* flush instruction cache */
+    md_icacheflush(rp->pc,4);
+}
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
@@ -183,4 +214,5 @@ void md_dcacheflush(u1 *addr, s4 nbytes)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */
index 5d8fe9fca5ac2812209a9ed87ba98a4192d81ac4..447014312d3eca2b8358a42b5f9ae0d81833dbfb 100644 (file)
@@ -283,7 +283,7 @@ void replace_activate_replacement_point(rplpoint *rp,rplpoint *target)
        
        rp->target = target;
        
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT)
        md_patch_replacement_point(rp);
 #endif
 }
@@ -311,7 +311,7 @@ void replace_deactivate_replacement_point(rplpoint *rp)
        
        rp->target = NULL;
        
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT)
        md_patch_replacement_point(rp);
 #endif
 }
@@ -330,6 +330,72 @@ void replace_deactivate_replacement_point(rplpoint *rp)
   
 *******************************************************************************/
 
+inline static void replace_read_value(executionstate *es,
+#ifdef HAS_4BYTE_STACKSLOT
+                                                                         u4 *sp,
+#else
+                                                                         u8 *sp,
+#endif
+                                                                         rplalloc *ra,
+                                                                         u8 *javaval)
+{
+       if (ra->flags & INMEMORY) {
+               /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
+#ifdef HAS_4BYTE_STACKSLOT
+               if (IS_2_WORD_TYPE(ra->type)) {
+                       *javaval = *(u8*)(sp + ra->index);
+               }
+               else {
+#endif
+                       *javaval = sp[ra->index];
+#ifdef HAS_4BYTE_STACKSLOT
+               }
+#endif
+       }
+       else {
+               /* allocated register */
+               if (IS_FLT_DBL_TYPE(ra->type)) {
+                       *javaval = es->fltregs[ra->index];
+               }
+               else {
+                       *javaval = es->intregs[ra->index];
+               }
+       }
+}
+
+inline static void replace_write_value(executionstate *es,
+#ifdef HAS_4BYTE_STACKSLOT
+                                                                         u4 *sp,
+#else
+                                                                         u8 *sp,
+#endif
+                                                                         rplalloc *ra,
+                                                                         u8 *javaval)
+{
+       if (ra->flags & INMEMORY) {
+               /* XXX HAS_4BYTE_STACKSLOT may not be the right discriminant here */
+#ifdef HAS_4BYTE_STACKSLOT
+               if (IS_2_WORD_TYPE(ra->type)) {
+                       *(u8*)(sp + ra->index) = *javaval;
+               }
+               else {
+#endif
+                       sp[ra->index] = *javaval;
+#ifdef HAS_4BYTE_STACKSLOT
+               }
+#endif
+       }
+       else {
+               /* allocated register */
+               if (IS_FLT_DBL_TYPE(ra->type)) {
+                       es->fltregs[ra->index] = *javaval;
+               }
+               else {
+                       es->intregs[ra->index] = *javaval;
+               }
+       }
+}
+
 static void replace_read_executionstate(rplpoint *rp,executionstate *es,
                                                                         sourcestate *ss)
 {
@@ -375,7 +441,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
        /* in some cases the top stack slot is passed in REG_ITMP1 */
 
        if (  (rp->type == BBTYPE_EXH)
-#if defined(__ALPHA__)
+#if defined(__ALPHA__) || defined(__POWERPC__)
           || (rp->type == BBTYPE_SBR)
 #endif
           )
@@ -401,7 +467,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
                ss->javalocals[i] = (u8) 0x00dead0000dead00ULL;
 
        /* some entries in the intregs array are not meaningful */
-       es->intregs[REG_ITMP3] = (u8) 0x11dead1111dead11ULL;
+       /*es->intregs[REG_ITMP3] = (u8) 0x11dead1111dead11ULL;*/
        es->intregs[REG_SP   ] = (u8) 0x11dead1111dead11ULL;
 #ifdef REG_PV
        es->intregs[REG_PV   ] = (u8) 0x11dead1111dead11ULL;
@@ -418,27 +484,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
                if (t == -1)
                        continue; /* dummy rplalloc */
 
-#ifdef HAS_4BYTE_STACKSLOT
-               if (IS_2_WORD_TYPE(ra->type)) {
-                       if (ra->flags & INMEMORY) {
-                               ss->javalocals[i*5+t] = *(u8*)(sp + ra->index);
-                       }
-                       else {
-                               dolog("XXX split 2-word types in registers are not supported");
-                               assert(0);
-                       }
-               }
-               else {
-#endif
-                       if (ra->flags & INMEMORY) {
-                               ss->javalocals[i*5+t] = sp[ra->index];
-                       }
-                       else {
-                               ss->javalocals[i*5+t] = es->intregs[ra->index];
-                       }
-#ifdef HAS_4BYTE_STACKSLOT
-               }
-#endif
+               replace_read_value(es,sp,ra,ss->javalocals + (5*i+t));
        }
 
        /* read stack slots */
@@ -480,12 +526,7 @@ static void replace_read_executionstate(rplpoint *rp,executionstate *es,
        for (; count--; ra++, i++) {
                assert(ra->next);
 
-               if (ra->flags & INMEMORY) {
-                       ss->javastack[i] = sp[ra->index];
-               }
-               else {
-                       ss->javastack[i] = es->intregs[ra->index];
-               }
+               replace_read_value(es,sp,ra,ss->javastack + i);
        }
 
        /* read unused callee saved int regs */
@@ -571,6 +612,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,
        code = rp->code;
        m = code->m;
        md = m->parseddesc;
+       topslot = TOP_IS_NORMAL;
        
        /* calculate stack pointer */
        
@@ -593,7 +635,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,
        /* in some cases the top stack slot is passed in REG_ITMP1 */
 
        if (  (rp->type == BBTYPE_EXH)
-#if defined(__ALPHA__)
+#if defined(__ALPHA__) || defined(__POWERPC__)
           || (rp->type == BBTYPE_SBR) 
 #endif
           )
@@ -626,27 +668,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,
                if (t == -1)
                        continue; /* dummy rplalloc */
 
-#ifdef HAS_4BYTE_STACKSLOT
-               if (IS_2_WORD_TYPE(ra->type)) {
-                       if (ra->flags & INMEMORY) {
-                               *(u8*)(sp + ra->index) = ss->javalocals[i*5+t];
-                       }
-                       else {
-                               dolog("XXX split 2-word types in registers are not supported");
-                               assert(0);
-                       }
-               }
-               else {
-#endif
-                       if (ra->flags & INMEMORY) {
-                               sp[ra->index] = ss->javalocals[i*5+t];
-                       }
-                       else {
-                               es->intregs[ra->index] = ss->javalocals[i*5+t];
-                       }
-#ifdef HAS_4BYTE_STACKSLOT
-               }
-#endif
+               replace_write_value(es,sp,ra,ss->javalocals + (5*i+t));
        }
 
        /* write stack slots */
@@ -680,12 +702,7 @@ static void replace_write_executionstate(rplpoint *rp,executionstate *es,
        for (; count--; ra++, i++) {
                assert(ra->next);
 
-               if (ra->flags & INMEMORY) {
-                       sp[ra->index] = ss->javastack[i];
-               }
-               else {
-                       es->intregs[ra->index] = ss->javastack[i];
-               }
+               replace_write_value(es,sp,ra,ss->javastack + i);
        }
        
        /* write unused callee saved int regs */
@@ -797,7 +814,7 @@ void replace_me(rplpoint *rp,executionstate *es)
 
        /* enter new code */
 
-#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__)) && defined(ENABLE_JIT)
+#if (defined(__I386__) || defined(__X86_64__) || defined(__ALPHA__) || defined(__POWERPC__)) && defined(ENABLE_JIT)
        asm_replacement_in(es);
 #endif
        abort();