* Removed all Id tags.
[cacao.git] / src / vm / jit / mips / asmpart.S
index 866a9d821faa5e7eb72b71921a5900b417b857ef..ab19557308eb7f5c740a9f49834119cc40f74547 100644 (file)
@@ -1,9 +1,9 @@
-/* vm/jit/mips/asmpart.S - Java-C interface functions for mips
+/* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
 
-   Copyright (C) 1996-2005 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
+   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
 
    This file is part of CACAO.
 
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.
-
-   Contact: cacao@complang.tuwien.ac.at
-
-   Authors: Andreas Krall
-
-   $Id: asmpart.S 1861 2005-01-04 16:40:12Z twisti $
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
 */
 
 
 #include "config.h"
-#include "vm/jit/mips/offsets.h"
-#include "vm/jit/mips/asmoffsets.h"
-
-
-#define zero    $0
-#define itmp1   $1
-#define v0      $2
-#define itmp2   $3
-#define a0      $4
-#define a1      $5
-#define a2      $6
-#define a3      $7
-
-#define a4      $8
-#define        a5      $9
-#define        a6      $10
-#define        a7      $11
-#define        t0      $12
-#define        t1      $13
-#define        t2      $14
-#define        t3      $15
-
-#define s0      $16
-#define s1      $17
-#define s2      $18
-#define s3      $19
-#define s4      $20
-#define s5      $21
-#define s6      $22
-#define s7      $23
-
-#define t8      $24
-#define itmp3   $25
-#define k0      $26
-#define k1      $27
-
-#define gp      $28
-#define sp      $29
-#define s8      $30
-#define ra      $31
-
-#define pv      s8
-#define t9      itmp3
-
-#define xptr    itmp1
-#define xpc     itmp2
-#define mptr    itmp3
-#define mptrreg 25
-
-#define fv0     $f0
-#define ft0     $f1
-#define ft1     $f2
-#define ft2     $f3
-#define ft3     $f4
-#define ft4     $f5
-#define ft5     $f6
-#define ft6     $f7
-
-#define ft7     $f8
-#define        ft8     $f9
-#define        ft9     $f10
-#define        ft10    $f11
-#define        fa0     $f12
-#define        fa1     $f13
-#define        fa2     $f14
-#define        fa3     $f15
-
-#define fa4     $f16
-#define fa5     $f17
-#define fa6     $f18
-#define fa7     $f19
-#define ft11    $f20
-#define ft12    $f21
-#define ft13    $f22
-#define ft14    $f23
-
-#define fs0     $f24
-#define ft15    $f25
-#define fs1     $f26
-#define ft16    $f27
-#define fs2     $f28
-#define ft17    $f29
-#define fs3     $f30
-#define ft18    $f31
-
-#define fss0    $f20
-#define fss1    $f22
-#define fss2    $f25
-#define fss3    $f27
-#define fss4    $f29
-#define fss5    $f31
-
-#define aaddu   daddu
-#define asubu   dsubu
-#define aaddiu  daddiu
-#define ald     ld
-#define ast     sd
-#define ala     dla
-#define asll    dsll
-#define ashift  3
+
+#include "vm/jit/mips/md-abi.h"
+#include "vm/jit/mips/md-asm.h"
+
+#include "vm/jit/abi-asm.h"
+#include "vm/jit/methodheader.h"
 
 
        .text
        .set    noat
 
 
-/********************* exported functions and variables ***********************/
-
-       .globl asm_calljavafunction
+/* export functions ***********************************************************/
 
-       .globl asm_calljavafunction2
-       .globl asm_calljavafunction2int
-       .globl asm_calljavafunction2long
-       .globl asm_calljavafunction2float
-       .globl asm_calljavafunction2double
+       .globl asm_vm_call_method
+       .globl asm_vm_call_method_int
+       .globl asm_vm_call_method_long
+       .globl asm_vm_call_method_float
+       .globl asm_vm_call_method_double
+       .globl asm_vm_call_method_exception_handler
+       .globl asm_vm_call_method_end
 
        .globl asm_call_jit_compiler
-       .globl asm_dumpregistersandcall
+
        .globl asm_handle_exception
        .globl asm_handle_nat_exception
-       .globl asm_check_clinit
-       .globl asm_builtin_checkarraycast
-       .globl asm_builtin_checkcast
-       .globl asm_builtin_aastore
-
-#if defined(USE_THREADS)
-       .globl asm_builtin_monitorenter
-       .globl asm_builtin_monitorexit
-#endif
 
-       .globl asm_builtin_idiv
-       .globl asm_builtin_irem
-       .globl asm_builtin_ldiv
-       .globl asm_builtin_lrem
-       .globl asm_perform_threadswitch
-       .globl asm_initialize_thread_stack
-       .globl asm_switchstackandcall
-       .globl asm_builtin_trace
-       .globl asm_builtin_exittrace
-       .globl asm_getclassvalues_atomic
-       .globl asm_criticalsections
+       .globl asm_abstractmethoderror
+
+#if defined(ENABLE_REPLACEMENT)
+       .globl asm_replacement_out
+       .globl asm_replacement_in
+#endif
 
        .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.                                           *
 *                                                                              *
 *******************************************************************************/
 
-       .ent    asm_calljavafunction
+       .ent    asm_vm_call_method
 
-call_name:
        .align  3
 
-       .dword  0                         /* catch type all                       */
-       .dword  calljava_xhandler         /* handler pc                           */
-       .dword  calljava_xhandler         /* end pc                               */
-       .dword  asm_calljavafunction      /* start pc                             */
-       .word   1                         /* extable size                         */
-       .word   0                         /* fltsave                              */
-       .word   0                         /* intsave                              */
-       .word   0                         /* isleaf                               */
-       .word   0                         /* IsSync                               */
-       .word   10*8                      /* frame size                           */
-       .dword  0                         /* method pointer (pointer to name)     */
-
-asm_calljavafunction:
-       aaddiu  sp,sp,-10*8               /* allocate stack space                 */
-       sd      ra,0(sp)                  /* save return address                  */
-
-       .set    noreorder
-       bal     call_java_pc
-       sd      pv,3*8(sp)                /* procedure vector                     */
-call_java_pc:
-       aaddiu  pv,ra,-4*4
-
-       .set    reorder
-       
-       sdc1    fss0,4*8(sp)              /* save non JavaABI saved flt registers */
-       sdc1    fss1,5*8(sp)
-       sdc1    fss2,6*8(sp)
-       sdc1    fss3,7*8(sp)
-       sdc1    fss4,8*8(sp)
-       sdc1    fss5,9*8(sp)
-       sd      a0,2*8(sp)                /* save method pointer for compiler     */
-       aaddiu  itmp1,sp,16               /* pass pointer to methodptr via itmp1  */
-
-       move    a0,a1                     /* pass the remaining parameters        */
-       move    a1,a2
-       move    a2,a3
-       move    a3,a4
-
-       ala     mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
-       ast     mptr,1*8(sp)              /* store function address               */
-       move    mptr,sp                   /* set method pointer                   */
-
-       .set    noreorder
-       
-       ald     pv,1*8(mptr)              /* method call as in Java               */
-       jalr    pv                        /* call JIT compiler                    */
-       nop
-       aaddiu  pv,ra,-23*4               /* recompute procedure vector           */
-#if 0
-       move    v0,zero                   /* clear return value (exception ptr)   */
-#else
-       nop
-#endif
-
-calljava_return:
-       ld      ra,0(sp)                  /* restore return address               */
-       ld      pv,3*8(sp)                /* restore procedure vector             */
-
-       ldc1    fss0,4*8(sp)              /* restore non JavaABI saved flt regs   */
-       ldc1    fss1,5*8(sp)
-       ldc1    fss2,6*8(sp)
-       ldc1    fss3,7*8(sp)
-       ldc1    fss4,8*8(sp)
-       ldc1    fss5,9*8(sp)
-       j       ra                        /* return                               */
-       aaddiu  sp,sp,10*8                /* free stack space                     */
-
-       .set    reorder
-       
-calljava_xhandler:
-       move    a0,itmp1                  
-       jal     builtin_throw_exception
-       b       calljava_return
-
-       .end    asm_calljavafunction
+#if SIZEOF_VOID_P == 8
+
+       .dword  0                           /* catch type all                     */
+       .dword  0                           /* handler pc                         */
+       .dword  0                           /* end pc                             */
+       .dword  0                           /* start pc                           */
+       .word   1                           /* extable size                       */
+       .word   0                           /* 4-byte ALIGNMENT PADDING           */
+       .dword  0                           /* line number table start            */
+       .dword  0                           /* line number table size             */
+       .word   0                           /* 4-byte ALIGNMENT PADDING           */
+       .word   0                           /* fltsave                            */
+       .word   0                           /* intsave                            */
+       .word   0                           /* isleaf                             */
+       .word   0                           /* IsSync                             */
+       .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:
+asm_vm_call_method_float:
+asm_vm_call_method_double:
+       .set    noreorder                 /* XXX we need to recompute pv          */
 
