* src/vm/jit/mips/md-abi.h: Merged MIPS32 code.
authortwisti <none@none>
Thu, 11 Jan 2007 22:39:52 +0000 (22:39 +0000)
committertwisti <none@none>
Thu, 11 Jan 2007 22:39:52 +0000 (22:39 +0000)
* src/vm/jit/mips/emit.c: Likewise.
* src/vm/jit/mips/codegen.c: Likewise.
* src/vm/jit/mips/codegen.h: Likewise.
* src/vm/jit/mips/linux/md-os.c: Likewise.
* src/vm/jit/mips/asmpart.S: Likewise.
* src/vm/jit/mips/md-abi.c: Likewise.

src/vm/jit/mips/asmpart.S
src/vm/jit/mips/codegen.c
src/vm/jit/mips/codegen.h
src/vm/jit/mips/emit.c
src/vm/jit/mips/linux/md-os.c
src/vm/jit/mips/md-abi.c
src/vm/jit/mips/md-abi.h

index 0aa1f5cf2a96b5be2828ae72dae58d4db913c78d..c8e5af9f6a48346e6327008bec3b6eda8e099eea 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Christian Thalinger
             Edwin Steiner
 
-   $Id: asmpart.S 6265 2007-01-02 20:40:57Z edwin $
+   $Id: asmpart.S 7206 2007-01-11 22:39:52Z twisti $
 
 */
 
@@ -77,7 +77,7 @@
        .globl compare_and_swap
 
 
-/********************* function asm_calljavafunction ***************************
+/* asm_vm_call_method **********************************************************
 *                                                                              *
 *   This function calls a Java-method (which possibly needs compilation)       *
 *   with up to 4 address parameters.                                           *
 
        .align  3
 
+#if SIZEOF_VOID_P == 8
+
        .dword  0                           /* catch type all                     */
        .dword  0                           /* handler pc                         */
        .dword  0                           /* end pc                             */
        .word   0                           /* frame size                         */
        .dword  0                           /* codeinfo pointer                   */
 
+#else /* SIZEOF_VOID_P == 8 */
+
+       .word   0                           /* catch type all                     */
+       .word   0                           /* handler pc                         */
+       .word   0                           /* end pc                             */
+       .word   0                           /* start pc                           */
+       .word   1                           /* extable size                       */
+       .word   0                           /* line number table start            */
+       .word   0                           /* line number table size             */
+       .word   0                           /* fltsave                            */
+       .word   0                           /* intsave                            */
+       .word   0                           /* isleaf                             */
+       .word   0                           /* IsSync                             */
+       .word   0                           /* frame size                         */
+       .word   0                           /* method pointer (pointer to name)   */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
 asm_vm_call_method:
 asm_vm_call_method_int:
 asm_vm_call_method_long:
@@ -130,84 +150,147 @@ asm_vm_call_method_double:
        ast     pv,1*8(sp)                /* procedure vector                     */
 L_asm_vm_call_method_compute_pv:
        aaddiu  pv,ra,-4*4
+
        ast     s7,3*8(sp)
 
+#if SIZEOF_VOID_P == 8
        sdc1    fss0,5*8(sp)              /* save non JavaABI saved flt registers */
        sdc1    fss1,6*8(sp)
        sdc1    fss2,7*8(sp)
        sdc1    fss3,8*8(sp)
        sdc1    fss4,9*8(sp)
        sdc1    fss5,10*8(sp)
+#endif
 
        ast     a0,4*8(sp)                /* save method pointer for compiler     */
 
-       move    t0,a2
-       move    s7,a1
+       move    t0,a2                     /* address of first block               */
+       move    s7,a1                     /* argument count                       */
        blez    s7,calljava_argsloaded
        nop
 
+#if SIZEOF_VOID_P == 8
+
        ald     a0,offvmargdata(t0)
        ldc1    fa0,offvmargdata(t0)
-       daddi   s7,s7,-1
+       aaddi   s7,s7,-1
        blez    s7,calljava_argsloaded
        nop
 
        ald     a1,offvmargdata+sizevmarg*1(t0)
        ldc1    fa1,offvmargdata+sizevmarg*1(t0)
-       daddi   s7,s7,-1
+       aaddi   s7,s7,-1
        blez    s7,calljava_argsloaded
        nop
 
        ald     a2,offvmargdata+sizevmarg*2(t0)
        ldc1    fa2,offvmargdata+sizevmarg*2(t0)
-       daddi   s7,s7,-1
+       aaddi   s7,s7,-1
        blez    s7,calljava_argsloaded
        nop
 
        ald     a3,offvmargdata+sizevmarg*3(t0)
        ldc1    fa3,offvmargdata+sizevmarg*3(t0)
-       daddi   s7,s7,-1
+       aaddi   s7,s7,-1
        blez    s7,calljava_argsloaded
        nop
 
        ald     a4,offvmargdata+sizevmarg*4(t0)
        ldc1    fa4,offvmargdata+sizevmarg*4(t0)
-       daddi   s7,s7,-1
+       aaddi   s7,s7,-1
        blez    s7,calljava_argsloaded
        nop
 
        ald     a5,offvmargdata+sizevmarg*5(t0)
        ldc1    fa5,offvmargdata+sizevmarg*5(t0)
-       daddi   s7,s7,-1
+       aaddi   s7,s7,-1
        blez    s7,calljava_argsloaded
        nop
 
        ald     a6,offvmargdata+sizevmarg*6(t0)
        ldc1    fa6,offvmargdata+sizevmarg*6(t0)
-       daddi   s7,s7,-1
+       aaddi   s7,s7,-1
        blez    s7,calljava_argsloaded
        nop
 
        ald     a7,offvmargdata+sizevmarg*7(t0)
        ldc1    fa7,offvmargdata+sizevmarg*7(t0)
-       daddi   s7,s7,-1
-               
+       aaddi   s7,s7,-1
+
+#else /* SIZEOF_VOID_P == 8 */
+
+#if WORDS_BIGENDIAN == 1
+       ald     a0,offvmargdata+4(t0)
+#else
+       ald     a0,offvmargdata(t0)
+#endif
+#if !defined(ENABLE_SOFT_FLOAT)
+       ldc1    fa0,offvmargdata(t0)
+#endif
+       aaddi   s7,s7,-1
+       blez    s7,calljava_argsloaded
+
+#if WORDS_BIGENDIAN == 1
+       ald     a1,offvmargdata+4+sizevmarg*1(t0)
+#else
+       ald     a1,offvmargdata+sizevmarg*1(t0)
+#endif
+#if !defined(ENABLE_SOFT_FLOAT)
+       ldc1    fa1,offvmargdata+sizevmarg*1(t0)
+#endif
+       aaddi   s7,s7,-1
+       blez    s7,calljava_argsloaded
+
+#if WORDS_BIGENDIAN == 1
+       ald     a2,offvmargdata+4+sizevmarg*2(t0)
+#else
+       ald     a2,offvmargdata+sizevmarg*2(t0)
+#endif
+       aaddi   s7,s7,-1
+       blez    s7,calljava_argsloaded
+
+#if WORDS_BIGENDIAN == 1
+       ald     a3,offvmargdata+4+sizevmarg*3(t0)
+#else
+       ald     a3,offvmargdata+sizevmarg*3(t0)
+#endif
+       aaddi   s7,s7,-1
+       blez    s7,calljava_argsloaded
+
+#endif /* SIZEOF_VOID_P == 8 */
+
 calljava_argsloaded:
-       move    t4,sp                      /* save stack pointer                  */
+       move    t4,sp                     /* save stack pointer                   */
        blez    s7,calljava_nocopy
        nop
-       subu    t1,zero,s7                 /* create argument stack frame         */
-       sll     t2,t1,3
-       aaddu   sp,sp,t2
-       aaddu   t2,t2,t4
+
+#if SIZEOF_VOID_P == 4
+       aaddiu  s7,s7,4                   /* add stack space for 4 arguments      */
+#endif
+       subu    t1,zero,s7                /* remaining argument count (negative)  */
+       sll     t2,t1,3                   /* calculate stackframe size            */
+       aaddu   sp,sp,t2                  /* create stackframe                    */
+       aaddu   t2,t2,t4                  /* also set temp sp                     */
+#if SIZEOF_VOID_P == 4
+       aaddiu  t2,t2,4*8                 /* skip stack space for 4 arguments     */
+       addiu   t1,t1,4
+#endif
 
 calljava_copyloop:
-    ald     t3,offvmargdata+sizevmarg*8(t0)
-       ast     t3,0(t2)
-       aaddi   t1,t1,1
-       aaddi   t0,t0,sizevmarg
-       aaddi   t2,t2,8
-       bnez    t1,calljava_copyloop
+#if SIZEOF_VOID_P == 8
+       ald     t3,offvmargdata+sizevmarg*8(t0)
+#else
+# if WORDS_BIGENDIAN == 1
+       ald     t3,offvmargdata+4+sizevmarg*4(t0)
+# else
+       ald     t3,offvmargdata+sizevmarg*4(t0)
+# endif
+#endif
+       ast     t3,0(t2)                  /* store argument on stack              */
+       addi    t1,t1,1                   /* count 1 argument                     */
+       aaddi   t0,t0,sizevmarg           /* load address of next block           */
+       aaddi   t2,t2,8                   /* increase stack position              */
+       bnez    t1,calljava_copyloop      /* all arguments copied?                */
        nop
 
 calljava_nocopy:
@@ -221,35 +304,46 @@ calljava_nocopy:
        jalr    pv                        /* call JIT compiler                    */
        nop
 L_asm_vm_call_method_recompute_pv:
-/*     aaddiu  pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)*/
+#if SIZEOF_VOID_P == 8
        aaddiu  pv,ra,-76*4               /* recompute procedure vector           */
+#else
+       aaddiu  pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
+#endif
 
        .set    reorder                   /* XXX we need to recompute pv          */
 
-       asll    s7,s7,3                   /* remove argument stack frame          */
-       aaddu   sp,sp,s7
+       sll     t1,s7,3                   /* remove argument stackframe           */
+       aaddu   sp,sp,t1
 
 calljava_return2:
-       ald     ra,0(sp)                  /* restore return address               */
-       ald     pv,8(sp)                  /* restore procedure vector             */
+       ald     ra,0*8(sp)                /* restore return address               */
+       ald     pv,1*8(sp)                /* restore procedure vector             */
        ald     s7,3*8(sp)
 
+#if SIZEOF_VOID_P == 8
        ldc1    fss0,5*8(sp)              /* restore non JavaABI saved flt regs   */
        ldc1    fss1,6*8(sp)
        ldc1    fss2,7*8(sp)
        ldc1    fss3,8*8(sp)
        ldc1    fss4,9*8(sp)
        ldc1    fss5,10*8(sp)
+#endif
 
        aaddiu  sp,sp,12*8                /* free stack space                     */
        j       ra                        /* return                               */
 
 asm_vm_call_method_exception_handler:
-       asll    s7,s7,3                   /* remove argument stack frame          */
-       aaddu   sp,sp,s7
+       sll     t1,s7,3                   /* remove stackframe                    */
+       aaddu   sp,sp,t1
+#if SIZEOF_VOID_P == 4
+       aaddiu  sp,sp,-4*4                /* reserve space for 1 argument         */
+#endif
 
        move    a0,itmp1                  
        jal     builtin_throw_exception
+#if SIZEOF_VOID_P == 4
+       aaddiu  sp,sp,4*4
+#endif
        b       calljava_return2
 
        .end    asm_vm_call_method
@@ -278,11 +372,12 @@ asm_vm_call_method_exception_handler:
 *                                                                              *
 *******************************************************************************/
 
-
        .ent    asm_call_jit_compiler
 
 asm_call_jit_compiler:
-       aaddiu  sp,sp,-(ARG_CNT+2)*8  /* allocate stack space                     */
+#if SIZEOF_VOID_P == 8
+
+       aaddiu  sp,sp,-(ARG_CNT+2)*8  /* +2: keep stack 16-bytes aligned          */
 
        ast     ra,0*8(sp)            /* save return address                      */
 
@@ -301,6 +396,29 @@ asm_call_jit_compiler:
 
        aaddiu  sp,sp,(ARG_CNT+2)*8   /* remove stack frame                       */
 
+#else /* SIZEOF_VOID_P == 8 */
+
+       aaddiu  sp,sp,-(ARG_CNT+2)*8  /* +4: keep stack 16-bytes aligned          */
+
+       ast     ra,4*4+0*4(sp)        /* save return address                      */
+
+       SAVE_ARGUMENT_REGISTERS(6)
+
+       move    a0,itmp1              /* pass methodinfo pointer                  */
+       move    a1,mptr               /* pass method pointer                      */
+       aaddiu  a2,sp,(ARG_CNT+2)*8   /* pass java sp                             */
+       move    a3,ra
+       jal     jit_asm_compile       /* call jit compiler                        */
+       move    pv,v0
+
+       ald     ra,4*4+0*4(sp)        /* restore return address                   */
+
+       RESTORE_ARGUMENT_REGISTERS(6)
+
+       aaddiu  sp,sp,(ARG_CNT+2)*8   /* remove stack frame                       */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
        beqz    pv,L_asm_call_jit_compiler_exception
 
        jr      pv                    /* and call method. The method returns      */
@@ -334,20 +452,38 @@ L_asm_call_jit_compiler_exception:
 
 asm_handle_nat_exception:
 L_asm_handle_exception_stack_loop:
+#if SIZEOF_VOID_P == 8
        aaddiu  sp,sp,-6*8                  /* keep stack 16-byte aligned         */
        ast     xptr,0*8(sp)                /* save exception pointer             */
        ast     xpc,1*8(sp)                 /* save exception pc                  */
        ast     ra,3*8(sp)                  /* save RA                            */
        ast     zero,4*8(sp)                /* save maybe-leaf flag (cleared)     */
+#else
+       aaddiu  sp,sp,-(4*4+6*8)            /* allocate stack                     */
+       ast     xptr,4*4+0*8(sp)            /* save exception pointer             */
+       ast     xpc,4*4+1*8(sp)             /* save exception pc                  */
+       ast     ra,4*4+3*8(sp)              /* save return address                */
+       ast     zero,4*4+4*8(sp)            /* save maybe-leaf flag (cleared)     */
+#endif
 
        move    a0,ra                       /* pass RA                            */
        jal     md_codegen_get_pv_from_pc   /* get PV from RA                     */
+
+#if SIZEOF_VOID_P == 8
        ast     v0,2*8(sp)                  /* save PV                            */
 
        ald     a0,0*8(sp)                  /* pass xptr                          */
        ald     a1,1*8(sp)                  /* pass xpc                           */
        move    a2,v0                       /* pass PV                            */
        aaddiu  a3,sp,6*8                   /* pass Java SP                       */
+#else
+       ast     v0,4*4+2*8(sp)              /* save data segment pointer          */
+
+       ald     a0,4*4+0*8(sp)              /* pass exception pointer             */
+       ald     a1,4*4+1*8(sp)              /* pass exception pc                  */
+       move    a2,v0                       /* pass data segment pointer          */
+       aaddiu  a3,sp,(4*4+6*8)             /* pass Java stack pointer            */
+#endif
 
        b       L_asm_handle_exception_continue
 
@@ -359,17 +495,32 @@ asm_handle_exception:
        SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
        SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
 
+#if SIZEOF_VOID_P == 8
        aaddiu  sp,sp,-6*8                  /* allocate stack                     */
        ast     xptr,0*8(sp)                /* save exception pointer             */
        ast     pv,2*8(sp)                  /* save PV                            */
        ast     ra,3*8(sp)                  /* save RA                            */
        addu    t0,zero,1                   /* set maybe-leaf flag                */
        ast     t0,4*8(sp)                  /* save maybe-leaf flag               */
+#else
+       aaddiu  sp,sp,-(4*4+6*8)            /* allocate stack                     */
+       ast     xptr,4*4+0*8(sp)            /* save exception pointer             */
+       ast     xpc,4*4+1*8(sp)             /* save exception pc                  */
+       ast     pv,4*4+2*8(sp)              /* save data segment pointer          */
+       ast     ra,4*4+3*8(sp)              /* save return address                */
+       addu    t0,zero,1                   /* set maybe-leaf flag                */
+       ast     t0,4*4+4*8(sp)              /* save maybe-leaf flag               */
+#endif
 
        move    a0,xptr                     /* pass xptr                          */
        move    a1,xpc                      /* pass xpc                           */
        move    a2,pv                       /* pass PV                            */