-
-       .ent    asm_calljavafunction2
-
-call_name2:
-       .align  3
-
-       .dword  0                         /* catch type all                       */
-       .dword  calljava_xhandler2        /* handler pc                           */
-       .dword  calljava_xhandler2        /* end pc                               */
-       .dword  asm_calljavafunction2     /* start pc                             */
-       .word   1                         /* extable size                         */
-       .word   0                         /* fltsave                              */
-       .word   1                         /* intsave                              */
-       .word   0                         /* isleaf                               */
-       .word   0                         /* IsSync                               */
-       .word   12*8                      /* frame size                           */
-       .dword  0                         /* method pointer (pointer to name)     */
-
-asm_calljavafunction2:
-asm_calljavafunction2int:
-asm_calljavafunction2long:
-asm_calljavafunction2float:
-asm_calljavafunction2double:
        aaddiu  sp,sp,-12*8               /* allocate stack space (only 11 needed)*/
-       sd      ra,0(sp)                  /* save return address                  */
+       ast     ra,0*8(sp)                /* save return address                  */
 
-       .set    noreorder
-       bal     call_java_pc2
-       sd      pv,1*8(sp)                /* procedure vector                     */
-call_java_pc2:
+       bal     L_asm_vm_call_method_compute_pv
+       ast     pv,1*8(sp)                /* procedure vector                     */
+L_asm_vm_call_method_compute_pv:
        aaddiu  pv,ra,-4*4
-       sd      s7,3*8(sp)
 
-       .set    reorder
-       
+       ast     s0,3*8(sp)                /* save callee saved register           */
+       ast     a0,4*8(sp)                /* save method PV                       */
+
+#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)
-       sd      a0,4*8(sp)                /* save method pointer for compiler     */
-       move    t0,a3
-       move    s7,a1
-
-       blez    s7,calljava_argsloaded
-       ald     a0,offjniitem(t0)
-       ldc1    fa0,offjniitem(t0)
-       daddi   s7,s7,-1
-       blez    s7,calljava_argsloaded
-
-       ald     a1,offjniitem+sizejniblock*1(t0)
-       ldc1    fa1,offjniitem+sizejniblock*1(t0)
-       daddi   s7,s7,-1
-       blez    s7,calljava_argsloaded
-
-       ald     a2,offjniitem+sizejniblock*2(t0)
-       ldc1    fa2,offjniitem+sizejniblock*2(t0)
-       daddi   s7,s7,-1
-       blez    s7,calljava_argsloaded
-
-       ald     a3,offjniitem+sizejniblock*3(t0)
-       ldc1    fa3,offjniitem+sizejniblock*3(t0)
-       daddi   s7,s7,-1
-       blez    s7,calljava_argsloaded
-
-       ald     a4,offjniitem+sizejniblock*4(t0)
-       ldc1    fa4,offjniitem+sizejniblock*4(t0)
-       daddi   s7,s7,-1
-       blez    s7,calljava_argsloaded
-
-       ald     a5,offjniitem+sizejniblock*5(t0)
-       ldc1    fa5,offjniitem+sizejniblock*5(t0)
-       daddi   s7,s7,-1
-       blez    s7,calljava_argsloaded
-
-       ald     a6,offjniitem+sizejniblock*6(t0)
-       ldc1    fa6,offjniitem+sizejniblock*6(t0)
-       daddi   s7,s7,-1
-       blez    s7,calljava_argsloaded
-
-       ald     a7,offjniitem+sizejniblock*7(t0)
-       ldc1    fa7,offjniitem+sizejniblock*7(t0)
-       daddi   s7,s7,-1
-               
-calljava_argsloaded:
-    move    t8,sp
-       blez    s7,calljava_nocopy
-       subu    t1,zero,s7
-       sll     t2,t1,3
-       daddu   sp,sp,t2
-       daddu   t2,t2,t8
-
-calljava_copyloop:
-    ald     t3,offjniitem+sizejniblock*8(t0)
-       ast     t3,0(t2)
-       ala     t1,1(t1)
-       ala     t0,sizejniblock(t0)
-       ala     t2,8(t2)
-       bnez    t1,calljava_copyloop
-
-calljava_nocopy:
-       ala     itmp1,32(t8)              /* pass pointer to methodptr via itmp1  */
-
-       ala     mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
-       ast     mptr,16(sp)               /* store function address               */
-       ala     mptr,8(t8)                /* set method pointer                   */
-
-       .set    noreorder
-       
-       ald     pv,8(mptr)                /* method call as in Java               */
-       jalr    pv                        /* call JIT compiler                    */
+#endif
+
+       move    t0,a1                     /* address of data structure            */
+       move    t1,a2                     /* stack argument count                 */
+       move    s0,sp                     /* save stack pointer                   */
+
+#if SIZEOF_VOID_P == 8
+
+       ld      a0,0*8(t0)
+       ld      a1,1*8(t0)
+       ld      a2,2*8(t0)
+       ld      a3,3*8(t0)
+       ld      a4,4*8(t0)
+       ld      a5,5*8(t0)
+       ld      a6,6*8(t0)
+       ld      a7,7*8(t0)
+
+       ldc1    fa0,8*8(t0)
+       ldc1    fa1,9*8(t0)
+       ldc1    fa2,10*8(t0)
+       ldc1    fa3,11*8(t0)
+       ldc1    fa4,12*8(t0)
+       ldc1    fa5,13*8(t0)
+       ldc1    fa6,14*8(t0)
+       ldc1    fa7,15*8(t0)
+
+#else /* SIZEOF_VOID_P == 8 */
+
+# if WORDS_BIGENDIAN == 1
+       lw      a0,0*8+4(t0)
+       lw      a1,1*8+4(t0)
+       lw      a2,2*8+4(t0)
+       lw      a3,3*8+4(t0)
+# else
+       lw      a0,0*8(t0)
+       lw      a1,1*8(t0)
+       lw      a2,2*8(t0)
+       lw      a3,3*8(t0)
+# endif
+
+# if !defined(ENABLE_SOFT_FLOAT)
+       ldc1    fa0,4*8(t0)
+       ldc1    fa1,5*8(t0)
+# endif
+
+#endif /* SIZEOF_VOID_P == 8 */
+
+       beqz    t1,L_asm_vm_call_method_stack_copy_done
        nop
+
+       sll     t2,t1,3                   /* calculate stackframe size (* 8)      */
+       asubu   sp,sp,t2                  /* create stackframe                    */
+       move    t2,sp                     /* temporary stack pointer              */
+
+L_asm_vm_call_method_stack_copy_loop:
+#if SIZEOF_VOID_P == 8
+       ld      t3,16*8(t0)               /* load argument                        */
+       sd      t3,0(t2)                  /* store argument on stack              */
+#else
+# if !defined(ENABLE_SOFT_FLOAT)
+       lw      t3,6*8+0(t0)              /* load argument                        */
+       lw      t4,6*8+4(t0)
+       sw      t3,0(t2)                  /* store argument on stack              */
+       sw      t4,4(t2)
+# else
+#  error implement me
+# endif
+#endif
+
+       aaddi   t1,t1,-1                  /* subtract 1 argument                  */
+       aaddi   t0,t0,8                   /* load address of next argument        */
+       aaddi   t2,t2,8                   /* increase stack pointer               */
+
+       bgtz    t1,L_asm_vm_call_method_stack_copy_loop
+       nop
+
+L_asm_vm_call_method_stack_copy_done:
+       ala     mptr,4*8(s0)              /* get address of PV                    */
+       ald     pv,0*8(mptr)              /* load PV                              */
+       jalr    pv
+       nop
+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          */
+
+       move    sp,s0                     /* restore stack pointer                */
 
 calljava_return2:
-       ld      ra,0(sp)                  /* restore return address               */
-       ld      pv,8(sp)                  /* restore procedure vector             */
-       ld      s7,24(sp)
+       ald     ra,0*8(sp)                /* restore return address               */
+       ald     pv,1*8(sp)                /* restore procedure vector             */
+       ald     s0,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)
-       j       ra                        /* return                               */
+#endif
+
        aaddiu  sp,sp,12*8                /* free stack space                     */
+       j       ra                        /* return                               */
+
+asm_vm_call_method_exception_handler:
+       move    sp,s0                     /* restore stack pointer                */
+#if SIZEOF_VOID_P == 4
+       aaddiu  sp,sp,-4*4                /* reserve space for 1 argument         */
+#endif
 
-       .set    reorder
-       
-calljava_xhandler2:
-    sll     s7,s7,3
-       aaddu   sp,s7,sp
        move    a0,itmp1                  
        jal     builtin_throw_exception
+#if SIZEOF_VOID_P == 4
+       aaddiu  sp,sp,4*4
+#endif
+asm_vm_call_method_end:
        b       calljava_return2
 
-       .end    asm_calljavafunction2
+       .end    asm_vm_call_method
 
 
 /****************** function asm_call_jit_compiler *****************************
@@ -441,922 +296,581 @@ calljava_xhandler2:
 *                                                                              *
 *******************************************************************************/
 
-
        .ent    asm_call_jit_compiler
 
 asm_call_jit_compiler:
-       lw      t0,-12(ra)            /* load instruction LD PV,xxx($y)           */
-       srl     t0,t0,21              /* shift right register number $y           */
-       and     t0,t0,31              /* isolate register number                  */
-       addiu   t0,t0,-mptrreg        /* test for REG_METHODPTR                   */
-       beqz    t0,noregchange       
-
-       lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
-       sll     t0,t0,16
-       sra     t0,t0,16              /* isolate offset                           */
-       aaddu   mptr,t0,ra            /* compute update address                   */
-
-noregchange:
-       aaddiu  sp,sp,-18*8           /* allocate stack space                     */
-       sd      a0,0*8(sp)            /* save all argument registers              */
-       sd      a1,1*8(sp)            /* they could be used by method             */
-       sd      a2,2*8(sp)
-       sd      a3,3*8(sp)
-       sd      a4,4*8(sp)
-       sd      a5,5*8(sp)
-       sd      a6,6*8(sp)
-       sd      a7,7*8(sp)
-       sdc1    fa0,8*8(sp)
-       sdc1    fa1,9*8(sp)
-       sdc1    fa2,10*8(sp)
-       sdc1    fa3,11*8(sp)
-       sdc1    fa4,12*8(sp)
-       sdc1    fa5,13*8(sp)
-       sdc1    fa6,14*8(sp)
-       sdc1    fa7,15*8(sp)
-       sd      mptr,16*8(sp)         /* save method pointer                      */
-       sd      ra,17*8(sp)           /* save return address                      */
-
-       ald     a0,0(itmp1)           /* pass 'methodinfo' pointer to             */
-       jal     jit_compile           /* jit compiler                             */
-
-       ld      a0,0*8(sp)            /* restore argument registers               */
-       ld      a1,1*8(sp)            /* they could be used by method             */
-       ld      a2,2*8(sp)
-       ld      a3,3*8(sp)
-       ld      a4,4*8(sp)
-       ld      a5,5*8(sp)
-       ld      a6,6*8(sp)
-       ld      a7,7*8(sp)
-       ldc1    fa0,8*8(sp)
-       ldc1    fa1,9*8(sp)
-       ldc1    fa2,10*8(sp)
-       ldc1    fa3,11*8(sp)
-       ldc1    fa4,12*8(sp)
-       ldc1    fa5,13*8(sp)
-       ldc1    fa6,14*8(sp)
-       ldc1    fa7,15*8(sp)
-       ld      mptr,16*8(sp)         /* restore method pointer                   */
-       ld      ra,17*8(sp)           /* restore return address                   */
-       aaddiu  sp,sp,18*8            /* deallocate stack area                    */
-
-       lw      t0,-12(ra)            /* load instruction LDQ PV,xxx($yy)         */
-       sll     t0,t0,16
-       sra     t0,t0,16              /* isolate offset                           */
-
-       aaddu   t0,t0,mptr            /* compute update address via method pointer*/
-       ast     v0,0(t0)              /* save new method address there            */
-
-       move    pv,v0                 /* move method address into pv              */
+#if SIZEOF_VOID_P == 8
 
-       jr      pv                    /* and call method. The method returns      */
-                                     /* directly to the caller (ra).             */
+       aaddiu  sp,sp,-(ARG_CNT+2)*8  /* +2: keep stack 16-bytes aligned          */
 
-       .end    asm_call_jit_compiler
+       ast     ra,0*8(sp)            /* save return address                      */
 
+       SAVE_ARGUMENT_REGISTERS(1)
 
-/********************* function asm_handle_exception ***************************
-*                                                                              *
-*   This function handles an exception. It does not use the usual calling      *
-*   conventions. The exception pointer is passed in REG_ITMP1 and the          *
-*   pc from the exception raising position is passed in REG_ITMP2. It searches *
-*   the local exception table for a handler. If no one is found, it unwinds    *
-*   stacks and continues searching the callers.                                *
-*                                                                              *
-*   void asm_handle_exception (exceptionptr, exceptionpc);                     *
-*                                                                              *
-*******************************************************************************/
+       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
 
-       .ent    asm_handle_nat_exception
+       ald     ra,0*8(sp)            /* restore return address                   */
 
-asm_handle_nat_exception:
-       lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
-       sll     t0,t0,16
-       sra     t0,t0,16              /* isolate offset                           */
-       aaddu   pv,t0,ra              /* compute update address                   */
+       RESTORE_ARGUMENT_REGISTERS(1)
 
-       .aent    asm_handle_exception
+       aaddiu  sp,sp,(ARG_CNT+2)*8   /* remove stack frame                       */
 