+
+#if SIZEOF_VOID_P == 8
        aaddiu  a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP                       */
+#else
+       aaddiu  a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer        */
+#endif
 
 L_asm_handle_exception_continue:
        jal     exceptions_handle_exception
@@ -377,11 +528,20 @@ L_asm_handle_exception_continue:
        beqz    v0,L_asm_handle_exception_not_catched
 
        move    xpc,v0                      /* move handlerpc into xpc            */
+
+#if SIZEOF_VOID_P == 8
        ald     xptr,0*8(sp)                /* restore exception pointer          */
        ald     pv,2*8(sp)                  /* restore PV                         */
        ald     ra,3*8(sp)                  /* restore RA                         */
        ald     t0,4*8(sp)                  /* get maybe-leaf flag                */
        aaddiu  sp,sp,6*8                   /* free stackframe                    */
+#else
+       ald     xptr,4*4+0*8(sp)            /* restore exception pointer          */
+       ald     pv,4*4+2*8(sp)              /* restore data segment pointer       */
+       ald     ra,4*4+3*8(sp)              /* restore return address             */
+       ald     t0,4*4+4*8(sp)              /* get maybe-leaf flag                */
+       aaddiu  sp,sp,4*4+6*8               /* free stackframe                    */
+#endif
        
        beqz    t0,L_asm_handle_exception_no_leaf
 
@@ -394,11 +554,19 @@ L_asm_handle_exception_no_leaf:
        jr      xpc                         /* jump to the handler                */
 
 L_asm_handle_exception_not_catched:
+#if SIZEOF_VOID_P == 8
        ald     xptr,0*8(sp)                /* restore xptr                       */
        ald     pv,2*8(sp)                  /* restore PV                         */
        ald     ra,3*8(sp)                  /* restore RA                         */
        ald     t0,4*8(sp)                  /* get maybe-leaf flag                */
        aaddiu  sp,sp,6*8                   /* free stackframe                    */
+#else
+       ald     xptr,4*4+0*8(sp)            /* restore xptr                       */
+       ald     pv,4*4+2*8(sp)              /* restore PV                         */
+       ald     ra,4*4+3*8(sp)              /* restore RA                         */
+       ald     t0,4*4+4*8(sp)              /* get maybe-leaf flag                */
+       aaddiu  sp,sp,4*4+6*8               /* free stackframe                    */
+#endif
        
        beqz    t0,L_asm_handle_exception_no_leaf_stack
 
@@ -431,6 +599,7 @@ L_asm_handle_exception_no_ra_restore:
        ald     s5,-3*8(t1)
        ald     s6,-2*8(t1)
        ald     s7,-1*8(t1)
+
 ex_int2:
        sll     t2,t2,1               /* t2 = register count * 4 * 2              */
        asubu   t1,t1,t2              /* t1 = t0 - 8 * register count             */
@@ -441,10 +610,21 @@ ex_int2:
        asubu   t3,t3,t2              /* t3 = ex_int_sav - 4 * register count     */
        jr      t3                          /* jump to save position              */
 
+#if SIZEOF_VOID_P == 8
+       ldc1    fs0,-4*8(t1)
+       ldc1    fs1,-3*8(t1)
+       ldc1    fs2,-2*8(t1)
+       ldc1    fs3,-1*8(t1)
+#else /* SIZEOF_VOID_P == 8 */
+# if !defined(ENABLE_SOFT_FLOAT)
        ldc1    fs0,-4*8(t1)
        ldc1    fs1,-3*8(t1)
        ldc1    fs2,-2*8(t1)
        ldc1    fs3,-1*8(t1)
+       ldc1    fs4,-1*8(t1)
+       ldc1    fs5,-1*8(t1)
+# endif /* !defined(ENABLE_SOFT_FLOAT) */
+#endif /* SIZEOF_VOID_P == 8 */
 
 ex_flt2:
        lw      t1,FrameSize(pv)            /* get frame size                     */
@@ -497,6 +677,8 @@ asm_abstractmethoderror:
     .ent    asm_patcher_wrapper
 
 asm_patcher_wrapper:
+#if SIZEOF_VOID_P == 8
+
        aaddiu  sp,sp,-((2+16+22+4)*8)/* create stack frame                       */
 
        SAVE_RETURN_REGISTERS(0)      /* save 1 int/1 float return registers      */
@@ -534,6 +716,50 @@ L_asm_patcher_wrapper_exception:
        move    xptr,itmp3            /* get exception                            */
        ald     xpc,(7+2+16+22+4)*8(sp) /* xpc is RA                              */
        aaddiu  sp,sp,(8+2+16+22+4)*8 /* remove stack frame                       */
+
+#else /* SIZEOF_VOID_P == 8 */
+
+       aaddiu  sp,sp,-((5+4+4+8+7)*4) /* create stack frame                      */
+                                     /* +7 keeps the SP 16-bytes aligned         */
+
+       SAVE_RETURN_REGISTERS(5)      /* save 2 int / 2 float return registers    */
+       SAVE_ARGUMENT_REGISTERS(9)    /* save 4 int argument registers            */
+       SAVE_TEMPORARY_REGISTERS(13)  /* save 8 int temporary registers           */
+
+       ast     itmp1,(5+4+4+8+0)*4(sp) /* save itmp1                             */
+       ast     itmp2,(5+4+4+8+1)*4(sp) /* save itmp2                             */
+       ast     ra,(5+4+4+8+2)*4(sp)  /* save method return address (for leafs)   */
+       ast     pv,(5+4+4+8+3)*4(sp)  /* save pv of calling java function         */
+
+       aaddiu  a0,sp,(5+4+4+8+7)*4   /* pass SP of patcher stub                  */
+       move    a1,pv                 /* pass PV                                  */
+       move    a2,ra                 /* pass RA (correct for leafs)              */
+       jal     patcher_wrapper
+       move    itmp3,v0
+
+       RESTORE_RETURN_REGISTERS(5)   /* restore 2 int / 2 float return registers */
+       RESTORE_ARGUMENT_REGISTERS(9) /* restore 4 int argument registers         */
+       RESTORE_TEMPORARY_REGISTERS(13) /* restore 9 int temporary registers      */
+
+       ald     itmp1,(5+4+4+8+0)*4(sp) /* restore itmp1                          */
+       ald     itmp2,(5+4+4+8+1)*4(sp) /* restore itmp2                          */
+       ald     ra,(5+4+4+8+2)*4(sp)  /* restore method return address (for leafs)*/
+       ald     pv,(5+4+4+8+3)*4(sp)  /* restore pv of calling java function      */
+
+       bnez    itmp3,L_asm_wrapper_patcher_exception
+
+       ald     itmp3,7*8+(5+4+4+8+7)*4(sp) /* load RA                            */
+       aaddiu  sp,sp,8*8+(5+4+4+8+7)*4 /* remove stack frame                     */
+
+       jr      itmp3                 /* jump to new patched code                 */
+
+L_asm_wrapper_patcher_exception:
+       move    xptr,itmp3            /* get exception                            */
+       ald     xpc,7*8+(5+4+4+8+7)*4(sp) /* xpc is RA                            */
+       aaddiu  sp,sp,8*8+(5+4+4+8+7)*4 /* remove stack frame                     */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
        b       asm_handle_exception
 
        .end    asm_patcher_wrapper
@@ -567,42 +793,44 @@ L_asm_patcher_wrapper_exception:
 
 asm_replacement_out:
     /* create stack frame */
-       daddiu  sp,sp,-REPLACEMENT_STACK_OFFSET
+       aaddiu  sp,sp,-REPLACEMENT_STACK_OFFSET
 
        /* save registers in execution state */
-       sd      $0 ,( 0*8+offes_intregs)(sp)
-       sd      $1 ,( 1*8+offes_intregs)(sp)
-       sd      $2 ,( 2*8+offes_intregs)(sp)
-       sd      $3 ,( 3*8+offes_intregs)(sp)
-       sd      $4 ,( 4*8+offes_intregs)(sp)
-       sd      $5 ,( 5*8+offes_intregs)(sp)
-       sd      $6 ,( 6*8+offes_intregs)(sp)
-       sd      $7 ,( 7*8+offes_intregs)(sp)
-       sd      $8 ,( 8*8+offes_intregs)(sp)
-       sd      $9 ,( 9*8+offes_intregs)(sp)
-       sd      $10,(10*8+offes_intregs)(sp)
-       sd      $11,(11*8+offes_intregs)(sp)
-       sd      $12,(12*8+offes_intregs)(sp)
-       sd      $13,(13*8+offes_intregs)(sp)
-       sd      $14,(14*8+offes_intregs)(sp)
-       sd      $15,(15*8+offes_intregs)(sp)
-       sd      $16,(16*8+offes_intregs)(sp)
-       sd      $17,(17*8+offes_intregs)(sp)
-       sd      $18,(18*8+offes_intregs)(sp)
-       sd      $19,(19*8+offes_intregs)(sp)
-       sd      $20,(20*8+offes_intregs)(sp)
-       sd      $21,(21*8+offes_intregs)(sp)
-       sd      $22,(22*8+offes_intregs)(sp)
-       sd      $23,(23*8+offes_intregs)(sp)
-       sd      $24,(24*8+offes_intregs)(sp)
-       sd      $25,(25*8+offes_intregs)(sp)
-       sd      $26,(26*8+offes_intregs)(sp)
-       sd      $27,(27*8+offes_intregs)(sp)
-       sd      $28,(28*8+offes_intregs)(sp)
-       sd      $29,(29*8+offes_intregs)(sp)
-       sd      $30,(30*8+offes_intregs)(sp)
-       sd      $31,(31*8+offes_intregs)(sp)
-       
+       ast     $0 ,( 0*8+offes_intregs)(sp)
+       ast     $1 ,( 1*8+offes_intregs)(sp)
+       ast     $2 ,( 2*8+offes_intregs)(sp)
+       ast     $3 ,( 3*8+offes_intregs)(sp)
+       ast     $4 ,( 4*8+offes_intregs)(sp)
+       ast     $5 ,( 5*8+offes_intregs)(sp)
+       ast     $6 ,( 6*8+offes_intregs)(sp)
+       ast     $7 ,( 7*8+offes_intregs)(sp)
+       ast     $8 ,( 8*8+offes_intregs)(sp)
+       ast     $9 ,( 9*8+offes_intregs)(sp)
+       ast     $10,(10*8+offes_intregs)(sp)
+       ast     $11,(11*8+offes_intregs)(sp)
+       ast     $12,(12*8+offes_intregs)(sp)
+       ast     $13,(13*8+offes_intregs)(sp)
+       ast     $14,(14*8+offes_intregs)(sp)
+       ast     $15,(15*8+offes_intregs)(sp)
+       ast     $16,(16*8+offes_intregs)(sp)
+       ast     $17,(17*8+offes_intregs)(sp)
+       ast     $18,(18*8+offes_intregs)(sp)
+       ast     $19,(19*8+offes_intregs)(sp)
+       ast     $20,(20*8+offes_intregs)(sp)
+       ast     $21,(21*8+offes_intregs)(sp)
+       ast     $22,(22*8+offes_intregs)(sp)
+       ast     $23,(23*8+offes_intregs)(sp)
+       ast     $24,(24*8+offes_intregs)(sp)
+       ast     $25,(25*8+offes_intregs)(sp)
+       ast     $26,(26*8+offes_intregs)(sp)
+       ast     $27,(27*8+offes_intregs)(sp)
+       ast     $28,(28*8+offes_intregs)(sp)
+       ast     $29,(29*8+offes_intregs)(sp)
+       ast     $30,(30*8+offes_intregs)(sp)
+       ast     $31,(31*8+offes_intregs)(sp)
+
+#if SIZEOF_VOID_P == 8
+
        sdc1    $f0 ,( 0*8+offes_fltregs)(sp)
        sdc1    $f1 ,( 1*8+offes_fltregs)(sp)
        sdc1    $f2 ,( 2*8+offes_fltregs)(sp)
@@ -635,16 +863,37 @@ asm_replacement_out:
        sdc1    $f29,(29*8+offes_fltregs)(sp)
        sdc1    $f30,(30*8+offes_fltregs)(sp)
        sdc1    $f31,(31*8+offes_fltregs)(sp)
+
+#else /* SIZEOF_VOID_P == 8 */
+
+       sdc1    $f0 ,( 0*8+offes_fltregs)(sp)
+       sdc1    $f2 ,( 2*8+offes_fltregs)(sp)
+       sdc1    $f4 ,( 4*8+offes_fltregs)(sp)
+       sdc1    $f6 ,( 6*8+offes_fltregs)(sp)
+       sdc1    $f8 ,( 8*8+offes_fltregs)(sp)
+       sdc1    $f10,(10*8+offes_fltregs)(sp)
+       sdc1    $f12,(12*8+offes_fltregs)(sp)
+       sdc1    $f14,(14*8+offes_fltregs)(sp)
+       sdc1    $f16,(16*8+offes_fltregs)(sp)
+       sdc1    $f18,(18*8+offes_fltregs)(sp)
+       sdc1    $f20,(20*8+offes_fltregs)(sp)
+       sdc1    $f22,(22*8+offes_fltregs)(sp)
+       sdc1    $f24,(24*8+offes_fltregs)(sp)
+       sdc1    $f26,(26*8+offes_fltregs)(sp)
+       sdc1    $f28,(28*8+offes_fltregs)(sp)
+       sdc1    $f30,(30*8+offes_fltregs)(sp)
+
+#endif /* SIZEOF_VOID_P == 8 */
        
        /* calculate sp of method */
-       daddiu  itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
-       sd      itmp1,(offes_sp)(sp)
+       aaddiu  itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
+       ast     itmp1,(offes_sp)(sp)
 
        /* store pv */
-       sd      pv,(offes_pv)(sp)
+       ast     pv,(offes_pv)(sp)
 
        /* call replace_me */
-       ld      a0,-(2*8)(itmp1)            /* arg0: rplpoint *                   */
+       ald     a0,-(2*8)(itmp1)            /* arg0: rplpoint *                   */
     move    a1,sp                       /* arg1: execution state              */
     jal     replace_me                  /* call C function replace_me         */
        jal     abort                       /* NEVER REACHED                      */
@@ -671,43 +920,45 @@ asm_replacement_in:
        /* a0 == executionstate *es */
 
        /* set new sp and pv */
-       ld      sp,(offes_sp)(a0)
-       ld      pv,(offes_pv)(a0)
+       ald     sp,(offes_sp)(a0)
+       ald     pv,(offes_pv)(a0)
        
        /* copy registers from execution state */
        /* $0 is zero                     */
-       ld      $1 ,( 1*8+offes_intregs)(a0)
-       ld      $2 ,( 2*8+offes_intregs)(a0)
-       ld      $3 ,( 2*8+offes_intregs)(a0)
+       ald     $1 ,( 1*8+offes_intregs)(a0)
+       ald     $2 ,( 2*8+offes_intregs)(a0)
+       ald     $3 ,( 2*8+offes_intregs)(a0)
        /* a0 is loaded below             */