-asm_handle_exception:
-       aaddiu  sp,sp,-14*8           /* allocate stack                           */
-       sd      v0,0*8(sp)            /* save possible used registers             */
-       sd      t0,1*8(sp)            /* also registers used by trace_exception   */
-       sd      t1,2*8(sp)
-       sd      t2,3*8(sp)
-       sd      t3,4*8(sp)
-       sd      t8,5*8(sp)
-       sd      a0,6*8(sp)
-       sd      a1,7*8(sp)
-       sd      a2,8*8(sp)
-       sd      a3,9*8(sp)
-       sd      a4,10*8(sp)
-       sd      a5,11*8(sp)
-       sd      a6,12*8(sp)
-       sd      a7,13*8(sp)
-
-       addu    t3,zero,1             /* set no unwind flag                       */
-ex_stack_loop:
-       aaddiu  sp,sp,-6*8            /* allocate stack                           */
-       sd      xptr,0*8(sp)          /* save used registers                      */
-       sd      xpc,1*8(sp)
-       sd      pv,2*8(sp)
-       sd      ra,3*8(sp)
-       sd      t3,4*8(sp)
-
-       move    a0,xptr
-       ald     a1,MethodPointer(pv)
-       move    a2,xpc
-/*     move    a3,t3 */
-       move    a3,zero
-       addu    a4,zero,1
-       jal     builtin_trace_exception /* trace_exception(xptr,methodptr)        */
-       
-       ld      xptr,0*8(sp)          /* restore used register                    */
-       ld      xpc,1*8(sp)
-       ld      pv,2*8(sp)
-       ld      ra,3*8(sp)
-       ld      t3,4*8(sp)
-       aaddiu  sp,sp,6*8             /* deallocate stack                         */
-       
-       lw      t0,ExTableSize(pv)    /* t0 = exception table size                */
-       beqz    t0,empty_table        /* if empty table skip                      */
-       aaddiu  t1,pv,ExTableStart    /* t1 = start of exception table            */
-
-ex_table_loop:
-       ald     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
-       sle     t2,t2,xpc             /* t2 = (startpc <= xpc)                    */
-       beqz    t2,ex_table_cont      /* if (false) continue                      */
-       ald     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
-       slt     t2,xpc,t2             /* t2 = (xpc < endpc)                       */
-       beqz    t2,ex_table_cont      /* if (false) continue                      */
-       ald     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
-       beqz    a1,ex_handle_it       /* NULL catches everything                  */
-
-       lw      itmp3,offclassloaded(a1)
-       bnez    itmp3,L_class_loaded
-
-       aaddiu  sp,sp,-8*8            /* allocate stack                           */
-       sd      t0,0*8(sp)            /* save used register                       */
-       sd      t1,1*8(sp)
-       sd      t3,2*8(sp)
-       sd      xptr,3*8(sp)
-       sd      xpc,4*8(sp)
-       sd      pv,5*8(sp)
-       sd      ra,6*8(sp)
-       sd      a1,7*8(sp)
-               
-       move    a0,a1
-       jal     class_load
-               
-       ld      t0,0*8(sp)            /* restore used register                    */
-       ld      t1,1*8(sp)
-       ld      t3,2*8(sp)
-       ld      xptr,3*8(sp)
-       ld      xpc,4*8(sp)
-       ld      pv,5*8(sp)
-       ld      ra,6*8(sp)
-       ld      a1,7*8(sp)
-       aaddiu  sp,sp,8*8             /* deallocate stack                         */
-       
-L_class_loaded:
-       lw      itmp3,offclasslinked(a1)
-       aaddiu  sp,sp,-8*8            /* allocate stack                           */
-       sd      a1,7*8(sp)
-       bnez    itmp3,L_class_linked
-
-       sd      t0,0*8(sp)            /* save used register                       */
-       sd      t1,1*8(sp)
-       sd      t3,2*8(sp)
-       sd      xptr,3*8(sp)
-       sd      xpc,4*8(sp)
-       sd      pv,5*8(sp)
-       sd      ra,6*8(sp)
-               
-       move    a0,a1
-       jal     class_link
-               
-       ld      t0,0*8(sp)            /* restore used register                    */
-       ld      t1,1*8(sp)
-       ld      t3,2*8(sp)
-       ld      xptr,3*8(sp)
-       ld      xpc,4*8(sp)
-       ld      pv,5*8(sp)
-       ld      ra,6*8(sp)
-
-L_class_linked:
-_crit_restart1:
-       ld      a1,7*8(sp)
-_crit_begin1:
-       ald     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
-       ald     a1,offclassvftbl(a1)  /* a1 = vftblptr(catchtype) class (not obj) */
-       lw      a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
-       lw      v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
-       lw      a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
-_crit_end1:
-       subu    a0,a0,v0              /* a0 = baseval(xptr) - baseval(catchtype)  */
-       sltu    v0,a1,a0              /* v0 = xptr is instanceof catchtype        */
-       aaddiu  sp,sp,8*8             /* deallocate stack                         */
-       bnez    v0,ex_table_cont      /* if (false) continue                      */
-
-ex_handle_it:
-       ald     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
-
-       beqz    t3,ex_jump            /* if (!(no stack unwinding) skip           */
-
-       ld      v0,0*8(sp)            /* restore possible used registers          */
-       ld      t0,1*8(sp)            /* also registers used by trace_exception   */
-       ld      t1,2*8(sp)
-       ld      t2,3*8(sp)
-       ld      t3,4*8(sp)
-       ld      t8,5*8(sp)
-       ld      a0,6*8(sp)
-       ld      a1,7*8(sp)
-       ld      a2,8*8(sp)
-       ld      a3,9*8(sp)
-       ld      a4,10*8(sp)
-       ld      a5,11*8(sp)
-       ld      a6,12*8(sp)
-       ld      a7,13*8(sp)
-       
-       aaddiu  sp,sp,14*8            /* deallocate stack                         */
-
-ex_jump:
-       jr      xpc                   /* jump to the handler                      */
-
-ex_table_cont:
-       aaddiu  t1,t1,ExEntrySize     /* next exception table entry               */
-       addiu   t0,t0,-1              /* decrement entry counter                  */
-       bgtz    t0,ex_table_loop      /* if (t0 > 0) next entry                   */
-
-empty_table:
-       beqz    t3,ex_already_cleared /* if here the first time, then             */
-       aaddiu  sp,sp,14*8            /* deallocate stack and                     */
-       move    t3,zero               /* clear the no unwind flag                 */
-ex_already_cleared:
-       lw      t0,IsSync(pv)         /* t0 = SyncOffset                          */
-       beqz    t0,no_monitor_exit    /* if zero no monitorexit                   */
-
-#if defined(USE_THREADS)
-       aaddu   t0,sp,t0              /* add stackptr to Offset                   */
-       ald     a0,-8(t0)             /* load monitorexit pointer                 */
-
-       aaddiu  sp,sp,-8*8            /* allocate stack                           */
-       sd      t0,0*8(sp)            /* save used register                       */
-       sd      t1,1*8(sp)
-       sd      t3,2*8(sp)
-       sd      xptr,3*8(sp)
-       sd      xpc,4*8(sp)
-       sd      pv,5*8(sp)
-       sd      ra,6*8(sp)
-
-       jal     builtin_monitorexit   /* builtin_monitorexit(objectptr)           */
-       
-       ld      t0,0*8(sp)            /* restore used register                    */
-       ld      t1,1*8(sp)
-       ld      t3,2*8(sp)
-       ld      xptr,3*8(sp)
-       ld      xpc,4*8(sp)
-       ld      pv,5*8(sp)
-       ld      ra,6*8(sp)
-       aaddiu  sp,sp,8*8             /* deallocate stack                         */
-#endif
+#else /* SIZEOF_VOID_P == 8 */
 
-no_monitor_exit:
-       lw      t0,FrameSize(pv)      /* t0 = frame size                          */
-       aaddu   sp,sp,t0              /* unwind stack                             */
-       move    t0,sp                 /* t0 = pointer to save area                */
-       lw      t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
-       bnez    t1,ex_no_restore      /* if (leaf) skip                           */
-       ld      ra,-8(t0)             /* restore ra                               */
-       aaddiu  t0,t0,-8              /* t0--                                     */
-ex_no_restore:
-       move    xpc,ra                /* the new xpc is ra                        */
-       lw      t1,IntSave(pv)        /* t1 = saved int register count            */
-       ala     t2,ex_int2            /* t2 = current pc                          */
-       sll     t1,t1,2               /* t1 = register count * 4                  */
-       asubu   t2,t2,t1              /* t2 = ex_int_sav - 4 * register count     */
-       jr      t2                    /* jump to save position                    */
-       ld      s0,-8*8(t0)
-       ld      s1,-7*8(t0)
-       ld      s2,-6*8(t0)
-       ld      s3,-5*8(t0)
-       ld      s4,-4*8(t0)
-       ld      s5,-3*8(t0)
-       ld      s6,-2*8(t0)
-       ld      s7,-1*8(t0)
-ex_int2:
-       sll     t1,t1,1               /* t1 = register count * 4 * 2              */
-       asubu   t0,t0,t1              /* t0 = t0 - 8 * register count             */
-
-       lw      t1,FltSave(pv)        /* t1 = saved flt register count            */
-       ala     t2,ex_flt2            /* t2 = current pc                          */
-       sll     t1,t1,2               /* t1 = register count * 4                  */
-       asubu   t2,t2,t1              /* t2 = ex_int_sav - 4 * register count     */
-       jr      t2                    /* jump to save position                    */
-       ldc1    fs0,-4*8(t0)
-       ldc1    fs1,-3*8(t0)
-       ldc1    fs2,-2*8(t0)
-       ldc1    fs3,-1*8(t0)
-ex_flt2:
-       lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
-       sll     t0,t0,16
-       sra     t0,t0,16              /* isolate offset                           */
-       aaddu   pv,t0,ra              /* compute update address                   */
-       b       ex_stack_loop
+       aaddiu  sp,sp,-(ARG_CNT+2)*8  /* +4: keep stack 16-bytes aligned          */
 