-       ld      $5 ,( 5*8+offes_intregs)(a0)
-       ld      $6 ,( 6*8+offes_intregs)(a0)
-       ld      $7 ,( 7*8+offes_intregs)(a0)
-       ld      $8 ,( 8*8+offes_intregs)(a0)
-       ld      $9 ,( 9*8+offes_intregs)(a0)
-       ld      $10,(10*8+offes_intregs)(a0)
-       ld      $11,(11*8+offes_intregs)(a0)
-       ld      $12,(12*8+offes_intregs)(a0)
-       ld      $13,(13*8+offes_intregs)(a0)
-       ld      $14,(14*8+offes_intregs)(a0)
-       ld      $15,(15*8+offes_intregs)(a0)
-       ld      $16,(16*8+offes_intregs)(a0)
-       ld      $17,(17*8+offes_intregs)(a0)
-       ld      $18,(18*8+offes_intregs)(a0)
-       ld      $19,(19*8+offes_intregs)(a0)
-       ld      $20,(20*8+offes_intregs)(a0)
-       ld      $21,(21*8+offes_intregs)(a0)
-       ld      $22,(22*8+offes_intregs)(a0)
-       ld      $23,(23*8+offes_intregs)(a0)
-       ld      $24,(24*8+offes_intregs)(a0)
-       ld      $25,(25*8+offes_intregs)(a0)
-       ld      $26,(26*8+offes_intregs)(a0)
-       ld      $27,(27*8+offes_intregs)(a0)
-       ld      $28,(28*8+offes_intregs)(a0)
+       ald     $5 ,( 5*8+offes_intregs)(a0)
+       ald     $6 ,( 6*8+offes_intregs)(a0)
+       ald     $7 ,( 7*8+offes_intregs)(a0)
+       ald     $8 ,( 8*8+offes_intregs)(a0)
+       ald     $9 ,( 9*8+offes_intregs)(a0)
+       ald     $10,(10*8+offes_intregs)(a0)
+       ald     $11,(11*8+offes_intregs)(a0)
+       ald     $12,(12*8+offes_intregs)(a0)
+       ald     $13,(13*8+offes_intregs)(a0)
+       ald     $14,(14*8+offes_intregs)(a0)
+       ald     $15,(15*8+offes_intregs)(a0)
+       ald     $16,(16*8+offes_intregs)(a0)
+       ald     $17,(17*8+offes_intregs)(a0)
+       ald     $18,(18*8+offes_intregs)(a0)
+       ald     $19,(19*8+offes_intregs)(a0)
+       ald     $20,(20*8+offes_intregs)(a0)
+       ald     $21,(21*8+offes_intregs)(a0)
+       ald     $22,(22*8+offes_intregs)(a0)
+       ald     $23,(23*8+offes_intregs)(a0)
+       ald     $24,(24*8+offes_intregs)(a0)
+       ald     $25,(25*8+offes_intregs)(a0)
+       ald     $26,(26*8+offes_intregs)(a0)
+       ald     $27,(27*8+offes_intregs)(a0)
+       ald     $28,(28*8+offes_intregs)(a0)
        /* $29 is sp                      */
        /* $30 is pv                      */
-       ld      $31,(31*8+offes_intregs)(a0)
+       ald     $31,(31*8+offes_intregs)(a0)
        
+#if SIZEOF_VOID_P == 8
+
        ldc1    $f0 ,( 0*8+offes_fltregs)(a0)
        ldc1    $f1 ,( 1*8+offes_fltregs)(a0)
        ldc1    $f2 ,( 2*8+offes_fltregs)(a0)
@@ -741,13 +992,34 @@ asm_replacement_in:
        ldc1    $f30,(30*8+offes_fltregs)(a0)
        ldc1    $f31,(31*8+offes_fltregs)(a0)
 
+#else /* SIZEOF_VOID_P == 8 */
+
+       ldc1    $f0 ,( 0*8+offes_fltregs)(a0)
+       ldc1    $f2 ,( 2*8+offes_fltregs)(a0)
+       ldc1    $f4 ,( 4*8+offes_fltregs)(a0)
+       ldc1    $f6 ,( 6*8+offes_fltregs)(a0)
+       ldc1    $f8 ,( 8*8+offes_fltregs)(a0)
+       ldc1    $f10,(10*8+offes_fltregs)(a0)
+       ldc1    $f12,(12*8+offes_fltregs)(a0)
+       ldc1    $f14,(14*8+offes_fltregs)(a0)
+       ldc1    $f16,(16*8+offes_fltregs)(a0)
+       ldc1    $f18,(18*8+offes_fltregs)(a0)
+       ldc1    $f20,(20*8+offes_fltregs)(a0)
+       ldc1    $f22,(22*8+offes_fltregs)(a0)
+       ldc1    $f24,(24*8+offes_fltregs)(a0)
+       ldc1    $f26,(26*8+offes_fltregs)(a0)
+       ldc1    $f28,(28*8+offes_fltregs)(a0)
+       ldc1    $f30,(30*8+offes_fltregs)(a0)
+
+#endif /* SIZEOF_VOID_P == 8 */
+
        /* load new pc */
 
-       ld      itmp3,offes_pc(a0)
+       ald     itmp3,offes_pc(a0)
 
        /* load a0 */
        
-       ld      a0,(4*8+offes_intregs)(a0)
+       ald     a0,(4*8+offes_intregs)(a0)
 
        /* jump to new code */
 
index f861eee18f4678f8d2972fc94588b2fed40bd8b6..4d148930f8bb680ef114e30dee46bedf50256d16 100644 (file)
@@ -34,7 +34,7 @@
    This module generates MIPS machine code for a sequence of
    intermediate code commands (ICMDs).
 
-   $Id: codegen.c 6286 2007-01-10 10:03:38Z twisti $
+   $Id: codegen.c 7206 2007-01-11 22:39:52Z twisti $
 
 */
 
@@ -138,8 +138,14 @@ bool codegen(jitdata *jd)
 #if defined(ENABLE_THREADS)
        /* space to save argument of monitor_enter */
 
-       if (checksync && (m->flags & ACC_SYNCHRONIZED))
+       if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
+# if SIZEOF_VOID_P == 8
                cd->stackframesize++;
+# else
+               rd->memuse++;
+               cd->stackframesize += 2;
+# endif
+       }
 #endif
 
        /* keep stack 16-byte aligned */
@@ -219,16 +225,40 @@ bool codegen(jitdata *jd)
                s1 = md->params[p].regoff;
                if (IS_INT_LNG_TYPE(t)) {                    /* integer args          */
                        if (!md->params[p].inmemory) {           /* register arguments    */
+#if SIZEOF_VOID_P == 8
                                s2 = rd->argintregs[s1];
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
                                        M_INTMOVE(s2, var->vv.regoff);
                                } else {                             /* reg arg -> spilled    */
                                        M_LST(s2, REG_SP, var->vv.regoff * 8);
                                }
-
+#else
+                               if (IS_2_WORD_TYPE(t)) {
+                                       s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                                  rd->argintregs[GET_HIGH_REG(s1)]);
+                                       if (!(var->flags & INMEMORY))    /* reg arg -> register   */
+                                               M_LNGMOVE(s2, var->vv.regoff);
+                                       else                             /* reg arg -> spilled    */
+                                               M_LST(s2, REG_SP, var->vv.regoff * 8);
+                               }
+                               else {
+                                       s2 = rd->argintregs[s1];
+                                       if (!(var->flags & INMEMORY))    /* reg arg -> register   */
+                                               M_INTMOVE(s2, var->vv.regoff);
+                                       else                             /* reg arg -> spilled    */
+                                               M_IST(s2, REG_SP, var->vv.regoff * 8);
+                               }
+#endif
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack arg -> register */
+#if SIZEOF_VOID_P == 8
                                        M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+#else
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+                                       else
+                                               M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
+#endif
                                } else {                             /* stack arg -> spilled  */
                                        var->vv.regoff = cd->stackframesize + s1;
                                }
@@ -236,6 +266,7 @@ bool codegen(jitdata *jd)
 
                } else {                                     /* floating args         */
                        if (!md->params[p].inmemory) {           /* register arguments    */
+#if SIZEOF_VOID_P == 8
                                s2 = rd->argfltregs[s1];
                                if (!(var->flags & INMEMORY)) {      /* reg arg -> register   */
                                        if (IS_2_WORD_TYPE(t))
@@ -248,6 +279,46 @@ bool codegen(jitdata *jd)
                                        else
                                                M_FST(s2, REG_SP, var->vv.regoff * 8);
                                }
+#else
+                               if ((p == 0) ||
+                                       ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
+                                       s2 = rd->argfltregs[s1];
+                                       if (!(var->flags & INMEMORY)) {  /* reg arg -> register   */
+                                               if (IS_2_WORD_TYPE(t))
+                                                       M_DBLMOVE(s2, var->vv.regoff);
+                                               else
+                                                       M_FLTMOVE(s2, var->vv.regoff);
+                                       }
+                                       else {                                   /* reg arg -> spilled    */
+                                               if (IS_2_WORD_TYPE(t))
+                                                       M_DST(s2, REG_SP, var->vv.regoff * 8);
+                                               else
+                                                       M_FST(s2, REG_SP, var->vv.regoff * 8);
+                                       }
+                               }
+                               else {
+                                       if (IS_2_WORD_TYPE(t)) {
+                                               s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                                          rd->argintregs[GET_HIGH_REG(s1)]);
+                                               if (!(var->flags & INMEMORY)) {
+                                                       M_MTC1(GET_LOW_REG(s2), var->vv.regoff);
+                                                       M_MTC1(GET_HIGH_REG(s2), var->vv.regoff + 1);
+                                                       M_NOP;
+                                               }
+                                               else
+                                                       M_LST(s2, REG_SP, var->vv.regoff * 8);
+                                       }
+                                       else {
+                                               s2 = rd->argintregs[s1];
+                                               if (!(var->flags & INMEMORY)) {
+                                                       M_MTC1(s2, var->vv.regoff);
+                                                       M_NOP;
+                                               }
+                                               else
+                                                       M_IST(s2, REG_SP, var->vv.regoff * 8);
+                                       }
+                               }
+#endif
 
                        } else {                                 /* stack arguments       */
                                if (!(var->flags & INMEMORY)) {      /* stack-arg -> register */
@@ -274,7 +345,7 @@ bool codegen(jitdata *jd)
                        M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
 
                        for (p = 0; p < INT_ARG_CNT; p++)
-                               M_LST(rd->argintregs[p], REG_SP, p * 8);
+                               M_AST(rd->argintregs[p], REG_SP, p * 8);
 
                        for (p = 0; p < FLT_ARG_CNT; p++)
                                M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
@@ -310,7 +381,7 @@ bool codegen(jitdata *jd)
 # if !defined(NDEBUG)
                if (opt_verbosecall) {
                        for (p = 0; p < INT_ARG_CNT; p++)
-                               M_LLD(rd->argintregs[p], REG_SP, p * 8);
+                               M_ALD(rd->argintregs[p], REG_SP, p * 8);
 
                        for (p = 0; p < FLT_ARG_CNT; p++)
                                M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
@@ -321,14 +392,13 @@ bool codegen(jitdata *jd)
 # endif
        }
 #endif
+       }
 
 #if !defined(NDEBUG)
        if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
                emit_verbosecall_enter(jd);
 #endif
 
-       }
-
        /* end of header generation */
 
        /* create replacement points */
@@ -391,7 +461,7 @@ bool codegen(jitdata *jd)
                /* walk through all instructions */
                
                len = bptr->icount;
-               currentline = 0;
+/*             currentline = 0; */
 
                for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
                        if (iptr->line != currentline) {
@@ -443,7 +513,11 @@ bool codegen(jitdata *jd)
 
                case ICMD_LCONST:     /* ...  ==> ..., constant                       */
 
+#if SIZEOF_VOID_P == 8
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+#endif
                        LCONST(d, iptr->sx.val.l);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -523,25 +597,46 @@ bool codegen(jitdata *jd)
 
                case ICMD_LNEG:       /* ..., value  ==> ..., - value                 */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_LSUB(REG_ZERO, s1, d);
+#else
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
+                       M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
+                       M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
+                       M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_I2L:        /* ..., value  ==> ..., value                   */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_INTMOVE(s1, d);
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_INTMOVE(s1, GET_LOW_REG(d));
+                       M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_L2I:        /* ..., value  ==> ..., value                   */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_ISLL_IMM(s1, 0, d );
+                       M_ISLL_IMM(s1, 0, d);
+#else
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_INTMOVE(GET_LOW_REG(s1), d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -549,8 +644,13 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
                        M_LSLL_IMM(s1, 56, d);
                        M_LSRA_IMM( d, 56, d);
+#else
+                       M_ISLL_IMM(s1, 24, d);
+                       M_ISRA_IMM( d, 24, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -558,7 +658,7 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-            M_CZEXT(s1, d);
+                       M_AND_IMM(s1, 0xffff, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -566,8 +666,13 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
                        M_LSLL_IMM(s1, 48, d);
                        M_LSRA_IMM( d, 48, d);
+#else
+                       M_ISLL_IMM(s1, 16, d);
+                       M_ISRA_IMM( d, 16, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -598,16 +703,33 @@ bool codegen(jitdata *jd)
 
                case ICMD_LADD:       /* ..., val1, val2  ==> ..., val1 + val2        */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_LADD(s1, s2, d);
+#else
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_IADD(s1, s2, GET_HIGH_REG(d));
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                       s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
+                       if (s1 == GET_LOW_REG(d)) {
+                               M_MOV(s1, REG_ITMP3);
+                               s1 = REG_ITMP3;
+                       }
+                       M_IADD(s1, s2, GET_LOW_REG(d));
+                       M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
+                       M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_LADDCONST:  /* ..., value  ==> ..., value + constant        */
                                      /* sx.val.l = constant                          */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
@@ -616,6 +738,33 @@ bool codegen(jitdata *jd)
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_LADD(s1, REG_ITMP2, d);
                        }
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+                               M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
+                               M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
+                       }
+                       else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+                               M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
+                               M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                               M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
+                               M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+                       }
+                       else {
+                               ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
+                               M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                               M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
+                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
+                               M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+                       }
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -644,16 +793,34 @@ bool codegen(jitdata *jd)
 
                case ICMD_LSUB:       /* ..., val1, val2  ==> ..., val1 - val2        */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_LSUB(s1, s2, d);
+#else
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_ISUB(s1, s2, GET_HIGH_REG(d));
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
+                       M_CMPULT(s1, s2, REG_ITMP3);
+                       M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+                       /* if s1 is equal to REG_ITMP3 we have to reload it, since
+                          the CMPULT instruction destroyed it */
+                       if (s1 == REG_ITMP3)
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                       M_ISUB(s1, s2, GET_LOW_REG(d));
+
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_LSUBCONST:  /* ..., value  ==> ..., value - constant        */
                                      /* sx.val.l = constant                          */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
@@ -662,6 +829,33 @@ bool codegen(jitdata *jd)
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_LSUB(s1, REG_ITMP2, d);
                        }
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+                               M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
+                               M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                               M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
+                               M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+                       }
+                       else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
+                               M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
+                               M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
+                       }
+                       else {
+                               ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
+                               M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                               M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
+                               ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
+                               M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+                       }
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -692,6 +886,7 @@ bool codegen(jitdata *jd)
 
                case ICMD_LMUL:       /* ..., val1, val2  ==> ..., val1 * val2        */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -699,6 +894,28 @@ bool codegen(jitdata *jd)
                        M_MFLO(d);
                        M_NOP;
                        M_NOP;
+#else
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_IMUL(s2, s1);
+                       M_MFLO(REG_ITMP3);
+                       M_NOP;
+                       M_NOP;
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_IMULU(s2, s1);
+                       M_MFHI(GET_HIGH_REG(d));
+                       M_MFLO(GET_LOW_REG(d));
+                       M_NOP;
+                       M_NOP;
+                       M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_IMUL(s1, s2);
+                       M_MFLO(s2);
+                       /* XXX do we need nops here? */
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -728,27 +945,29 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
-               case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
+               case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        emit_arithmetic_check(cd, iptr, s2);
-                       M_LDIV(s1, s2);
-                       M_MFLO(d);
+                       M_IDIV(s1, s2);
+                       M_MFHI(d);
                        M_NOP;
                        M_NOP;
                        emit_store_dst(jd, iptr, d);
                        break;
 
-               case ICMD_IREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
+#if SIZEOF_VOID_P == 8
+
+               case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        emit_arithmetic_check(cd, iptr, s2);
-                       M_IDIV(s1, s2);
-                       M_MFHI(d);
+                       M_LDIV(s1, s2);
+                       M_MFLO(d);
                        M_NOP;
                        M_NOP;
                        emit_store_dst(jd, iptr, d);