-       .end    asm_handle_nat_exception
+       ast     ra,4*4+0*4(sp)        /* save return address                      */
 
+       SAVE_ARGUMENT_REGISTERS(6)
 
-/********************* asm_check_clinit ****************************************
-*                                                                              *
-*   Checks if class is initialized. If not, do it right now.                   *
-*                                                                              *
-*******************************************************************************/
-               
-    .ent    asm_check_clinit
-
-asm_check_clinit:
-       daddiu  sp,sp,-24*8
-
-       sd      ra,0*8(sp)            /* save return address                      */
-
-       sd      a0,1*8(sp)            /* save argument registers for leaf funcs   */
-       sd      a1,2*8(sp)
-       sd      a2,3*8(sp)
-       sd      a3,4*8(sp)
-       sd      a4,5*8(sp)
-       sd      a5,6*8(sp)
-       sd      a6,7*8(sp)
-       sd      a7,8*8(sp)
-
-       sd      t0,9*8(sp)
-       sd      t1,10*8(sp)
-       sd      t2,11*8(sp)
-       sd      t3,12*8(sp)
-       sd      t8,13*8(sp)
-
-       sdc1    fa0,14*8(sp)
-       sdc1    fa1,15*8(sp)
-       sdc1    fa2,16*8(sp)
-       sdc1    fa3,17*8(sp)
-       sdc1    fa4,18*8(sp)
-       sdc1    fa5,19*8(sp)
-       sdc1    fa6,20*8(sp)
-       sdc1    fa7,21*8(sp)
-
-       sd      itmp2,22*8(sp)        /* save machine code                        */
-
-                                     /* check if class is initialized            */
-       lw      itmp3,offclassinit(itmp1)
-       bnez    itmp3,L_is_initialized
-       
-       move    a0,itmp1              /* move class pointer to a0                 */
-       jal     class_init
-               
-       beqz    v0,L_initializererror
+       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
 
-L_is_initialized:
-       ld      ra,0*8(sp)            /* get return address                       */
-       ld      itmp1,22*8(sp)        /* get machine code                         */
+       ald     ra,4*4+0*4(sp)        /* restore return address                   */
 
-       daddiu  ra,ra,-2*4            /* go back 2 instructions (jal + nop delay) */
-       sw      itmp1,0(ra)           /* patch first instruction                  */
-       dsrl32  itmp1,itmp1,0         /* get high 32 bit                          */
-       sw      itmp1,4(ra)           /* patch second instruction                 */
+       RESTORE_ARGUMENT_REGISTERS(6)
 
-       move    a0,ra                 /* start of flush area                      */
-       addiu   a1,zero,2*4           /* 2 instruction words long                 */
-       jal     docacheflush          /* flush!                                   */
-       
-       ld      ra,0*8(sp)            /* restore return address                   */
-
-       ld      a0,1*8(sp)            /* restore argument registers               */
-       ld      a1,2*8(sp)
-       ld      a2,3*8(sp)
-       ld      a3,4*8(sp)
-       ld      a4,5*8(sp)
-       ld      a5,6*8(sp)
-       ld      a6,7*8(sp)
-       ld      a7,8*8(sp)
-
-       ld      t0,9*8(sp)
-       ld      t1,10*8(sp)
-       ld      t2,11*8(sp)
-       ld      t3,12*8(sp)
-       ld      t8,13*8(sp)
-
-       ldc1    fa0,14*8(sp)
-       ldc1    fa1,15*8(sp)
-       ldc1    fa2,16*8(sp)
-       ldc1    fa3,17*8(sp)
-       ldc1    fa4,18*8(sp)
-       ldc1    fa5,19*8(sp)
-       ldc1    fa6,20*8(sp)
-       ldc1    fa7,21*8(sp)
-
-       daddiu  sp,sp,24*8
-
-       daddiu  ra,ra,-2*4            /* go back 2 instructions (jal + nop delay) */
-       jr      ra
-
-L_initializererror:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-       jal     builtin_asm_get_exceptionptrptr
-#else
-       la      v0,_exceptionptr
-#endif
-       ld      xptr,0(v0)            /* get the exception pointer                */
-       sd      zero,0(v0)            /* clear the exception pointer              */
-
-       ld      ra,0*8(sp)            /* restore return address                   */
-
-       ld      a0,1*8(sp)            /* restore argument registers               */
-       ld      a1,2*8(sp)
-       ld      a2,3*8(sp)
-       ld      a3,4*8(sp)
-       ld      a4,5*8(sp)
-       ld      a5,6*8(sp)
-       ld      a6,7*8(sp)
-       ld      a7,8*8(sp)
-
-       ld      t0,9*8(sp)
-       ld      t1,10*8(sp)
-       ld      t2,11*8(sp)
-       ld      t3,12*8(sp)
-       ld      t8,13*8(sp)
-
-       ldc1    fa0,14*8(sp)
-       ldc1    fa1,15*8(sp)
-       ldc1    fa2,16*8(sp)
-       ldc1    fa3,17*8(sp)
-       ldc1    fa4,18*8(sp)
-       ldc1    fa5,19*8(sp)
-       ldc1    fa6,20*8(sp)
-       ldc1    fa7,21*8(sp)
-
-       daddiu  sp,sp,24*8
-
-       aaddiu  xpc,ra,-4             /* faulting address is return adress - 4    */
-       b       asm_handle_exception
-
-       .end    asm_check_clinit
+       aaddiu  sp,sp,(ARG_CNT+2)*8   /* remove stack frame                       */
 
-               
-/********************* function asm_builtin_monitorenter ***********************
-*                                                                              *
-*   Does null check and calls monitorenter or throws an exception              *
-*                                                                              *
-*******************************************************************************/
+#endif /* SIZEOF_VOID_P == 8 */
 
-#if defined(USE_THREADS)
-       .ent    asm_builtin_monitorenter
+       beqz    pv,L_asm_call_jit_compiler_exception
 
-asm_builtin_monitorenter:
-       beqz    a0,nb_monitorenter        /* if (null) throw exception            */
-       ala     t9,builtin_monitorenter   /* else call builtin_monitorenter       */
-       j       t9
+       jr      pv                    /* and call method. The method returns      */
+                                     /* directly to the caller (ra).             */
 
-nb_monitorenter:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       ald     a0,string_java_lang_NullPointerException
-       jal     new_exception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
+L_asm_call_jit_compiler_exception:
+       aaddiu  sp,sp,-2*8
+       ast     ra,0*8(sp)
+       jal     exceptions_get_and_clear_exception
+       ald     ra,0*8(sp)
+       aaddiu  sp,sp,2*8
 
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
+       move    xptr,v0               /* get exception                            */
+       aaddiu  xpc,ra,-4             /* exception address is RA - 4              */
        b       asm_handle_nat_exception
 