@@ -767,20 +986,60 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
+#else /* SIZEOF_VOID_P == 8 */
+
+               case ICMD_LDIV:       /* ..., val1, val2  ==> ..., val1 / val2        */
+               case ICMD_LREM:       /* ..., val1, val2  ==> ..., val1 % val2        */
+
+                       bte = iptr->sx.s23.s3.bte;
+                       md  = bte->md;
+
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
+                       M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
+                       emit_arithmetic_check(cd, iptr, REG_ITMP3);
+
+                       s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
+                                                  rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
+                       M_LNGMOVE(s2, s3);
+
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
+                                                  rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
+                       M_LNGMOVE(s1, s3);
+
+                       disp = dseg_add_functionptr(cd, bte->fp);
+                       M_ALD(REG_ITMP3, REG_PV, disp);
+                       M_JSR(REG_RA, REG_ITMP3);
+                       M_NOP;
+
+                       d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                       M_LNGMOVE(REG_RESULT_PACKED, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
+#endif /* SIZEOF_VOID_P == 8 */
+
                case ICMD_IDIVPOW2:   /* ..., value  ==> ..., value << constant       */
-               case ICMD_LDIVPOW2:   /* val.i = constant                             */
+                                     /* val.i = constant                             */
                                      
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
                        M_LSRA_IMM(s1, 63, REG_ITMP2);
                        M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
                        M_LADD(s1, REG_ITMP2, REG_ITMP2);
                        M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
+#else
+                       M_ISRA_IMM(s1, 31, REG_ITMP2);
+                       M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
+                       M_IADD(s1, REG_ITMP2, REG_ITMP2);
+                       M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_IREMPOW2:   /* ..., value  ==> ..., value % constant        */
-                                     /* sx.val.i = constant                          */
+                                     /* val.i = constant                             */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -807,8 +1066,22 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
+#if SIZEOF_VOID_P == 8
+
+               case ICMD_LDIVPOW2:   /* ..., value  ==> ..., value << constant       */
+                                     /* val.i = constant                             */
+                                     
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_LSRA_IMM(s1, 63, REG_ITMP2);
+                       M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
+                       M_LADD(s1, REG_ITMP2, REG_ITMP2);
+                       M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
                case ICMD_LREMPOW2:   /* ..., value  ==> ..., value % constant        */
-                                     /* sx.val.l = constant                          */
+                                     /* val.l = constant                             */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -835,6 +1108,8 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
+#endif /* SIZEOF_VOID_P == 8 */
+
                case ICMD_ISHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
@@ -891,13 +1166,43 @@ bool codegen(jitdata *jd)
 
                case ICMD_LSHL:       /* ..., val1, val2  ==> ..., val1 << val2       */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_LSLL(s1, s2, d);
+#else
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP3);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+
+                       M_ISLL(s2, 26, REG_ITMP1);
+                       M_BGEZ(REG_ITMP1, 3);
+                       M_NOP;
+
+                       M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
+                       M_BR(7);
+                       M_MOV(REG_ZERO, GET_LOW_REG(d));                    /* delay slot */
+
+#if 1
+                       M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
+#endif
+                       M_BEQZ(REG_ITMP1, 4);
+                       M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d));      /* delay slot */
+
+                       M_ISUB(s2, REG_ZERO, REG_ITMP3);
+                       M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
+                       M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
+
+#if 0
+                       M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
+#endif
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
+#if SIZEOF_VOID_P == 8
+
                case ICMD_LSHLCONST:  /* ..., value  ==> ..., value << constant       */
                                      /* sx.val.i = constant                             */
 
@@ -943,8 +1248,9 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
+#endif /* SIZEOF_VOID_P == 8 */
+
                case ICMD_IAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
-               case ICMD_LAND:
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -958,18 +1264,38 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
+                       if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
                                M_AND_IMM(s1, iptr->sx.val.i, d);
-                       else {
+                       else {
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_AND(s1, REG_ITMP2, d);
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
 
+               case ICMD_LAND:       /* ..., val1, val2  ==> ..., val1 & val2        */
+
+#if SIZEOF_VOID_P == 8
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
+                       M_AND(s1, s2, d);
+#else
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_AND(s1, s2, GET_LOW_REG(d));
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       M_AND(s1, s2, GET_HIGH_REG(d));
+#endif
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
                case ICMD_LANDCONST:  /* ..., value  ==> ..., value & constant        */
                                      /* sx.val.l = constant                          */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
@@ -978,16 +1304,30 @@ bool codegen(jitdata *jd)
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_AND(s1, REG_ITMP2, d);
                        }
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+                               M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
+                       }
+                       else {
+                               LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
+                               M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
+                       }
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_IOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
-               case ICMD_LOR:
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
-                       M_OR(s1,s2, d);
+                       M_OR(s1, s2, d);
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1005,9 +1345,29 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
+               case ICMD_LOR:        /* ..., val1, val2  ==> ..., val1 | val2        */
+
+#if SIZEOF_VOID_P == 8
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_OR(s1, s2, d);
+#else
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_OR(s1, s2, GET_LOW_REG(d));
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       M_OR(s1, s2, GET_HIGH_REG(d));
+#endif
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
                case ICMD_LORCONST:   /* ..., value  ==> ..., value | constant        */
                                      /* sx.val.l = constant                          */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
@@ -1016,11 +1376,25 @@ bool codegen(jitdata *jd)
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_OR(s1, REG_ITMP2, d);
                        }
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+                               M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
+                       }
+                       else {
+                               LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
+                               M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
+                       }
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
                case ICMD_IXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
-               case ICMD_LXOR:
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -1043,9 +1417,29 @@ bool codegen(jitdata *jd)
                        emit_store_dst(jd, iptr, d);
                        break;
 
+               case ICMD_LXOR:       /* ..., val1, val2  ==> ..., val1 ^ val2        */
+
+#if SIZEOF_VOID_P == 8
+                       s1 = emit_load_s1(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_XOR(s1, s2, d);
+#else
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       M_XOR(s1, s2, GET_LOW_REG(d));
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
+                       M_XOR(s1, s2, GET_HIGH_REG(d));
+#endif
+                       emit_store_dst(jd, iptr, d);
+                       break;
+
                case ICMD_LXORCONST:  /* ..., value  ==> ..., value ^ constant        */
                                      /* sx.val.l = constant                          */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
@@ -1054,18 +1448,49 @@ bool codegen(jitdata *jd)
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_XOR(s1, REG_ITMP2, d);
                        }
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+                       if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
+                               M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
+                       }
+                       else {
+                               LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
+                               M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
+                       }
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
 
                case ICMD_LCMP:       /* ..., val1, val2  ==> ..., val1 cmp val2      */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                        M_CMPLT(s1, s2, REG_ITMP3);
                        M_CMPLT(s2, s1, REG_ITMP1);
                        M_LSUB(REG_ITMP1, REG_ITMP3, d);
+#else
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+                       M_CMPLT(s1, s2, REG_ITMP3);
+                       M_CMPLT(s2, s1, REG_ITMP1);
+                       M_ISUB(REG_ITMP1, REG_ITMP3, d);
+                       M_BNEZ(d, 4);
+                       M_NOP;
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_CMPULT(s1, s2, REG_ITMP3);
+                       M_CMPULT(s2, s1, REG_ITMP1);
+                       M_ISUB(REG_ITMP1, REG_ITMP3, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1273,11 +1698,11 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        M_FCMPULEF(s1, s2);
                        M_FBT(3);
-                       M_LADD_IMM(REG_ZERO, 1, d);
+                       M_AADD_IMM(REG_ZERO, 1, d);
                        M_BR(4);
                        M_NOP;
                        M_FCMPEQF(s1, s2);
-                       M_LSUB_IMM(REG_ZERO, 1, d);
+                       M_ASUB_IMM(REG_ZERO, 1, d);
                        M_CMOVT(REG_ZERO, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1289,11 +1714,11 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        M_FCMPULED(s1, s2);
                        M_FBT(3);
-                       M_LADD_IMM(REG_ZERO, 1, d);
+                       M_AADD_IMM(REG_ZERO, 1, d);
                        M_BR(4);
                        M_NOP;
                        M_FCMPEQD(s1, s2);
-                       M_LSUB_IMM(REG_ZERO, 1, d);
+                       M_ASUB_IMM(REG_ZERO, 1, d);
                        M_CMOVT(REG_ZERO, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1305,11 +1730,11 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        M_FCMPOLTF(s1, s2);
                        M_FBF(3);
-                       M_LSUB_IMM(REG_ZERO, 1, d);
+                       M_ASUB_IMM(REG_ZERO, 1, d);
                        M_BR(4);
                        M_NOP;
                        M_FCMPEQF(s1, s2);
-                       M_LADD_IMM(REG_ZERO, 1, d);
+                       M_AADD_IMM(REG_ZERO, 1, d);
                        M_CMOVT(REG_ZERO, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1321,11 +1746,11 @@ bool codegen(jitdata *jd)
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
                        M_FCMPOLTD(s1, s2);
                        M_FBF(3);
-                       M_LSUB_IMM(REG_ZERO, 1, d);
+                       M_ASUB_IMM(REG_ZERO, 1, d);
                        M_BR(4);
                        M_NOP;
                        M_FCMPEQD(s1, s2);
-                       M_LADD_IMM(REG_ZERO, 1, d);
+                       M_AADD_IMM(REG_ZERO, 1, d);
                        M_CMOVT(REG_ZERO, d);
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -1393,7 +1818,11 @@ bool codegen(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+#if SIZEOF_VOID_P == 8
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#else
+                       d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
+#endif
                        emit_array_checks(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP3);
                        M_AADD(REG_ITMP3, s1, REG_ITMP3);
@@ -1478,7 +1907,11 @@ bool codegen(jitdata *jd)
                        emit_array_checks(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
                        s3 = emit_load_s3(jd, iptr, REG_ITMP3);
+#else
+                       s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
+#endif
                        M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
                        break;
 
@@ -1570,7 +2003,11 @@ bool codegen(jitdata *jd)
                        emit_array_checks(cd, iptr, s1, s2);
                        M_ASLL_IMM(s2, 3, REG_ITMP2);
                        M_AADD(REG_ITMP2, s1, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
                        M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
+#else
+                       M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
+#endif
                        break;
 
                case ICMD_AASTORECONST:   /* ..., arrayref, index  ==> ...            */
@@ -1610,7 +2047,11 @@ bool codegen(jitdata *jd)
                                M_ILD_INTERN(d, REG_ITMP1, 0);
                                break;
                        case TYPE_LNG:
+#if SIZEOF_VOID_P == 8
                                d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
+#else
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
+#endif
                                M_LLD_INTERN(d, REG_ITMP1, 0);
                                break;
                        case TYPE_ADR:
@@ -1655,7 +2096,11 @@ bool codegen(jitdata *jd)
                                M_IST_INTERN(s1, REG_ITMP1, 0);
                                break;
                        case TYPE_LNG:
+#if SIZEOF_VOID_P == 8
                                s1 = emit_load_s1(jd, iptr, REG_ITMP2);
+#else
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
+#endif
                                M_LST_INTERN(s1, REG_ITMP1, 0);
                                break;
                        case TYPE_ADR:
@@ -1739,8 +2184,13 @@ bool codegen(jitdata *jd)
                                M_ILD(d, s1, disp);
                                break;
                        case TYPE_LNG:
+#if SIZEOF_VOID_P == 8
                                d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
                                M_LLD(d, s1, disp);
+#else
+                               d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
+                               M_LLD_GETFIELD(d, s1, disp);
+#endif
                                break;
                        case TYPE_ADR:
                                d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
@@ -1774,10 +2224,21 @@ bool codegen(jitdata *jd)
                                disp      = fi->offset;
                        }
 
+#if SIZEOF_VOID_P == 8
                        if (IS_INT_LNG_TYPE(fieldtype))
                                s2 = emit_load_s2(jd, iptr, REG_ITMP2);
                        else
                                s2 = emit_load_s2(jd, iptr, REG_FTMP1);
+#else
+                       if (IS_INT_LNG_TYPE(fieldtype)) {
+                               if (IS_2_WORD_TYPE(fieldtype))
+                                       s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
+                               else
+                                       s2 = emit_load_s2(jd, iptr, REG_ITMP2);
+                       }
+                       else
+                               s2 = emit_load_s2(jd, iptr, REG_FTMP2);
+#endif
 
                        if (INSTRUCTION_IS_UNRESOLVED(iptr))
                                codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
@@ -1933,18 +2394,16 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.i == 0) {
                                M_BLEZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
                                        M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
                                        M_BNEZ(REG_ITMP1, 0);
-                                       }
-                               else {
+                               } else {
                                        ICONST(REG_ITMP2, iptr->sx.val.i);
                                        M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
                                        M_BEQZ(REG_ITMP1, 0);
-                                       }
                                }
+                       }
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
@@ -1954,11 +2413,10 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.i == 0) {
                                M_BNEZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                ICONST(REG_ITMP2, iptr->sx.val.i);
                                M_BNE(s1, REG_ITMP2, 0);
-                               }
+                       }
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
@@ -1968,18 +2426,16 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.i == 0) {
                                M_BGTZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
                                        M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
                                        M_BEQZ(REG_ITMP1, 0);
-                                       }
-                               else {
+                               } else {
                                        ICONST(REG_ITMP2, iptr->sx.val.i);
                                        M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
                                        M_BNEZ(REG_ITMP1, 0);
-                                       }
                                }
+                       }
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
@@ -1989,134 +2445,256 @@ bool codegen(jitdata *jd)
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.i == 0) {
                                M_BGEZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
                                        M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
-                                       }
-                               else {
+                               } else {
                                        ICONST(REG_ITMP2, iptr->sx.val.i);
                                        M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
-                                       }
-                               M_BEQZ(REG_ITMP1, 0);
                                }
+                               M_BEQZ(REG_ITMP1, 0);
+                       }
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
                case ICMD_IF_LEQ:       /* ..., value ==> ...                         */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
                                M_BEQZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_BEQ(s1, REG_ITMP2, 0);
-                               }
+                       }
+#else
+                       if (iptr->sx.val.l == 0) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
+                               M_BEQZ(REG_ITMP3, 0);
+                       }
+                       else {
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+                               M_XOR(s1, REG_ITMP2, REG_ITMP2);
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
+                               M_XOR(s1, REG_ITMP3, REG_ITMP3);
+                               M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
+                               M_BEQZ(REG_ITMP3, 0);
+                       }
+#endif
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
                case ICMD_IF_LLT:       /* ..., value ==> ...                         */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
                                M_BLTZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
                                        M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
-                                       }
-                               else {
+                               } else {
                                        LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
-                                       }
-                               M_BNEZ(REG_ITMP1, 0);
                                }
+                               M_BNEZ(REG_ITMP1, 0);
+                       }
+#else
+                       if (iptr->sx.val.l == 0) {
+                               /* if high word is less than zero, the whole long is too */
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               M_BLTZ(s1, 0);
+                       }
+                       else {
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+                               M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                               codegen_add_branch_ref(cd, iptr->dst.block);
+                               M_NOP;
+                               s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_BNE(s1, REG_ITMP2, 5);
+                               M_NOP;
+                               ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+                               M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                       }
+#endif
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
                case ICMD_IF_LLE:       /* ..., value ==> ...                         */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
                                M_BLEZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
                                        M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
                                        M_BNEZ(REG_ITMP1, 0);
-                                       }
-                               else {
+                               } else {
                                        LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
                                        M_BEQZ(REG_ITMP1, 0);
-                                       }
                                }
+                       }
+#else
+                       if (iptr->sx.val.l == 0) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_BGTZ(GET_HIGH_REG(s1), 5);
+                               M_NOP;
+                               M_BLTZ(GET_HIGH_REG(s1), 0);
+                               codegen_add_branch_ref(cd, iptr->dst.block);
+                               M_NOP;
+                               M_BEQZ(GET_LOW_REG(s1), 0);
+                       }
+                       else {
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+                               M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                               codegen_add_branch_ref(cd, iptr->dst.block);
+                               M_NOP;
+                               s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_BNE(s1, REG_ITMP2, 5);
+                               M_NOP;
+                               ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+                               M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
+                               M_BEQZ(REG_ITMP3, 0);
+                       }
+#endif
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
                case ICMD_IF_LNE:       /* ..., value ==> ...                         */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
                                M_BNEZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                LCONST(REG_ITMP2, iptr->sx.val.l);
                                M_BNE(s1, REG_ITMP2, 0);
-                               }
+                       }
+#else
+                       if (iptr->sx.val.l == 0) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                       }
+                       else {
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+                               M_XOR(s1, REG_ITMP2, REG_ITMP2);
+                               s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
+                               M_XOR(s1, REG_ITMP3, REG_ITMP3);
+                               M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                       }
+#endif
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
                case ICMD_IF_LGT:       /* ..., value ==> ...                         */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
                                M_BGTZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
                                        M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
                                        M_BEQZ(REG_ITMP1, 0);
-                                       }
-                               else {
+                               } else {
                                        LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
                                        M_BNEZ(REG_ITMP1, 0);
-                                       }
                                }
+                       }
+#else
+                       if (iptr->sx.val.l == 0) {
+                               s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
+                               M_BGTZ(GET_HIGH_REG(s1), 0);
+                               codegen_add_branch_ref(cd, iptr->dst.block);
+                               M_NOP;
+                               M_BLTZ(GET_HIGH_REG(s1), 3);
+                               M_NOP;
+                               M_BNEZ(GET_LOW_REG(s1), 0);
+                       }
+                       else {
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+                               M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                               codegen_add_branch_ref(cd, iptr->dst.block);
+                               M_NOP;
+                               s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_BNE(s1, REG_ITMP2, 5);
+                               M_NOP;
+                               ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+                               M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                       }
+#endif
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
                case ICMD_IF_LGE:       /* ..., value ==> ...                         */
 
+#if SIZEOF_VOID_P == 8
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        if (iptr->sx.val.l == 0) {
                                M_BGEZ(s1, 0);
-                               }
-                       else {
+                       } else {
                                if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
                                        M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
-                                       }
-                               else {
+                               } else {
                                        LCONST(REG_ITMP2, iptr->sx.val.l);
                                        M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
-                                       }
-                               M_BEQZ(REG_ITMP1, 0);
                                }
+                               M_BEQZ(REG_ITMP1, 0);
+                       }
+#else
+                       if (iptr->sx.val.l == 0) {
+                               /* if high word is greater equal zero, the whole long is too */
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               M_BGEZ(s1, 0);
+                       }
+                       else {
+                               s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                               ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
+                               M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
+                               M_BNEZ(REG_ITMP3, 0);
+                               codegen_add_branch_ref(cd, iptr->dst.block);
+                               M_NOP;
+                               s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
+                               M_BNE(s1, REG_ITMP2, 5);
+                               M_NOP;
+                               ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
+                               M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
+                               M_BEQZ(REG_ITMP3, 0);
+                       }
+#endif
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
                case ICMD_IF_ICMPEQ:    /* ..., value, value ==> ...                  */
-               case ICMD_IF_LCMPEQ:    /* op1 = target JavaVM pc                     */
-               case ICMD_IF_ACMPEQ:
+               case ICMD_IF_ACMPEQ:    /* op1 = target JavaVM pc                     */
+#if SIZEOF_VOID_P == 8
+               case ICMD_IF_LCMPEQ:
+#endif
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -2125,9 +2703,27 @@ bool codegen(jitdata *jd)
                        M_NOP;
                        break;
 
+#if SIZEOF_VOID_P == 4
+               case ICMD_IF_LCMPEQ:    /* ..., value, value ==> ...                  */
+                                       /* op1 = target JavaVM pc                     */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_BNE(s1, s2, 3);
+                       M_NOP;
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BEQ(s1, s2, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       break;
+#endif
+
                case ICMD_IF_ICMPNE:    /* ..., value, value ==> ...                  */
-               case ICMD_IF_LCMPNE:    /* op1 = target JavaVM pc                     */
-               case ICMD_IF_ACMPNE:
+               case ICMD_IF_ACMPNE:    /* op1 = target JavaVM pc                     */
+#if SIZEOF_VOID_P == 8
+               case ICMD_IF_LCMPNE:
+#endif
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -2136,53 +2732,166 @@ bool codegen(jitdata *jd)
                        M_NOP;
                        break;
 
+#if SIZEOF_VOID_P == 4
+               case ICMD_IF_LCMPNE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_BNE(s1, s2, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BNE(s1, s2, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       break;
+#endif
+
                case ICMD_IF_ICMPLT:    /* ..., value, value ==> ...                  */
+#if SIZEOF_VOID_P == 8
                case ICMD_IF_LCMPLT:    /* op1 = target JavaVM pc                     */
+#endif
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMPLT(s1, s2, REG_ITMP1);
-                       M_BNEZ(REG_ITMP1, 0);
+                       M_CMPLT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       break;
+
+#if SIZEOF_VOID_P == 4
+               case ICMD_IF_LCMPLT:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMPLT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       M_CMPGT(s1, s2, REG_ITMP3);
+                       /* load low-bits before the branch, so we know the distance */
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BNEZ(REG_ITMP3, 4);
+                       M_NOP;
+                       M_CMPULT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
+#endif
 
                case ICMD_IF_ICMPGT:    /* ..., value, value ==> ...                  */
+#if SIZEOF_VOID_P == 8
                case ICMD_IF_LCMPGT:    /* op1 = target JavaVM pc                     */
+#endif
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMPGT(s1, s2, REG_ITMP1);
-                       M_BNEZ(REG_ITMP1, 0);
+                       M_CMPGT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
+#if SIZEOF_VOID_P == 4
+               case ICMD_IF_LCMPGT:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMPGT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       M_CMPLT(s1, s2, REG_ITMP3);
+                       /* load low-bits before the branch, so we know the distance */
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BNEZ(REG_ITMP3, 4);
+                       M_NOP;
+                       M_CMPUGT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       break;
+#endif
+
                case ICMD_IF_ICMPLE:    /* ..., value, value ==> ...                  */
+#if SIZEOF_VOID_P == 8
                case ICMD_IF_LCMPLE:    /* op1 = target JavaVM pc                     */
+#endif
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMPGT(s1, s2, REG_ITMP1);
-                       M_BEQZ(REG_ITMP1, 0);
+                       M_CMPGT(s1, s2, REG_ITMP3);
+                       M_BEQZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       break;
+
+#if SIZEOF_VOID_P == 4
+               case ICMD_IF_LCMPLE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMPLT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       M_CMPGT(s1, s2, REG_ITMP3);
+                       /* load low-bits before the branch, so we know the distance */
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BNEZ(REG_ITMP3, 4);
+                       M_NOP;
+                       M_CMPUGT(s1, s2, REG_ITMP3);
+                       M_BEQZ(REG_ITMP3, 0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
+#endif
 
                case ICMD_IF_ICMPGE:    /* ..., value, value ==> ...                  */
+#if SIZEOF_VOID_P == 8
                case ICMD_IF_LCMPGE:    /* op1 = target JavaVM pc                     */
+#endif
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        s2 = emit_load_s2(jd, iptr, REG_ITMP2);
-                       M_CMPLT(s1, s2, REG_ITMP1);
-                       M_BEQZ(REG_ITMP1, 0);
+                       M_CMPLT(s1, s2, REG_ITMP3);
+                       M_BEQZ(REG_ITMP3, 0);
                        codegen_add_branch_ref(cd, iptr->dst.block);
                        M_NOP;
                        break;
 
+#if SIZEOF_VOID_P == 4
+               case ICMD_IF_LCMPGE:    /* ..., value, value ==> ...                  */
+
+                       s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
+                       M_CMPGT(s1, s2, REG_ITMP3);
+                       M_BNEZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       M_CMPLT(s1, s2, REG_ITMP3);
+                       /* load low-bits before the branch, so we know the distance */
+                       s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
+                       s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
+                       M_BNEZ(REG_ITMP3, 4);
+                       M_NOP;
+                       M_CMPULT(s1, s2, REG_ITMP3);
+                       M_BEQZ(REG_ITMP3, 0);
+                       codegen_add_branch_ref(cd, iptr->dst.block);
+                       M_NOP;
+                       break;
+#endif
 
                case ICMD_IRETURN:      /* ..., retvalue ==> ...                      */
+#if SIZEOF_VOID_P == 8
                case ICMD_LRETURN:
+#endif
 
                        REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_RESULT);
@@ -2204,8 +2913,15 @@ bool codegen(jitdata *jd)
 #endif /* ENABLE_VERIFIER */
                        goto nowperformreturn;
 
-           case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
+#if SIZEOF_VOID_P == 4
+               case ICMD_LRETURN:      /* ..., retvalue ==> ...                      */
 
+                       s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
+                       M_LNGMOVE(s1, REG_RESULT_PACKED);
+                       goto nowperformreturn;
+#endif
+
+           case ICMD_FRETURN:      /* ..., retvalue ==> ...                      */
                        REPLACEMENT_POINT_RETURN(cd, iptr);
                        s1 = emit_load_s1(jd, iptr, REG_FRESULT);
                        M_FLTMOVE(s1, REG_FRESULT);
@@ -2243,11 +2959,21 @@ nowperformreturn:
                                switch (iptr->opc) {
                                case ICMD_IRETURN:
                                case ICMD_ARETURN:
+#if SIZEOF_VOID_P == 8
+                               case ICMD_LRETURN:
+#endif
+                                       M_ALD(REG_A0, REG_SP, rd->memuse * 8);
+                                       M_JSR(REG_RA, REG_ITMP3);
+                                       M_AST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
+                                       break;
+#if SIZEOF_VOID_P == 4
                                case ICMD_LRETURN:
                                        M_ALD(REG_A0, REG_SP, rd->memuse * 8);
+                                       M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
                                        M_JSR(REG_RA, REG_ITMP3);
-                                       M_LST(REG_RESULT, REG_SP, rd->memuse * 8);  /* delay slot */
+                                       M_NOP;
                                        break;
+#endif
                                case ICMD_FRETURN:
                                case ICMD_DRETURN:
                                        M_ALD(REG_A0, REG_SP, rd->memuse * 8);
@@ -2265,9 +2991,16 @@ nowperformreturn:
                                switch (iptr->opc) {
                                case ICMD_IRETURN:
                                case ICMD_ARETURN:
+#if SIZEOF_VOID_P == 8
                                case ICMD_LRETURN:
-                                       M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
+#endif
+                                       M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
                                        break;
+#if SIZEOF_VOID_P == 4
+                               case ICMD_LRETURN:
+                                       M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
+                                       break;
+#endif
                                case ICMD_FRETURN:
                                case ICMD_DRETURN:
                                        M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
@@ -2285,7 +3018,7 @@ nowperformreturn:
                        /* restore saved registers                                        */
 
                        for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
-                               p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
+                               p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
                        }
                        for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
                                p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
@@ -2302,12 +3035,12 @@ nowperformreturn:
 
                                if (hi == 0) {
                                        M_RET(REG_RA);
-                                       M_LADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
+                                       M_AADD_IMM(REG_SP, lo, REG_SP);             /* delay slot */
                                } else {
                                        M_LUI(REG_ITMP3,hi);
-                                       M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
+                                       M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
                                        M_RET(REG_RA);
-                                       M_LADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
+                                       M_AADD(REG_ITMP3,REG_SP,REG_SP);            /* delay slot */
                                }
 
                        } else {
@@ -2349,7 +3082,7 @@ nowperformreturn:
                        M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
                        M_BEQZ(REG_ITMP2, 0);
                        codegen_add_branch_ref(cd, table[0].block); /* default target */
-                       M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);      /* delay slot*/
+                       M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);     /* delay slot */
 
                        /* build jump table top down and use address of lowest entry */
 
@@ -2438,6 +3171,7 @@ gen_method:
                                        continue;
 
                                if (IS_INT_LNG_TYPE(var->type)) {
+#if SIZEOF_VOID_P == 8
                                        if (!md->params[s3].inmemory) {
                                                s1 = rd->argintregs[md->params[s3].regoff];
                                                d = emit_load(jd, iptr, var, s1);
@@ -2447,15 +3181,70 @@ gen_method:
                                                d = emit_load(jd, iptr, var, REG_ITMP1);
                                                M_LST(d, REG_SP, md->params[s3].regoff * 8);
                                        }
+#else
+                                       if (!md->params[s3].inmemory) {
+                                               if (IS_2_WORD_TYPE(var->type)) {
+                                                       s1 = md->params[s3].regoff;
+                                                       s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                                                  rd->argintregs[GET_HIGH_REG(s1)]);
+                                                       d = emit_load(jd, iptr, var, s1);
+                                                       M_LNGMOVE(d, s1);
+                                               }
+                                               else {
+                                                       s1 = rd->argintregs[md->params[s3].regoff];
+                                                       d = emit_load(jd, iptr, var, s1);
+                                                       M_INTMOVE(d, s1);
+                                               }
+                                       }
+                                       else {
+                                               if (IS_2_WORD_TYPE(var->type)) {
+                                                       d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
+                                                       M_LST(d, REG_SP, md->params[s3].regoff * 8);
+                                               }
+                                               else {
+                                                       d = emit_load(jd, iptr, var, REG_ITMP1);
+                                                       M_IST(d, REG_SP, md->params[s3].regoff * 8);
+                                               }
+                                       }
+#endif
                                }
                                else {
                                        if (!md->params[s3].inmemory) {
+#if SIZEOF_VOID_P == 8
                                                s1 = rd->argfltregs[md->params[s3].regoff];
                                                d = emit_load(jd, iptr, var, s1);
                                                if (IS_2_WORD_TYPE(var->type))
                                                        M_DMOV(d, s1);
                                                else
                                                        M_FMOV(d, s1);
+#else
+                                               if ((s3 == 0) ||
+                                                       ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
+                                                       s1 = rd->argfltregs[md->params[s3].regoff];
+                                                       d = emit_load(jd, iptr, var, s1);
+                                                       if (IS_2_WORD_TYPE(var->type))
+                                                               M_DBLMOVE(d, s1);
+                                                       else
+                                                               M_FLTMOVE(d, s1);
+                                               }
+                                               else {
+                                                       if (IS_2_WORD_TYPE(var->type)) {
+                                                               s1 = md->params[s3].regoff;
+                                                               s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                                                          rd->argintregs[GET_HIGH_REG(s1)]);
+                                                               d = emit_load(jd, iptr, var, REG_FTMP1);
+                                                               M_MFC1(GET_LOW_REG(s2), d);
+                                                               M_MFC1(GET_HIGH_REG(s2), d + 1);
+                                                               M_NOP;
+                                                       }
+                                                       else {
+                                                               s1 = rd->argintregs[md->params[s3].regoff];
+                                                               d = emit_load(jd, iptr, var, s1);
+                                                               M_MFC1(s1, d);
+                                                               M_NOP;
+                                                       }
+                                               }       
+#endif
                                        }
                                        else {
                                                d = emit_load(jd, iptr, var, REG_FTMP1);
@@ -2564,8 +3353,19 @@ gen_method:
 
                        if (d != TYPE_VOID) {
                                if (IS_INT_LNG_TYPE(d)) {
+#if SIZEOF_VOID_P == 8
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
                                        M_INTMOVE(REG_RESULT, s1);
+#else
+                                       if (IS_2_WORD_TYPE(d)) {
+                                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
+                                               M_LNGMOVE(REG_RESULT_PACKED, s1);
+                                       }
+                                       else {
+                                               s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
+                                               M_INTMOVE(REG_RESULT, s1);
+                                       }
+#endif
                                }
                                else {
                                        s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
@@ -2910,7 +3710,11 @@ gen_method:
 
                                if (!(var->flags & PREALLOC)) {
                                        s2 = emit_load(jd, iptr, var, REG_ITMP1);
+#if SIZEOF_VOID_P == 8
                                        M_LST(s2, REG_SP, s1 * 8);
+#else
+                                       M_IST(s2, REG_SP, (s1 + 2) * 8);
+#endif
                                }
                        }
 
@@ -2936,7 +3740,11 @@ gen_method:
 
                        /* a2 = pointer to dimensions = stack pointer */
 
-                       M_INTMOVE(REG_SP, REG_A2);
+#if SIZEOF_VOID_P == 8
+                       M_MOV(REG_SP, REG_A2);
+#else
+                       M_AADD_IMM(REG_SP, 4*4, REG_A2);
+#endif
 
                        disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
                        M_ALD(REG_ITMP3, REG_PV, disp);
@@ -3092,9 +3900,17 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
                sizeof(stackframeinfo) / SIZEOF_VOID_P +
                sizeof(localref_table) / SIZEOF_VOID_P +
                md->paramcount +                /* for saving arguments over calls    */
+#if SIZEOF_VOID_P == 4
+               5 +                             /* additional save space (MIPS32)     */
+#endif
                1 +                             /* for saving return address          */
                nmd->memuse;
 
+       /* adjust stackframe size for 16-byte alignment */
+
+       if (cd->stackframesize & 1)
+               cd->stackframesize++;
+
        /* create method header */
 
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
@@ -3127,16 +3943,38 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* save integer and float argument registers */
 
+#if SIZEOF_VOID_P == 8
        for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
-               if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
-                       M_LST(rd->argintregs[i], REG_SP, j * 8);
+               if (IS_INT_LNG_TYPE(md->params[i].type)) {
+                       M_AST(rd->argintregs[i], REG_SP, j * 8);
                        j++;
                }
        }
+#else
+       for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
+               if (IS_INT_LNG_TYPE(md->params[i].type)) {
+                       if (!md->params[i].inmemory) {
+                               s1 = md->params[i].regoff;
+                               if (IS_2_WORD_TYPE(md->params[i].type)) {
+                                       s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                                  rd->argintregs[GET_HIGH_REG(s1)]);
+                                       M_LST(s1, REG_SP, j * 8);
+                               }
+                               else {
+                                       M_IST(rd->argintregs[s1], REG_SP, j * 8);
+                               }
+                               j++;
+                       }
+               }
+       }
+#endif
 
        for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