-       .end    asm_builtin_monitorenter
-#endif
-
-
-/********************* function asm_builtin_monitorexit ************************
-*                                                                              *
-*   Does null check and calls monitorexit or throws an exception               *
-*                                                                              *
-*******************************************************************************/
-
-#if defined(USE_THREADS)
-       .ent    asm_builtin_monitorexit
-
-asm_builtin_monitorexit:
-       beqz    a0,nb_monitorexit         /* if (null) throw exception            */
-       ala     t9,builtin_monitorexit    /* else call builtin_monitorexit        */
-       j       t9
-
-nb_monitorexit:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       jal     new_nullpointerexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
+       .end    asm_call_jit_compiler
 
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
-       b       asm_handle_nat_exception
 
-       .end    asm_builtin_monitorexit
-#endif
+/* asm_handle_exception ********************************************************
 
+   This function handles an exception. It does not use the usual calling
+   conventions. The exception pointer is passed in REG_ITMP1 and the
+   pc from the exception raising position is passed in REG_ITMP2. It searches
+   the local exception table for a handler. If no one is found, it unwinds
+   stacks and continues searching the callers.
 
-/************************ function asm_builtin_idiv ****************************
-*                                                                              *
-*   Does null check and calls idiv or throws an exception                      *
-*                                                                              *
 *******************************************************************************/
 
-       .ent    asm_builtin_idiv
-
-asm_builtin_idiv:
-       beqz    a1,nb_idiv                /* if (null) throw exception            */
-       ala     itmp3,builtin_idiv        /* else call builtin_idiv               */
-       j       itmp3
-
-nb_idiv:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       jal     new_arithmeticexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
-
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
-       b       asm_handle_nat_exception
-
-       .end    asm_builtin_idiv
-
-
-/************************ function asm_builtin_ldiv ****************************
-*                                                                              *
-*   Does null check and calls ldiv or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
+       .ent    asm_handle_nat_exception
 
-       .ent    asm_builtin_ldiv
+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
 
-asm_builtin_ldiv:
-       beqz    a1,nb_ldiv                /* if (null) throw exception            */
-       ala     itmp3,builtin_ldiv        /* else call builtin_ldiv               */
-       j       itmp3
+       move    a0,ra                       /* pass RA                            */
+       jal     md_codegen_get_pv_from_pc   /* get PV from RA                     */
 
-nb_ldiv:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       jal     new_arithmeticexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
+#if SIZEOF_VOID_P == 8
+       ast     v0,2*8(sp)                  /* save PV                            */
 
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
-       b       asm_handle_nat_exception
+       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          */
 
-       .end    asm_builtin_ldiv
+       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
 
-/************************ function asm_builtin_irem ****************************
-*                                                                              *
-*   Does null check and calls irem or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
+       .aent    asm_handle_exception
 
-       .ent    asm_builtin_irem
+asm_handle_exception:
+       aaddiu  sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
+
+       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
 
-asm_builtin_irem:
-       beqz    a1,nb_irem                /* if (null) throw exception            */
-       ala     t9,builtin_irem           /* else call builtin_irem               */
-       j       t9
+       move    a0,xptr                     /* pass xptr                          */
+       move    a1,xpc                      /* pass xpc                           */
+       move    a2,pv                       /* pass PV                            */
 
-nb_irem:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       jal     new_arithmeticexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
+#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
 
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
-       b       asm_handle_nat_exception
+L_asm_handle_exception_continue:
+       jal     exceptions_handle_exception
+       
+       beqz    v0,L_asm_handle_exception_not_catched
 
-       .end    asm_builtin_irem
+       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
 
-/************************ function asm_builtin_lrem ****************************
-*                                                                              *
-*   Does null check and calls lrem or throws an exception                      *
-*                                                                              *
-*******************************************************************************/
+       RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
+       RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
+       
+       aaddiu  sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
+
+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
+
+       aaddiu  sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
+       move    t0,zero                     /* clear the maybe-leaf flag          */
+
+L_asm_handle_exception_no_leaf_stack:
+       lw      t1,FrameSize(pv)            /* get frame size                     */
+       aaddu   t1,sp,t1                    /* pointer to save area               */
+
+       lw      t2,IsLeaf(pv)               /* is leaf procedure                  */
+       bnez    t2,L_asm_handle_exception_no_ra_restore
+
+       ald     ra,-1*8(t1)                 /* restore ra                         */
+       aaddiu  t1,t1,-8                    /* t1--                               */
+
+L_asm_handle_exception_no_ra_restore:
+       move    xpc,ra                      /* the new xpc is ra                  */
+       lw      t2,IntSave(pv)              /* t1 = saved int register count      */
+       ala     t3,ex_int2                  /* t3 = current pc                    */
+       sll     t2,t2,2                     /* t2 = register count * 4            */
+       asubu   t3,t3,t2                    /* t3 = IntSave - 4 * register count  */
+       jr      t3                          /* jump to save position              */
+
+       ald     s0,-8*8(t1)
+       ald     s1,-7*8(t1)
+       ald     s2,-6*8(t1)
+       ald     s3,-5*8(t1)
+       ald     s4,-4*8(t1)
+       ald     s5,-3*8(t1)
+       ald     s6,-2*8(t1)
+       ald     s7,-1*8(t1)
 
-       .ent    asm_builtin_lrem
+ex_int2:
+       sll     t2,t2,1               /* t2 = register count * 4 * 2              */
+       asubu   t1,t1,t2              /* t1 = t0 - 8 * register count             */
+
+       lw      t2,FltSave(pv)        /* t2 = saved flt register count            */
+       ala     t3,ex_flt2            /* t3 = current pc                          */
+       sll     t2,t2,2               /* t2 = register count * 4                  */
+       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 */
 
-asm_builtin_lrem:
-       beqz    a1,nb_lrem                /* if (null) throw exception            */
-       ala     t9,builtin_lrem           /* else call builtin_lrem               */
-       j       t9
+ex_flt2:
+       lw      t1,FrameSize(pv)            /* get frame size                     */
+       aaddu   sp,sp,t1                    /* unwind stack                       */
+       b       L_asm_handle_exception_stack_loop
 
-nb_lrem:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       jal     new_arithmeticexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
+       .end    asm_handle_nat_exception
 
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
-       b       asm_handle_nat_exception
 
-       .end    asm_builtin_lrem
+/* asm_abstractmethoderror *****************************************************
 
+   Creates and throws an AbstractMethodError.
 
-/******************* function asm_builtin_checkarraycast ***********************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
 *******************************************************************************/
 
-       .ent    asm_builtin_checkarraycast
-
-asm_builtin_checkarraycast:
-       aaddiu  sp,sp,-16                 /* allocate stack space                 */
-       sd      ra,0(sp)                  /* save return address                  */
-       sd      a0,8(sp)                  /* save object pointer                  */
-       jal     builtin_checkarraycast    /* builtin_checkarraycast               */
-       beqz    v0,nb_carray_throw        /* if (false) throw exception           */
-       ld      ra,0(sp)                  /* restore return address               */
-       ld      v0,8(sp)                  /* return object pointer                */
-       aaddiu  sp,sp,16                  /* deallocate stack                     */
-       j       ra                        /* return                               */
+       .ent    asm_abstractmethoderror
 
-nb_carray_throw:
-       jal     new_classcastexception
-       move    xptr,v0
+asm_abstractmethoderror:
+       aaddiu  sp,sp,-2*8                  /* create stackframe                  */
+       ast     ra,0*8(sp)                  /* save return address                */
+       aaddiu  a0,sp,2*8                   /* pass java sp                       */
+       move    a1,ra                       /* pass exception address             */
+       jal     exceptions_asm_new_abstractmethoderror
+       ald     ra,0*8(sp)                  /* restore return address             */
+       aaddiu  sp,sp,2*8                   /* remove stackframe                  */
 
-       ld      ra,0(sp)                  /* restore return address               */
-       aaddiu  sp,sp,16                  /* free stack space                     */
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
+       move    xptr,v0                     /* get exception pointer              */
+       aaddiu  xpc,ra,-4                   /* exception address is ra - 4        */
        b       asm_handle_nat_exception
 
-       .end    asm_builtin_checkarraycast
-
+       .end    asm_abstractmethoderror
 
-/********************* function asm_builtin_checkcast **************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*                                                                              *
-*******************************************************************************/
 