-               if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
-                       M_DST(rd->argfltregs[i], REG_SP, j * 8);
+               if (IS_FLT_DBL_TYPE(md->params[i].type)) {
+                       if (IS_2_WORD_TYPE(md->params[i].type))
+                               M_DST(rd->argfltregs[i], REG_SP, j * 8);
+                       else
+                               M_FST(rd->argfltregs[i], REG_SP, j * 8);
                        j++;
                }
        }
@@ -3154,16 +3992,38 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
 
        /* restore integer and float argument registers */
 
+#if SIZEOF_VOID_P == 8
        for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
-               if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
+               if (IS_INT_LNG_TYPE(md->params[i].type)) {
                        M_LLD(rd->argintregs[i], REG_SP, j * 8);
                        j++;
                }
        }
+#else
+       for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
+               if (IS_INT_LNG_TYPE(md->params[i].type)) {
+                       if (!md->params[i].inmemory) {
+                               s1 = md->params[i].regoff;
+                               if (IS_2_WORD_TYPE(md->params[i].type)) {
+                                       s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                                  rd->argintregs[GET_HIGH_REG(s1)]);
+                                       M_LLD(s1, REG_SP, j * 8);
+                               }
+                               else {
+                                       M_ILD(rd->argintregs[s1], REG_SP, j * 8);
+                               }
+                               j++;
+                       }
+               }
+       }
+#endif
 
        for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
-               if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
-                       M_DLD(rd->argfltregs[i], REG_SP, j * 8);
+               if (IS_FLT_DBL_TYPE(md->params[i].type)) {
+                       if (IS_2_WORD_TYPE(md->params[i].type))
+                               M_DLD(rd->argfltregs[i], REG_SP, j * 8);
+                       else
+                               M_FLD(rd->argfltregs[i], REG_SP, j * 8);
                        j++;
                }
        }
@@ -3171,53 +4031,139 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        /* copy or spill arguments to new locations */
 
        for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
-               t = md->paramtypes[i].type;
+               t = md->params[i].type;
 
                if (IS_INT_LNG_TYPE(t)) {
                        if (!md->params[i].inmemory) {
-                               s1 = rd->argintregs[md->params[i].regoff];
+                               s1 = md->params[i].regoff;
+#if SIZEOF_VOID_P == 8
+                               s1 = rd->argintregs[s1];
+#else
+                               if (IS_2_WORD_TYPE(t))
+                                       s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
+                                                                  rd->argintregs[GET_HIGH_REG(s1)]);
+                               else
+                                       s1 = rd->argintregs[s1];
+#endif
 
                                if (!nmd->params[j].inmemory) {
-                                       s2 = rd->argintregs[nmd->params[j].regoff];
-                                       M_INTMOVE(s1, s2);
-                               } else {
                                        s2 = nmd->params[j].regoff;
-                                       M_AST(s1, REG_SP, s2 * 8);
+#if SIZEOF_VOID_P == 8
+                                       s2 = rd->argintregs[s2];
+                                       M_INTMOVE(s1, s2);
+#else
+                                       if (IS_2_WORD_TYPE(t)) {
+                                               s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
+                                                                          rd->argintregs[GET_HIGH_REG(s2)]);
+                                               M_LNGMOVE(s1, s2);
+                                       }
+                                       else {
+                                               s2 = rd->argintregs[s2];
+                                               M_INTMOVE(s1, s2);
+                                       }
+#endif
                                }
+                               else {
+                                       s2 = nmd->params[j].regoff;
 
-                       } else {
+#if SIZEOF_VOID_P == 8
+                                       M_LST(s1, REG_SP, s2 * 8);
+#else
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_LST(s1, REG_SP, s2 * 4);
+                                       else
+                                               M_IST(s1, REG_SP, s2 * 4);
+#endif
+                               }
+                       }
+                       else {
                                s1 = md->params[i].regoff + cd->stackframesize;
                                s2 = nmd->params[j].regoff;
-                               M_ALD(REG_ITMP1, REG_SP, s1 * 8);
-                               M_AST(REG_ITMP1, REG_SP, s2 * 8);
-                       }
 
-               } else {
+#if SIZEOF_VOID_P == 8
+                               M_LLD(REG_ITMP1, REG_SP, s1 * 8);
+                               M_LST(REG_ITMP1, REG_SP, s2 * 8);
+#else
+                               if (IS_2_WORD_TYPE(t)) {
+                                       M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8);
+                                       M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4);
+                               }
+                               else {
+                                       M_ILD(REG_ITMP1, REG_SP, s1 * 8);
+                                       M_IST(REG_ITMP1, REG_SP, s2 * 4);
+                               }
+#endif
+                       }
+               }
+               else {
                        if (!md->params[i].inmemory) {
-                               s1 = rd->argfltregs[md->params[i].regoff];
+                               s1 = md->params[i].regoff;
+                               s2 = nmd->params[j].regoff;
 
                                if (!nmd->params[j].inmemory) {
-                                       s2 = rd->argfltregs[nmd->params[j].regoff];
+#if SIZEOF_VOID_P == 8
+                                       s1 = rd->argfltregs[s1];
+                                       s2 = rd->argfltregs[s2];
                                        if (IS_2_WORD_TYPE(t))
                                                M_DMOV(s1, s2);
                                        else
                                                M_FMOV(s1, s2);
+#else
+                                       /* On MIPS32 float arguments for native functions
+                                          can never be in float argument registers, since
+                                          the first argument is _always_ an integer
+                                          argument (JNIenv) */
+
+                                       if (IS_2_WORD_TYPE(t)) {
+                                               s1 = rd->argfltregs[s1];
+                                               s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
+                                                                          rd->argintregs[GET_HIGH_REG(s2)]);
+
+                                               /* double high/low order is endian
+                                                  independent: even numbered holds low
+                                                  32-bits, odd numbered high 32-bits */
+
+                                               M_MFC1(GET_LOW_REG(s2), s1);           /* low 32-bits */
+                                               M_MFC1(GET_HIGH_REG(s2), s1 + 1);     /* high 32-bits */
+                                       }
+                                       else {
+                                               s1 = rd->argfltregs[s1];
+                                               s2 = rd->argintregs[s2];
+                                               M_MFC1(s2, s1);
+                                       }
+#endif
+                               }
+                               else {
+#if SIZEOF_VOID_P == 8
+                                       s1 = rd->argfltregs[s1];
 
-                               } else {
-                                       s2 = nmd->params[j].regoff;
                                        if (IS_2_WORD_TYPE(t))
                                                M_DST(s1, REG_SP, s2 * 8);
                                        else
                                                M_FST(s1, REG_SP, s2 * 8);
-                               }
+#else
+                                       /* s1 may have been originally in 2 int registers,
+                                          but was moved out by the native function
+                                          argument(s), just get low register */
 
-                       } else {
+                                       s1 = rd->argfltregs[GET_LOW_REG(s1)];
+
+                                       if (IS_2_WORD_TYPE(t))
+                                               M_DST(s1, REG_SP, s2 * 4);
+                                       else
+                                               M_FST(s1, REG_SP, s2 * 4);
+#endif
+                               }
+                       }
+                       else {
                                s1 = md->params[i].regoff + cd->stackframesize;
                                s2 = nmd->params[j].regoff;
+
                                if (IS_2_WORD_TYPE(t)) {
                                        M_DLD(REG_FTMP1, REG_SP, s1 * 8);
                                        M_DST(REG_FTMP1, REG_SP, s2 * 8);
-                               } else {
+                               }
+                               else {
                                        M_FLD(REG_FTMP1, REG_SP, s1 * 8);
                                        M_FST(REG_FTMP1, REG_SP, s2 * 8);
                                }
@@ -3246,10 +4192,20 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        /* save return value */
 
        if (md->returntype.type != TYPE_VOID) {
+#if SIZEOF_VOID_P == 8
                if (IS_INT_LNG_TYPE(md->returntype.type))
                        M_LST(REG_RESULT, REG_SP, 0 * 8);
                else
                        M_DST(REG_FRESULT, REG_SP, 0 * 8);
+#else
+               if (IS_INT_LNG_TYPE(md->returntype.type)) {
+                       M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
+                       if (IS_2_WORD_TYPE(md->returntype.type))
+                               M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
+               }
+               else
+                       M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
+#endif
        }
 
 #if !defined(NDEBUG)
@@ -3269,10 +4225,20 @@ u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
        /* restore return value */
 
        if (md->returntype.type != TYPE_VOID) {
+#if SIZEOF_VOID_P == 8
                if (IS_INT_LNG_TYPE(md->returntype.type))
                        M_LLD(REG_RESULT, REG_SP, 0 * 8);
                else
                        M_DLD(REG_FRESULT, REG_SP, 0 * 8);
+#else
+               if (IS_INT_LNG_TYPE(md->returntype.type)) {
+                       M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
+                       if (IS_2_WORD_TYPE(md->returntype.type))
+                               M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
+               }
+               else
+                       M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
+#endif
        }
 
        M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA           */
index 9ed113c6b8640c31207c61baf1e8d04835467682..d02ee11000cb93d7924cbaec96f7d858a975f25c 100644 (file)
@@ -27,7 +27,7 @@
    Authors: Andreas Krall
             Christian Thalinger
 
-   $Id: codegen.h 6078 2006-11-28 22:19:16Z twisti $
+   $Id: codegen.h 7206 2007-01-11 22:39:52Z twisti $
 
 */
 
             M_MOV(a, b); \
     } while (0)
 
+#if SIZEOF_VOID_P == 8
+
+#define M_LNGMOVE(a,b)    M_INTMOVE(a,b)
+
+#else /* SIZEOF_VOID_P == 8 */
+
+#define M_LNGMOVE(a,b) \
+    do { \
+        if (GET_LOW_REG(b) == GET_HIGH_REG(a)) { \
+            assert(GET_HIGH_REG(b) == GET_LOW_REG(a)); \
+            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+        } else { \
+            M_INTMOVE(GET_LOW_REG(a), GET_LOW_REG(b)); \
+            M_INTMOVE(GET_HIGH_REG(a), GET_HIGH_REG(b)); \
+        } \
+    } while (0)
+
+#endif /* SIZEOF_VOID_P == 8 */
+
 #define M_FLTMOVE(a,b) \
     do { \
         if ((a) != (b)) \
         if (hi == 0) { \
             M_AADD_IMM(b,lo,a); \
         } else { \
-            M_LUI(REG_ITMP3,hi); \
-            M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3); \
-            M_AADD(REG_ITMP3,b,a); \
+            M_LUI(REG_ITMP3, hi); \
+            M_AADD_IMM(REG_ITMP3, lo, REG_ITMP3); \
+            M_AADD(b, REG_ITMP3, a); \
         } \
     } while (0)
 
 #define M_SLDU(a,b,disp)        M_ITYPE(0x25,b,a,disp)          /* 16 load    */
 
 #define M_ILD_INTERN(a,b,disp)  M_ITYPE(0x23,b,a,disp)          /* 32 load    */
-#define M_LLD_INTERN(a,b,disp)  M_ITYPE(0x37,b,a,disp)          /* 64 load    */
 
 #define M_ILD(a,b,disp) \
     do { \
         } \
     } while (0)
 
+#if SIZEOF_VOID_P == 8
+
+#define M_LLD_INTERN(a,b,disp)  M_ITYPE(0x37,b,a,disp)          /* 64 load    */
+
+#else /* SIZEOF_VOID_P == 8 */
+
+# if WORDS_BIGENDIAN == 1
+
+/* ATTENTION: b may be equal to GET_LOW_REG(a) (displacement overflow case ) */
+
+#define M_LLD_INTERN(a,b,disp) \
+    do { \
+        M_ILD_INTERN(GET_HIGH_REG(a), b, disp); \
+        M_ILD_INTERN(GET_LOW_REG(a), b, disp + 4); \
+    } while (0)
+
+/* this macro is specially for ICMD_GETFIELD since the base (source)
+   register may be one of the destination registers */
+
+#define M_LLD_GETFIELD(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            if (GET_HIGH_REG(a) == (b)) { \
+                M_ILD_INTERN(GET_LOW_REG(a), b, disp + 4); \
+                M_ILD_INTERN(GET_HIGH_REG(a), b, disp); \
+            } else { \
+                M_ILD_INTERN(GET_HIGH_REG(a), b, disp); \
+                M_ILD_INTERN(GET_LOW_REG(a), b, disp + 4); \
+            } \
+        } else { \
+            M_LUI(GET_LOW_REG(a), hi); \
+            M_AADD(b, GET_LOW_REG(a), GET_LOW_REG(a)); \
+            M_LLD_INTERN(a, GET_LOW_REG(a), lo); \
+        } \
+    } while (0)
+
+# else /* if WORDS_BIGENDIAN == 1 */
+
+/* ATTENTION: b may be equal to GET_LOW_REG(a) (displacement overflow case ) */
+
+#define M_LLD_INTERN(a,b,disp) \
+    do { \
+        M_ILD_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+        M_ILD_INTERN(GET_LOW_REG(a), b, disp); \
+    } while (0)
+
+/* this macro is specially for ICMD_GETFIELD since the base (source)
+   register may be one of the destination registers */
+
+#define M_LLD_GETFIELD(a,b,disp) \
+    do { \
+        s4 lo = (short) (disp); \
+        s4 hi = (short) (((disp) - lo) >> 16); \
+        if (hi == 0) { \
+            if (GET_HIGH_REG(a) == (b)) { \
+                M_ILD_INTERN(GET_LOW_REG(a), b, disp); \
+                M_ILD_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+            } else { \
+                M_ILD_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+                M_ILD_INTERN(GET_LOW_REG(a), b, disp); \
+            } \
+        } else { \
+            M_LUI(GET_LOW_REG(a), hi); \
+            M_AADD(b, GET_LOW_REG(a), GET_LOW_REG(a)); \
+            M_LLD_INTERN(a, GET_LOW_REG(a), lo); \
+        } \
+    } while (0)
+
+# endif /* if WORDS_BIGENDIAN == 1 */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
 #define M_LLD(a,b,disp) \
     do { \
         s4 lo = (short) (disp); \
         s4 hi = (short) (((disp) - lo) >> 16); \
         if (hi == 0) { \
-            M_LLD_INTERN(a,b,lo); \
+            M_LLD_INTERN(a, b, lo); \
         } else { \
-            M_LUI(a,hi); \
-            M_AADD(b,a,a); \
-            M_LLD_INTERN(a,a,lo); \
+            M_LUI(GET_LOW_REG(a), hi); \
+            M_AADD(b, GET_LOW_REG(a), GET_LOW_REG(a)); \
+            M_LLD_INTERN(a, GET_LOW_REG(a), lo); \
         } \
     } while (0)
 
 #define M_SST(a,b,disp)         M_ITYPE(0x29,b,a,disp)          /* 16 store   */
 
 #define M_IST_INTERN(a,b,disp)  M_ITYPE(0x2b,b,a,disp)          /* 32 store   */
-#define M_LST_INTERN(a,b,disp)  M_ITYPE(0x3f,b,a,disp)          /* 64 store   */
 
 #define M_IST(a,b,disp) \
     do { \
         } else { \
             M_LUI(REG_ITMP3, hi); \
             M_AADD(b, REG_ITMP3, REG_ITMP3); \
-            M_IST_INTERN(a,REG_ITMP3,lo); \
+            M_IST_INTERN(a, REG_ITMP3, lo); \
         } \
     } while (0)
 
+#if SIZEOF_VOID_P == 8
+
+#define M_LST_INTERN(a,b,disp)  M_ITYPE(0x3f,b,a,disp)          /* 64 store   */
+
+#else /* SIZEOF_VOID_P == 8 */
+
+#if WORDS_BIGENDIAN == 1
+
+#define M_LST_INTERN(a,b,disp) \
+    do { \
+        M_IST_INTERN(GET_HIGH_REG(a), b, disp); \
+        M_IST_INTERN(GET_LOW_REG(a), b, disp + 4); \
+    } while (0)
+
+#else /* if WORDS_BIGENDIAN == 1 */
+
+#define M_LST_INTERN(a,b,disp) \
+    do { \
+        M_IST_INTERN(GET_HIGH_REG(a), b, disp + 4); \
+        M_IST_INTERN(GET_LOW_REG(a), b, disp); \
+    } while (0)
+
+#endif /* if WORDS_BIGENDIAN == 1 */
+
+#endif /* SIZEOF_VOID_P == 8 */
+
 #define M_LST(a,b,disp) \
     do { \
         s4 lo = (short) (disp); \
         } else { \
             M_LUI(REG_ITMP3, hi); \
             M_AADD(b, REG_ITMP3, REG_ITMP3); \
-            M_LST_INTERN(a,REG_ITMP3,lo); \
+            M_LST_INTERN(a, REG_ITMP3, lo); \
         } \
     } while (0)
 
         if (hi == 0) { \
             M_FLD_INTERN(a,b,lo); \
         } else { \
-            M_LUI(REG_ITMP3,hi); \
-            M_AADD(b,REG_ITMP3,REG_ITMP3); \
-            M_FLD_INTERN(a,REG_ITMP3,lo); \
+            M_LUI(REG_ITMP3, hi); \
+            M_AADD(b, REG_ITMP3, REG_ITMP3); \
+            M_FLD_INTERN(a, REG_ITMP3, lo); \
         } \
     } while (0)
 
         if (hi == 0) { \
             M_DLD_INTERN(a,b,lo); \
         } else { \
-            M_LUI(REG_ITMP3,hi); \
-            M_AADD(b,REG_ITMP3,REG_ITMP3); \
-            M_DLD_INTERN(a,REG_ITMP3,lo); \
+            M_LUI(REG_ITMP3, hi); \
+            M_AADD(b, REG_ITMP3, REG_ITMP3); \
+            M_DLD_INTERN(a, REG_ITMP3, lo); \
         } \
     } while (0)
 
         } else { \
             M_LUI(REG_ITMP3, hi); \
             M_AADD(b, REG_ITMP3, REG_ITMP3); \
-            M_FST_INTERN(a,REG_ITMP3,lo); \
+            M_FST_INTERN(a, REG_ITMP3, lo); \
         } \
     } while (0)
 
         } else { \
             M_LUI(REG_ITMP3, hi); \
             M_AADD(b, REG_ITMP3, REG_ITMP3); \
-            M_DST_INTERN(a,REG_ITMP3,lo); \
+            M_DST_INTERN(a, REG_ITMP3, lo); \
         } \
     } while (0)
 
 #define M_ISUB(a,b,c)           M_RTYPE(0,a,b,c,0,0x23)         /* 32 sub     */
 #define M_LSUB(a,b,c)           M_RTYPE(0,a,b,c,0,0x2f)         /* 64 sub     */
 #define M_IMUL(a,b)             M_ITYPE(0,a,b,0x18)             /* 32 mul     */
+#define M_IMULU(a,b)            M_ITYPE(0,a,b,0x19)             /* 32 mul     */
 #define M_LMUL(a,b)             M_ITYPE(0,a,b,0x1c)             /* 64 mul     */
 #define M_IDIV(a,b)             M_ITYPE(0,a,b,0x1a)             /* 32 div     */
 #define M_LDIV(a,b)             M_ITYPE(0,a,b,0x1e)             /* 64 div     */
 
 #define M_IADD_IMM(a,b,c)       M_ITYPE(0x09,a,c,b)             /* 32 add     */
 #define M_LADD_IMM(a,b,c)       M_ITYPE(0x19,a,c,b)             /* 64 add     */
-#define M_ISUB_IMM(a,b,c)       M_ITYPE(0x09,a,c,-(b))          /* 32 sub     */
-#define M_LSUB_IMM(a,b,c)       M_ITYPE(0x19,a,c,-(b))          /* 64 sub     */
+#define M_ISUB_IMM(a,b,c)       M_IADD_IMM(a,-(b),c)            /* 32 sub     */
+#define M_LSUB_IMM(a,b,c)       M_LADD_IMM(a,-(b),c)            /* 64 sub     */
 
 #define M_LUI(a,imm)            M_ITYPE(0x0f,0,a,imm)           /* a = imm<<16*/
 
 #define M_OR_IMM( a,b,c)        M_ITYPE(0x0d,a,c,b)             /* c = a |  b */
 #define M_XOR_IMM(a,b,c)        M_ITYPE(0x0e,a,c,b)             /* c = a ^  b */
 
-#define M_CZEXT(a,c)            M_AND_IMM(a,0xffff,c)           /* c = zext(a)*/
-
 #define M_ISLL(a,b,c)           M_RTYPE(0,b,a,c,0,0x04)         /* c = a << b */
 #define M_ISRL(a,b,c)           M_RTYPE(0,b,a,c,0,0x06)         /* c = a >>>b */
 #define M_ISRA(a,b,c)           M_RTYPE(0,b,a,c,0,0x07)         /* c = a >> b */
 #define M_MOVID(i,d)            M_FP3(0,4,d,i,0)                /* d = i      */
 #define M_MOVLD(l,d)            M_FP3(0,5,d,l,0)                /* d = l      */
 
+#define M_MFC1(l,f)             M_FP3(0,0,f,l,0)
+#define M_MTC1(l,f)             M_FP3(0,4,f,l,0)
+
 #define M_DMFC1(l,f)            M_FP3(0,1,f,l,0)
 #define M_DMTC1(l,f)            M_FP3(0,5,f,l,0)
 
index d9ef34e85a17e10f239985a472ef76117df9b5b2..6a19ea0bf5b57fb146988d8d15c880a74399e051 100644 (file)
 
    Changes:
 
-   $Id: emitfuncs.c 4398 2006-01-31 23:43:08Z twisti $
+   $Id: emit.c 4398 2006-01-31 23:43:08Z twisti $
 
 */
 
 
 #include "config.h"
-#include "vm/types.h"
 
 #include <assert.h>
 
-#include "md-abi.h"
+#include "vm/types.h"
 
 #include "vm/jit/mips/codegen.h"
+#include "vm/jit/mips/md-abi.h"
 
 #if defined(ENABLE_THREADS)
 # include "threads/native/lock.h"
@@ -84,8 +84,16 @@ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
                        else
                                M_FLD(tempreg, REG_SP, disp);
                }
-               else
+               else {
+#if SIZEOF_VOID_P == 8
                        M_LLD(tempreg, REG_SP, disp);
+#else
+                       if (IS_2_WORD_TYPE(src->type))
+                               M_LLD(tempreg, REG_SP, disp);
+                       else
+                               M_ILD(tempreg, REG_SP, disp);
+#endif
+               }
 
                reg = tempreg;
        }
@@ -96,6 +104,86 @@ s4 emit_load(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
 }
 
 
+/* emit_load_low ***************************************************************
+
+   Emits a possible load of the low 32-bits of an operand.
+
+*******************************************************************************/
+
+#if SIZEOF_VOID_P == 4
+s4 emit_load_low(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+{
+       codegendata  *cd;
+       s4            disp;
+       s4            reg;
+
+       assert(src->type == TYPE_LNG);
+
+       /* get required compiler data */
+
+       cd = jd->cd;
+
+       if (src->flags & INMEMORY) {
+               COUNT_SPILLS;
+
+               disp = src->vv.regoff * 8;
+
+#if WORDS_BIGENDIAN == 1
+               M_ILD(tempreg, REG_SP, disp + 4);
+#else
+               M_ILD(tempreg, REG_SP, disp);
+#endif
+
+               reg = tempreg;
+       }
+       else
+               reg = GET_LOW_REG(src->vv.regoff);
+
+       return reg;
+}
+#endif /* SIZEOF_VOID_P == 4 */
+
+
+/* emit_load_high **************************************************************
+
+   Emits a possible load of the high 32-bits of an operand.
+
+*******************************************************************************/
+
+#if SIZEOF_VOID_P == 4
+s4 emit_load_high(jitdata *jd, instruction *iptr, varinfo *src, s4 tempreg)
+{
+       codegendata  *cd;
+       s4            disp;
+       s4            reg;
+
+       assert(src->type == TYPE_LNG);
+
+       /* get required compiler data */
+
+       cd = jd->cd;
+
+       if (src->flags & INMEMORY) {
+               COUNT_SPILLS;
+
+               disp = src->vv.regoff * 8;
+
+#if WORDS_BIGENDIAN == 1
+               M_ILD(tempreg, REG_SP, disp);
+#else
+               M_ILD(tempreg, REG_SP, disp + 4);
+#endif
+
+               reg = tempreg;
+       }
+       else
+               reg = GET_HIGH_REG(src->vv.regoff);
+
+       return reg;
+}
+#endif /* SIZEOF_VOID_P == 4 */
+
+
 /* emit_store ******************************************************************
 
    Emits a possible store to variable.
@@ -122,8 +210,16 @@ void emit_store(jitdata *jd, instruction *iptr, varinfo *dst, s4 d)
                        else
                                M_FST(d, REG_SP, disp);
                }
-               else
+               else {
+#if SIZEOF_VOID_P == 8
                        M_LST(d, REG_SP, disp);
+#else
+                       if (IS_2_WORD_TYPE(dst->type))
+                               M_LST(d, REG_SP, disp);
+                       else
+                               M_IST(d, REG_SP, disp);
+#endif
+               }
        }
 }
 
@@ -145,18 +241,27 @@ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
 
        if ((src->vv.regoff != dst->vv.regoff) ||
                ((src->flags ^ dst->flags) & INMEMORY)) {
-
                /* If one of the variables resides in memory, we can eliminate
                   the register move from/to the temporary register with the
                   order of getting the destination register and the load. */
 
                if (IS_INMEMORY(src->flags)) {
-                       d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
+#if SIZEOF_VOID_P == 4
+                       if (IS_2_WORD_TYPE(src->type))
+                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
+                       else
+#endif
+                               d = codegen_reg_of_var(iptr->opc, dst, REG_IFTMP);
                        s1 = emit_load(jd, iptr, src, d);
                }
                else {
                        s1 = emit_load(jd, iptr, src, REG_IFTMP);
-                       d = codegen_reg_of_var(iptr->opc, dst, s1);
+#if SIZEOF_VOID_P == 4
+                       if (IS_2_WORD_TYPE(src->type))
+                               d = codegen_reg_of_var(iptr->opc, dst, REG_ITMP12_PACKED);
+                       else
+#endif
+                               d = codegen_reg_of_var(iptr->opc, dst, s1);
                }
 
                if (s1 != d) {
@@ -166,8 +271,16 @@ void emit_copy(jitdata *jd, instruction *iptr, varinfo *src, varinfo *dst)
                                else
                                        M_FMOV(s1, d);
                        }
-                       else
+                       else {
+#if SIZEOF_VOID_P == 8
                                M_MOV(s1, d);
+#else
+                               if (IS_2_WORD_TYPE(src->type))
+                                       M_LNGMOVE(s1, d);
+                               else
+                                       M_MOV(s1, d);
+#endif
+                       }
                }
 
                emit_store(jd, iptr, dst, d);
@@ -206,6 +319,7 @@ void emit_lconst(codegendata *cd, s4 d, s8 value)
 {
        s4 disp;
 
+#if SIZEOF_VOID_P == 8
        if ((value >= -32768) && (value <= 32767))
                M_LADD_IMM(REG_ZERO, value, d);
        else if ((value >= 0) && (value <= 0xffff))
@@ -214,6 +328,10 @@ void emit_lconst(codegendata *cd, s4 d, s8 value)
                disp = dseg_add_s8(cd, value);
                M_LLD(d, REG_PV, disp);
        }
+#else
+       disp = dseg_add_s8(cd, value);
+       M_LLD(d, REG_PV, disp);
+#endif
 }
 
 
@@ -467,6 +585,9 @@ void emit_exception_stubs(jitdata *jd)
                                M_ALD(REG_A2, REG_SP, (cd->stackframesize - 1) * 8);
 
                        M_MOV(REG_ITMP2_XPC, REG_A3);
+
+#if SIZEOF_VOID_P == 8
+                       /* XXX */
                        M_MOV(REG_ITMP1, REG_A4);
 
                        M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
@@ -474,16 +595,33 @@ void emit_exception_stubs(jitdata *jd)
 
                        if (jd->isleafmethod)
                                M_AST(REG_RA, REG_SP, 1 * 8);
+#else
+                       M_ASUB_IMM(REG_SP, 5*4 + 2 * 8, REG_SP);
+                       M_AST(REG_ITMP2_XPC, REG_SP, 5*4 + 0 * 8);
+
+                       if (jd->isleafmethod)
+                               M_AST(REG_RA, REG_SP, 5*4 + 1 * 8);
+
+                       M_AST(REG_ITMP1, REG_SP, 4 * 4);
+#endif
 
                        M_JSR(REG_RA, REG_ITMP3);
                        M_NOP;
                        M_MOV(REG_RESULT, REG_ITMP1_XPTR);
 
+#if SIZEOF_VOID_P == 8
                        if (jd->isleafmethod)
                                M_ALD(REG_RA, REG_SP, 1 * 8);
 
                        M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
                        M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
+#else
+                       if (jd->isleafmethod)
+                               M_ALD(REG_RA, REG_SP, 5*4 + 1 * 8);
+
+                       M_ALD(REG_ITMP2_XPC, REG_SP, 5*4 + 0 * 8);
+                       M_AADD_IMM(REG_SP, 5*4 + 2 * 8, REG_SP);
+#endif
 
                        disp = dseg_add_functionptr(cd, asm_handle_exception);
                        M_ALD(REG_ITMP3, REG_PV, disp);
@@ -740,7 +878,7 @@ void emit_verbosecall_enter(jitdata *jd)
        registerdata *rd;
        methoddesc   *md;
        s4            disp;
-       s4            i, t;
+       s4            i, j, t;
 
        /* get required compiler data */
 
@@ -754,30 +892,33 @@ void emit_verbosecall_enter(jitdata *jd)
 
        M_NOP;
 
-       M_LDA(REG_SP, REG_SP, -(2 + ARG_CNT + TMP_CNT) * 8);
-       M_AST(REG_RA, REG_SP, 1 * 8);
+       M_LDA(REG_SP, REG_SP, -(PA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8));
+       M_AST(REG_RA, REG_SP, PA_SIZE + 1 * 8);
 
-       /* save argument registers */
+       /* save argument registers (we store the registers as address
+          types, so it's correct for MIPS32 too) */
 
        for (i = 0; i < INT_ARG_CNT; i++)