-       .ent    asm_builtin_checkcast
-
-asm_builtin_checkcast:
-       aaddiu  sp,sp,-16                 /* allocate stack space                 */
-       sd      ra,0(sp)                  /* save return address                  */
-       sd      a0,8(sp)                  /* save object pointer                  */
-       jal     builtin_checkcast         /* builtin_checkcast                    */
-       beqz    v0,nb_ccast_throw         /* if (false) throw exception           */
-       ld      ra,0(sp)                  /* restore return address               */
-       ld      v0,8(sp)                  /* return object pointer                */
-       aaddiu  sp,sp,16                  /* deallocate stack                     */
-       j       ra                        /* return                               */
+#if defined(ENABLE_REPLACEMENT)
+               
+/* asm_replacement_out *********************************************************
 
-nb_ccast_throw:
-       jal     new_classcastexception
-       move    xptr,v0
+   This code is jumped to from the replacement-out stubs that are executed
+   when a thread reaches an activated replacement point.
 
-       ld      ra,0(sp)                  /* restore return address               */
-       aaddiu  sp,sp,16                  /* free stack space                     */
-       aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
-       b       asm_handle_nat_exception
+   The purpose of asm_replacement_out is to read out the parts of the
+   execution state that cannot be accessed from C code, store this state,
+   and then call the C function replace_me.
 
-       .end    asm_builtin_checkcast
+   Stack layout:
+     16                 start of stack inside method to replace
+      0   rplpoint *    info on the replacement point that was reached
 
+   NOTE: itmp3 has been clobbered by the replacement-out stub!
 
-/******************* function asm_builtin_aastore ******************************
-*                                                                              *
-*   Does the cast check and eventually throws an exception                     *
-*   a0 = arrayref, a1 = index, a2 = value                                      *
-*                                                                              *
 *******************************************************************************/
 
-       .ent    asm_builtin_aastore
-
-asm_builtin_aastore:
-       beqz    a0,nb_aastore_null        /* if null pointer throw exception      */
-       lw      t0,offarraysize(a0)       /* load size                            */
-       aaddiu  sp,sp,-32                 /* allocate stack space                 */
-       sd      ra,0(sp)                  /* save return address                  */
-       asll    t1,a1,ashift              /* add index*8 to arrayref              */
-       aaddu   t1,a0,t1                  /* add index * ashift to arrayref       */
-       sltu    t0,a1,t0                  /* do bound check                       */
-       beqz    t0,nb_aastore_bound       /* if out of bounds throw exception     */
-       move    a1,a2                     /* object is second argument            */
-       sd      t1,8(sp)                  /* save store position                  */
-       sd      a1,16(sp)                 /* save object                          */
-       jal     builtin_canstore          /* builtin_canstore(arrayref,object)    */
-       ld      ra,0(sp)                  /* restore return address               */
-       ld      a0,8(sp)                  /* restore store position               */
-       ld      a1,16(sp)                 /* restore object                       */
-       aaddiu  sp,sp,32                  /* free stack space                     */
-       beqz    v0,nb_aastore_store       /* if (false) throw exception           */
-       ast     a1,offobjarrdata(a0)      /* store objectptr in array             */
-       j       ra                        /* return                               */
-
-nb_aastore_null:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       jal     new_nullpointerexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
+/* some room to accomodate changes of the stack frame size during replacement */
+       /* XXX we should find a cleaner solution here */
+#define REPLACEMENT_ROOM  512
+
+#define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
+
+       .ent asm_replacement_out
+
+asm_replacement_out:
+    /* create stack frame */
+       aaddiu  sp,sp,-REPLACEMENT_STACK_OFFSET
+
+       /* save registers in execution state */
+       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)
+       sdc1    $f3 ,( 3*8+offes_fltregs)(sp)
+       sdc1    $f4 ,( 4*8+offes_fltregs)(sp)
+       sdc1    $f5 ,( 5*8+offes_fltregs)(sp)
+       sdc1    $f6 ,( 6*8+offes_fltregs)(sp)
+       sdc1    $f7 ,( 7*8+offes_fltregs)(sp)
+       sdc1    $f8 ,( 8*8+offes_fltregs)(sp)
+       sdc1    $f9 ,( 9*8+offes_fltregs)(sp)
+       sdc1    $f10,(10*8+offes_fltregs)(sp)
+       sdc1    $f11,(11*8+offes_fltregs)(sp)
+       sdc1    $f12,(12*8+offes_fltregs)(sp)
+       sdc1    $f13,(13*8+offes_fltregs)(sp)
+       sdc1    $f14,(14*8+offes_fltregs)(sp)
+       sdc1    $f15,(15*8+offes_fltregs)(sp)
+       sdc1    $f16,(16*8+offes_fltregs)(sp)
+       sdc1    $f17,(17*8+offes_fltregs)(sp)
+       sdc1    $f18,(18*8+offes_fltregs)(sp)
+       sdc1    $f19,(19*8+offes_fltregs)(sp)
+       sdc1    $f20,(20*8+offes_fltregs)(sp)
+       sdc1    $f21,(21*8+offes_fltregs)(sp)
+       sdc1    $f22,(22*8+offes_fltregs)(sp)
+       sdc1    $f23,(23*8+offes_fltregs)(sp)
+       sdc1    $f24,(24*8+offes_fltregs)(sp)
+       sdc1    $f25,(25*8+offes_fltregs)(sp)
+       sdc1    $f26,(26*8+offes_fltregs)(sp)
+       sdc1    $f27,(27*8+offes_fltregs)(sp)
+       sdc1    $f28,(28*8+offes_fltregs)(sp)
+       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 */
        
-       move    xpc,ra                    /* faulting address is return adress    */
-       b       asm_handle_nat_exception
+       /* calculate sp of method */
+       aaddiu  itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
+       ast     itmp1,(offes_sp)(sp)
 
-nb_aastore_bound:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       move    a0,a1                     /* move index into a0                   */
-       jal     new_arrayindexoutofboundsexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
-
-       aaddiu  sp,sp,32                  /* free stack space                     */
-       move    xpc,ra                    /* faulting address is return adress    */
-       b       asm_handle_nat_exception
+       /* store pv */
+       ast     pv,(offes_pv)(sp)
 
-nb_aastore_store:
-       daddiu  sp,sp,-2*8
-       sd      ra,0*8(sp)
-       jal     new_arraystoreexception
-       move    xptr,v0
-       ld      ra,0*8(sp)
-       daddiu  sp,sp,2*8
+       /* call replace_me */
+       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                      */
 
-       move    xpc,ra                    /* faulting address is return adress    */
-       b       asm_handle_nat_exception
+       .end asm_replacement_out
 
-       .end    asm_builtin_aastore
+/* asm_replacement_in **********************************************************
 
+   This code writes the given execution state and jumps to the replacement
+   code.
 
-/******************* function asm_initialize_thread_stack **********************
-*                                                                              *
-*   u1* asm_initialize_thread_stack (void *func, u1 *stack);                   *
-*                                                                              *
-*   initialize a thread stack                                                  *
-*                                                                              *
-*******************************************************************************/
+   This function never returns!
 
-       .ent    asm_initialize_thread_stack
-
-asm_initialize_thread_stack:
-       aaddiu  a1,a1,-14*8     /* allocate save area                             */
-       sd      zero, 0*8(a1)   /* s0 initalize thread area                       */
-       sd      zero, 1*8(a1)   /* s1                                             */
-       sd      zero, 2*8(a1)   /* s2                                             */
-       sd      zero, 3*8(a1)   /* s3                                             */
-       sd      zero, 4*8(a1)   /* s4                                             */
-       sd      zero, 5*8(a1)   /* s5                                             */
-       sd      zero, 6*8(a1)   /* s6                                             */
-       sd      zero, 7*8(a1)   /* s7                                             */
-       sd      zero, 8*8(a1)   /* s8                                             */
-       sd      zero, 9*8(a1)   /* fs0                                            */
-       sd      zero,10*8(a1)   /* fs1                                            */
-       sd      zero,11*8(a1)   /* fs2                                            */
-       sd      zero,12*8(a1)   /* fs3                                            */
-       sd      a0, 13*8(a1)
-       move    v0,a1
-       j       ra              /* return                                         */
-
-       .end    asm_initialize_thread_stack
-
-
-/******************* function asm_perform_threadswitch *************************
-*                                                                              *
-*   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
-*                                                                              *
-*   performs a threadswitch                                                    *
-*                                                                              *
-*******************************************************************************/
+   NOTE: itmp3 is not restored!
 