-               M_LST(rd->argintregs[i], REG_SP, (2 + i) * 8);
+               M_AST(rd->argintregs[i], REG_SP, PA_SIZE + (2 + i) * 8);
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DST(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
+               M_DST(rd->argfltregs[i], REG_SP, PA_SIZE + (2 + INT_ARG_CNT + i) * 8);
 
        /* save temporary registers for leaf methods */
 
        if (jd->isleafmethod) {
                for (i = 0; i < INT_TMP_CNT; i++)
-                       M_LST(rd->tmpintregs[i], REG_SP, (2 + ARG_CNT + i) * 8);
+                       M_AST(rd->tmpintregs[i], REG_SP, PA_SIZE + (2 + ARG_CNT + i) * 8);
 
                for (i = 0; i < FLT_TMP_CNT; i++)
-                       M_DST(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
+                       M_DST(rd->tmpfltregs[i], REG_SP, PA_SIZE + (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
        }
 
-       /* load float arguments into integer registers */
+       /* Load float arguments into integer registers.  MIPS32 has less
+          float argument registers than integer ones, we need to check
+          that. */
 
-       for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
+       for (i = 0; i < md->paramcount && i < INT_ARG_CNT && i < FLT_ARG_CNT; i++) {
                t = md->paramtypes[i].type;
 
                if (IS_FLT_DBL_TYPE(t)) {
@@ -792,9 +933,32 @@ void emit_verbosecall_enter(jitdata *jd)
                }
        }
 
+#if SIZEOF_VOID_P == 4
+               for (i = 0, j = 0; i < md->paramcount && i < TRACE_ARGS_NUM; i++) {
+                       t = md->paramtypes[i].type;
+
+                       if (IS_INT_LNG_TYPE(t)) {
+                               if (IS_2_WORD_TYPE(t)) {
+                                       M_ILD(rd->argintregs[j], REG_SP, PA_SIZE + (2 + i) * 8);
+                                       M_ILD(rd->argintregs[j + 1], REG_SP, PA_SIZE + (2 + i) * 8 + 4);
+                               }
+                               else {
+# if WORDS_BIGENDIAN == 1
+                                       M_MOV(REG_ZERO, rd->argintregs[j]);
+                                       M_ILD(rd->argintregs[j + 1], REG_SP, PA_SIZE + (2 + i) * 8);
+# else
+                                       M_ILD(rd->argintregs[j], REG_SP, PA_SIZE + (2 + i) * 8);
+                                       M_MOV(REG_ZERO, rd->argintregs[j + 1]);
+# endif
+                               }
+                               j += 2;
+                       }
+               }
+#endif
+
        disp = dseg_add_address(cd, m);
        M_ALD(REG_ITMP1, REG_PV, disp);
-       M_AST(REG_ITMP1, REG_SP, 0 * 8);
+       M_AST(REG_ITMP1, REG_SP, PA_SIZE + 0 * 8);
        disp = dseg_add_functionptr(cd, builtin_trace_args);
        M_ALD(REG_ITMP3, REG_PV, disp);
        M_JSR(REG_RA, REG_ITMP3);
@@ -803,23 +967,23 @@ void emit_verbosecall_enter(jitdata *jd)
        /* restore argument registers */
 
        for (i = 0; i < INT_ARG_CNT; i++)
-               M_LLD(rd->argintregs[i], REG_SP, (2 + i) * 8);
+               M_ALD(rd->argintregs[i], REG_SP, PA_SIZE + (2 + i) * 8);
 
        for (i = 0; i < FLT_ARG_CNT; i++)
-               M_DLD(rd->argfltregs[i], REG_SP, (2 + INT_ARG_CNT + i) * 8);
+               M_DLD(rd->argfltregs[i], REG_SP, PA_SIZE + (2 + INT_ARG_CNT + i) * 8);
 
        /* restore temporary registers for leaf methods */
 
        if (jd->isleafmethod) {
                for (i = 0; i < INT_TMP_CNT; i++)
-                       M_LLD(rd->tmpintregs[i], REG_SP, (2 + ARG_CNT + i) * 8);
+                       M_ALD(rd->tmpintregs[i], REG_SP, PA_SIZE + (2 + ARG_CNT + i) * 8);
 
                for (i = 0; i < FLT_TMP_CNT; i++)
-                       M_DLD(rd->tmpfltregs[i], REG_SP, (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
+                       M_DLD(rd->tmpfltregs[i], REG_SP, PA_SIZE + (2 + ARG_CNT + INT_TMP_CNT + i) * 8);
        }
 
-       M_ALD(REG_RA, REG_SP, 1 * 8);
-       M_LDA(REG_SP, REG_SP, (2 + ARG_CNT + TMP_CNT) * 8);
+       M_ALD(REG_RA, REG_SP, PA_SIZE + 1 * 8);
+       M_LDA(REG_SP, REG_SP, PA_SIZE + (2 + ARG_CNT + TMP_CNT) * 8);
 
        /* mark trace code */
 
@@ -840,6 +1004,7 @@ void emit_verbosecall_exit(jitdata *jd)
        methodinfo   *m;
        codegendata  *cd;
        registerdata *rd;
+       methoddesc   *md;
        s4            disp;
 
        /* get required compiler data */
@@ -848,33 +1013,76 @@ void emit_verbosecall_exit(jitdata *jd)
        cd = jd->cd;
        rd = jd->rd;
 
+       md = m->parseddesc;
+
        /* mark trace code */
 
        M_NOP;
 
+#if SIZEOF_VOID_P == 8
        M_LDA(REG_SP, REG_SP, -4 * 8);              /* keep stack 16-byte aligned */
-       M_LST(REG_RA, REG_SP, 0 * 8);
+       M_AST(REG_RA, REG_SP, 0 * 8);
 
        M_LST(REG_RESULT, REG_SP, 1 * 8);
        M_DST(REG_FRESULT, REG_SP, 2 * 8);
+#else
+       M_LDA(REG_SP, REG_SP, -(8*4 + 4 * 8));
+       M_AST(REG_RA, REG_SP, 8*4 + 0 * 8);
+
+       M_LST(REG_RESULT_PACKED, REG_SP, 8*4 + 1 * 8);
+       M_DST(REG_FRESULT, REG_SP, 8*4 + 2 * 8);
+#endif
 
        disp = dseg_add_address(cd, m);
        M_ALD(rd->argintregs[0], REG_PV, disp);
 
+#if SIZEOF_VOID_P == 8
        M_MOV(REG_RESULT, rd->argintregs[1]);
        M_DMOV(REG_FRESULT, rd->argfltregs[2]);
        M_FMOV(REG_FRESULT, rd->argfltregs[3]);
+#else
+       switch (md->returntype.type) {
+       case TYPE_LNG:
+# if WORDS_BIGENDIAN == 1
+               M_MOV(REG_RESULT, rd->argintregs[2]);
+               M_MOV(REG_RESULT2, rd->argintregs[3]);
+# else
+               M_MOV(REG_RESULT2, rd->argintregs[2]);
+               M_MOV(REG_RESULT, rd->argintregs[3]);
+# endif
+               break;
+       default:
+# if WORDS_BIGENDIAN == 1
+               M_MOV(REG_ZERO, rd->argintregs[2]);
+               M_MOV(REG_RESULT, rd->argintregs[3]);
+# else
+               M_MOV(REG_RESULT, rd->argintregs[2]);
+               M_MOV(REG_ZERO, rd->argintregs[3]);
+# endif
+       }
+
+       M_DST(REG_FRESULT, REG_SP, 4*4);
+       M_FST(REG_FRESULT, REG_SP, 4*4 + 2 * 4);
+#endif
 
        disp = dseg_add_functionptr(cd, builtin_displaymethodstop);
        M_ALD(REG_ITMP3, REG_PV, disp);
        M_JSR(REG_RA, REG_ITMP3);
        M_NOP;
 
+#if SIZEOF_VOID_P == 8
        M_DLD(REG_FRESULT, REG_SP, 2 * 8);
        M_LLD(REG_RESULT, REG_SP, 1 * 8);
 
-       M_LLD(REG_RA, REG_SP, 0 * 8);
+       M_ALD(REG_RA, REG_SP, 0 * 8);
        M_LDA(REG_SP, REG_SP, 4 * 8);
+#else
+       M_DLD(REG_FRESULT, REG_SP, 8*4 + 2 * 8);
+       M_LLD(REG_RESULT_PACKED, REG_SP, 8*4 + 1 * 8);
+
+       M_ALD(REG_RA, REG_SP, 8*4 + 0 * 8);
+       M_LDA(REG_SP, REG_SP, 8*4 + 4 * 8);
+#endif
 
        /* mark trace code */
 
index b22e11b8321497520e18957cc55d026f0e06aad3..86d5c731c107d7b805a5edef81afa7db124506de 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/mips/linux/md-os.c - machine dependent MIPS Linux functions
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
 
    Authors: Andreas Krall
             Reinhard Grafl
+            Christian Thalinger
 
-   Changes: Christian Thalinger
-
-   $Id: md-os.c 5900 2006-11-04 17:30:44Z michi $
+   $Id: md-os.c 7206 2007-01-11 22:39:52Z twisti $
 
 */
 
@@ -37,6 +36,7 @@
 #include "config.h"
 
 #include <assert.h>
+#include <sgidefs.h> /* required for _MIPS_SIM_ABI* defines (before signal.h) */
 #include <signal.h>
 #include <ucontext.h>
 
@@ -147,6 +147,17 @@ void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 }
 
 
+/* md_signal_handler_sigusr2 ***************************************************
+
+   DOCUMENT ME
+
+*******************************************************************************/
+
+void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
+{
+}
+
+
 #if defined(ENABLE_THREADS)
 void thread_restartcriticalsection(ucontext_t *_uc)
 {
@@ -186,4 +197,5 @@ void thread_restartcriticalsection(ucontext_t *_uc)
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */
index 08aa28aa7e6834e748c53fcf7a72e2d50b6db97c..680236cdbf1732aaf0a61b1641228703dcd1a43d 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Ullrich
 
-   $Id: md-abi.c 5634 2006-10-02 14:18:04Z edwin $
+   $Id: md-abi.c 7206 2007-01-11 22:39:52Z twisti $
 
 */
 
@@ -134,17 +134,26 @@ void md_param_alloc(methoddesc *md)
        s4         i;
        s4         reguse;
        s4         stacksize;
+#if SIZEOF_VOID_P == 4 && !defined(ENABLE_SOFT_FLOAT)
+       s4         t;
+       bool       a0_is_float;
+#endif
 
        /* set default values */
 
        reguse = 0;
        stacksize = 0;
+#if SIZEOF_VOID_P == 4 && !defined(ENABLE_SOFT_FLOAT)
+       a0_is_float = false;
+#endif
 
        /* get params field of methoddesc */
 
        pd = md->params;
 
        for (i = 0; i < md->paramcount; i++, pd++) {
+#if SIZEOF_VOID_P == 8
+
                switch (md->paramtypes[i].type) {
                case TYPE_INT:
                case TYPE_ADR:
@@ -174,6 +183,120 @@ void md_param_alloc(methoddesc *md)
                        }
                        break;
                }
+
+               /* register type is the same as java type */
+
+               pd->type = md->paramtypes[i].type;
+
+#else /* SIZEOF_VOID_P == 8 */
+
+#if !defined(ENABLE_SOFT_FLOAT)
+
+#define ALIGN_2_WORD(s)    ((s) & 1) ? ++(s) : (s)
+
+               t = md->paramtypes[i].type;
+
+               if (IS_FLT_DBL_TYPE(t) &&
+                       ((i == 0) ||
+                        ((i == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type)))) {
+                       if (IS_2_WORD_TYPE(t)) {
+                               pd->type = TYPE_DBL;
+                               pd->regoff = reguse;
+                               reguse++;
+                               stacksize += 2;
+                       }
+                       else {
+                               pd->type = TYPE_FLT;
+                               pd->regoff = reguse;
+                               reguse++;
+                               stacksize++;
+                       }
+                       md->argfltreguse = reguse;
+                       a0_is_float = true;
+               }
+               else {
+                       if (IS_2_WORD_TYPE(t)) {
+                               ALIGN_2_WORD(reguse);
+                               pd->type = TYPE_LNG;
+
+                               if (reguse < INT_ARG_CNT) {
+                                       pd->inmemory = false;
+# if WORDS_BIGENDIAN == 1
+                                       pd->regoff = PACK_REGS(reguse + 1, reguse);
+# else
+                                       pd->regoff = PACK_REGS(reguse, reguse + 1);
+# endif
+                                       reguse += 2;
+                                       md->argintreguse = reguse;
+                               }
+                               else {
+                                       pd->inmemory = true;
+                                       pd->regoff = ALIGN_2_WORD(stacksize);
+                               }
+                               stacksize += 2;
+                       }
+                       else {
+                               pd->type = TYPE_INT;
+
+                               if (reguse < INT_ARG_CNT) {
+                                       pd->inmemory = false;
+                                       pd->regoff = reguse;
+                                       reguse++;
+                                       md->argintreguse = reguse;
+                               }
+                               else {
+                                       pd->inmemory = true;
+                                       pd->regoff = stacksize;
+                               }
+                               stacksize++;
+                       }
+               }
+
+#else /* !defined(ENABLE_SOFT_FLOAT) */
+#error never actually tested!
+
+               switch (md->paramtypes[i].type) {
+               case TYPE_INT:
+               case TYPE_ADR:
+               case TYPE_FLT:
+                       pd->type = TYPE_INT;
+
+                       if (i < INT_ARG_CNT) {
+                               pd->inmemory = false;
+                               pd->regoff = reguse;
+                               reguse++;
+                               md->argintreguse = reguse;
+                       } else {
+                               pd->inmemory = true;
+                               pd->regoff = stacksize;
+                       }
+                       stacksize++;
+                       break;
+               case TYPE_LNG:
+               case TYPE_DBL:
+                       pd->type = TYPE_LNG;
+
+                       if (i < INT_ARG_CNT) {
+                               pd->inmemory = false;
+#if WORDS_BIGENDIAN == 1
+                               pd->regoff = PACK_REGS(reguse + 1, reguse);
+#else
+                               pd->regoff = PACK_REGS(reguse, reguse + 1);
+#endif
+                               reguse += 2;
+                               md->argintreguse = reguse;
+                       } else {
+                               pd->inmemory = true;
+                               pd->regoff = stacksize;
+                       }
+                       stacksize += 2;
+                       break;
+               }
+
+
+#endif /* !defined(ENABLE_SOFT_FLOAT) */
+
+#endif /* SIZEOF_VOID_P == 8 */
        }
 
        /* fill register and stack usage */
@@ -216,11 +339,16 @@ void md_return_alloc(jitdata *jd, stackptr stackslot)
           not to survive method invokations. */
 
        if (!(stackslot->flags & SAVEDVAR)) {
-
                VAR(stackslot->varnum)->flags = PREALLOC;
 
-               if (IS_INT_LNG_TYPE(md->returntype.type))
-                       VAR(stackslot->varnum)->vv.regoff = REG_RESULT;
+               if (IS_INT_LNG_TYPE(md->returntype.type)) {
+#if SIZEOF_VOID_P == 4
+                       if (IS_2_WORD_TYPE(md->returntype.type))
+                               VAR(stackslot->varnum)->vv.regoff = REG_RESULT_PACKED;
+                       else
+#endif
+                               VAR(stackslot->varnum)->vv.regoff = REG_RESULT;
+               }
                else
                        VAR(stackslot->varnum)->vv.regoff = REG_FRESULT;
        }
index 49630df75338cea0bca4c31c6f64a02f3351b578..0c190e2ea639bdac73c64eadca63713637d3022e 100644 (file)
@@ -28,7 +28,7 @@
 
    Changes: Christian Ullrich
 
-   $Id: md-abi.h 5829 2006-10-26 10:34:17Z twisti $
+   $Id: md-abi.h 7206 2007-01-11 22:39:52Z twisti $
 
 */
 
 #endif
 
 
+/* packed register defines ****************************************************/
+
+#if SIZEOF_VOID_P == 4
+# if WORDS_BIGENDIAN == 1
+#  define REG_ITMP12_PACKED    PACK_REGS(REG_ITMP2, REG_ITMP1)
+#  define REG_ITMP23_PACKED    PACK_REGS(REG_ITMP3, REG_ITMP2)
+#  define REG_RESULT_PACKED    PACK_REGS(REG_RESULT2, REG_RESULT)
+# else
+#  define REG_ITMP12_PACKED    PACK_REGS(REG_ITMP1, REG_ITMP2)
+#  define REG_ITMP23_PACKED    PACK_REGS(REG_ITMP2, REG_ITMP3)
+#  define REG_RESULT_PACKED    PACK_REGS(REG_RESULT, REG_RESULT2)
+# endif
+#endif
+
+
+/* ABI defines ****************************************************************/
+
+#if SIZEOF_VOID_P == 8
+# define PA_SIZE    0                   /* we don't have a parameter area     */
+#else
+# define PA_SIZE    4 * 4               /* parameter area is max. 4 * 4 bytes */
+#endif
+
+
 /* packed register defines ****************************************************/
 
 #if SIZEOF_VOID_P == 4