-       .ent    asm_perform_threadswitch
-
-asm_perform_threadswitch:
-       aaddiu  sp,sp,-14*8     /* allocate new stack                             */
-       sd      s0,  0*8(sp)    /* save saved registers of old thread             */
-       sd      s1,  1*8(sp)
-       sd      s2,  2*8(sp)
-       sd      s3,  3*8(sp)
-       sd      s4,  4*8(sp)
-       sd      s5,  5*8(sp)
-       sd      s6,  6*8(sp)
-       sd      s7,  7*8(sp)
-       sd      s8,  8*8(sp)
-       sdc1    fs0, 9*8(sp)
-       sdc1    fs1,10*8(sp)
-       sdc1    fs2,11*8(sp)
-       sdc1    fs3,12*8(sp)
-       sd      ra, 13*8(sp)
-       ast     sp,0(a0)        /* save old stack pointer                         */
-       ast     sp,0(a2)        /* stackTop = old stack pointer                   */
-       ald     sp,0(a1)        /* load new stack pointer                         */
-       ld      s0,  0*8(sp)    /* load saved registers of new thread             */
-       ld      s1,  1*8(sp)
-       ld      s2,  2*8(sp)
-       ld      s3,  3*8(sp)
-       ld      s4,  4*8(sp)
-       ld      s5,  5*8(sp)
-       ld      s6,  6*8(sp)
-       ld      s7,  7*8(sp)
-       ld      s8,  8*8(sp)
-       ldc1    fs0, 9*8(sp)
-       ldc1    fs1,10*8(sp)
-       ldc1    fs2,11*8(sp)
-       ldc1    fs3,12*8(sp)
-       ld      ra, 13*8(sp)
-       aaddiu  sp,sp,14*8      /* deallocate new stack                           */
-       move    itmp3, ra
-       j       ra              /* return                                         */
-
-       .end    asm_perform_threadswitch
-
-
-/********************* function asm_switchstackandcall *************************
-*                                                                              *
-*  void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
-*                                                                              *
-*   Switches to a new stack, calls a function and switches back.               *
-*       a0      new stack pointer                                              *
-*       a1      function pointer                                               *
-*              a2              pointer to variable where stack top should be stored           *
-*                                                                              *
-*******************************************************************************/
+   C prototype:
+      void asm_replacement_in(executionstate *es);
 
-       .ent    asm_switchstackandcall
+*******************************************************************************/
 
-asm_switchstackandcall:
-       aaddiu  a0,a0,-16       /* allocate new stack                             */
-       sd      ra,0(a0)        /* save return address on new stack               */
-       sd      sp,8(a0)        /* save old stack pointer on new stack            */
-       sd      sp,0(a2)        /* save old stack pointer to variable             */
-       move    sp,a0           /* switch to new stack                            */
+       .ent asm_replacement_in
        
-       move    itmp3,a1
-       move    a0,a3
-       jalr    itmp3           /* and call function                              */
-
-       ld      ra,0(sp)        /* load return address                            */
-       ld      sp,8(sp)        /* switch to old stack                            */
-
-       j       ra              /* return                                         */
+asm_replacement_in:
+       /* a0 == executionstate *es */
 
-       .end    asm_switchstackandcall
-
-
-       .ent    asm_getclassvalues_atomic
-
-asm_getclassvalues_atomic:
-_crit_restart2:
-_crit_begin2:
-       lw      t0,offbaseval(a0)
-       lw      t1,offdiffval(a0)
-       lw      t2,offbaseval(a1)
-_crit_end2:
-       sw      t0,offcast_super_baseval(a2)
-       sw      t1,offcast_super_diffval(a2)
-       sw      t2,offcast_sub_baseval(a2)
-       j       ra
+       /* set new sp and pv */
+       ald     sp,(offes_sp)(a0)
+       ald     pv,(offes_pv)(a0)
+       
+       /* copy registers from execution state */
+       /* $0 is zero                     */
+       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             */
+       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                      */
+       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)
+       ldc1    $f3 ,( 3*8+offes_fltregs)(a0)
+       ldc1    $f4 ,( 4*8+offes_fltregs)(a0)
+       ldc1    $f5 ,( 5*8+offes_fltregs)(a0)
+       ldc1    $f6 ,( 6*8+offes_fltregs)(a0)
+       ldc1    $f7 ,( 7*8+offes_fltregs)(a0)
+       ldc1    $f8 ,( 8*8+offes_fltregs)(a0)
+       ldc1    $f9 ,( 9*8+offes_fltregs)(a0)
+       ldc1    $f10,(10*8+offes_fltregs)(a0)
+       ldc1    $f11,(11*8+offes_fltregs)(a0)
+       ldc1    $f12,(12*8+offes_fltregs)(a0)
+       ldc1    $f13,(13*8+offes_fltregs)(a0)
+       ldc1    $f14,(14*8+offes_fltregs)(a0)
+       ldc1    $f15,(15*8+offes_fltregs)(a0)
+       ldc1    $f16,(16*8+offes_fltregs)(a0)
+       ldc1    $f17,(17*8+offes_fltregs)(a0)
+       ldc1    $f18,(18*8+offes_fltregs)(a0)
+       ldc1    $f19,(19*8+offes_fltregs)(a0)
+       ldc1    $f20,(20*8+offes_fltregs)(a0)
+       ldc1    $f21,(21*8+offes_fltregs)(a0)
+       ldc1    $f22,(22*8+offes_fltregs)(a0)
+       ldc1    $f23,(23*8+offes_fltregs)(a0)
+       ldc1    $f24,(24*8+offes_fltregs)(a0)
+       ldc1    $f25,(25*8+offes_fltregs)(a0)
+       ldc1    $f26,(26*8+offes_fltregs)(a0)
+       ldc1    $f27,(27*8+offes_fltregs)(a0)
+       ldc1    $f28,(28*8+offes_fltregs)(a0)
+       ldc1    $f29,(29*8+offes_fltregs)(a0)
+       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 */
+
+       ald     itmp3,offes_pc(a0)
+
+       /* load a0 */
+       
+       ald     a0,(4*8+offes_intregs)(a0)
 
-       .end    asm_getclassvalues_atomic
+       /* jump to new code */
 
-    .data
+       jr      itmp3
 
-asm_criticalsections:
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-    .dword  _crit_begin1
-    .dword  _crit_end1
-    .dword  _crit_restart1
-    .dword  _crit_begin2
-    .dword  _crit_end2
-    .dword  _crit_restart2
-#endif
-    .dword  0
+       .end asm_replacement_in
 
+#endif /* defined(ENABLE_REPLACEMENT) */
 
-       .text
 
        .ent    compare_and_swap
+
 compare_and_swap:
 1:
-       lld             v0,0(a0)
-       bne             v0,a1,2f
+       all     v0,0(a0)
+       bne     v0,a1,2f
        move    t0,a2
-       scd             t0,0(a0)
-       beqz    t0,1b
+       asc     t0,0(a0)
+       beqz    t0,1b
 2:
        sync
-       j               ra
+       j       ra
+
        .end    compare_and_swap
+
+
+/* disable exec-stacks ********************************************************/
+
+#if defined(__linux__) && defined(__ELF__)
+       .section .note.GNU-stack,"",%progbits
+#endif
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
@@ -1368,4 +882,5 @@ compare_and_swap:
  * c-basic-offset: 4
  * tab-width: 4
  * End:
+ * vim:noexpandtab:sw=4:ts=4:
  */