5f3be73bea0a1f795824090af8bf783eb0b43566
[cacao.git] / src / vm / jit / mips / asmpart.S
1 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: asmpart.S 8274 2007-08-08 15:58:17Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include "vm/jit/mips/md-abi.h"
33 #include "vm/jit/mips/md-asm.h"
34
35 #include "vm/jit/abi-asm.h"
36 #include "vm/jit/methodheader.h"
37
38
39         .text
40         .set    noat
41
42
43 /* export functions ***********************************************************/
44
45         .globl asm_vm_call_method
46         .globl asm_vm_call_method_int
47         .globl asm_vm_call_method_long
48         .globl asm_vm_call_method_float
49         .globl asm_vm_call_method_double
50         .globl asm_vm_call_method_exception_handler
51         .globl asm_vm_call_method_end
52
53         .globl asm_call_jit_compiler
54
55         .globl asm_handle_exception
56         .globl asm_handle_nat_exception
57
58         .globl asm_abstractmethoderror
59
60 #if defined(ENABLE_REPLACEMENT)
61         .globl asm_replacement_out
62         .globl asm_replacement_in
63 #endif
64
65         .globl compare_and_swap
66
67
68 /* asm_vm_call_method **********************************************************
69 *                                                                              *
70 *   This function calls a Java-method (which possibly needs compilation)       *
71 *   with up to 4 address parameters.                                           *
72 *                                                                              *
73 *   This functions calls the JIT-compiler which eventually translates the      *
74 *   method into machine code.                                                  *
75 *                                                                              *
76 *   A possibly throwed exception will be returned to the caller as function    *
77 *   return value, so the java method cannot return a fucntion value (this      *
78 *   function usually calls 'main' and '<clinit>' which do not return a         *
79 *   function value).                                                           *
80 *                                                                              *
81 *   C-prototype:                                                               *
82 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
83 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
84 *                                                                              *
85 *******************************************************************************/
86
87         .ent    asm_vm_call_method
88
89         .align  3
90
91 #if SIZEOF_VOID_P == 8
92
93         .dword  0                           /* catch type all                     */
94         .dword  0                           /* handler pc                         */
95         .dword  0                           /* end pc                             */
96         .dword  0                           /* start pc                           */
97         .word   1                           /* extable size                       */
98         .word   0                           /* 4-byte ALIGNMENT PADDING           */
99         .dword  0                           /* line number table start            */
100         .dword  0                           /* line number table size             */
101         .word   0                           /* 4-byte ALIGNMENT PADDING           */
102         .word   0                           /* fltsave                            */
103         .word   0                           /* intsave                            */
104         .word   0                           /* isleaf                             */
105         .word   0                           /* IsSync                             */
106         .word   0                           /* frame size                         */
107         .dword  0                           /* codeinfo pointer                   */
108
109 #else /* SIZEOF_VOID_P == 8 */
110
111         .word   0                           /* catch type all                     */
112         .word   0                           /* handler pc                         */
113         .word   0                           /* end pc                             */
114         .word   0                           /* start pc                           */
115         .word   1                           /* extable size                       */
116         .word   0                           /* line number table start            */
117         .word   0                           /* line number table size             */
118         .word   0                           /* fltsave                            */
119         .word   0                           /* intsave                            */
120         .word   0                           /* isleaf                             */
121         .word   0                           /* IsSync                             */
122         .word   0                           /* frame size                         */
123         .word   0                           /* method pointer (pointer to name)   */
124
125 #endif /* SIZEOF_VOID_P == 8 */
126
127 asm_vm_call_method:
128 asm_vm_call_method_int:
129 asm_vm_call_method_long:
130 asm_vm_call_method_float:
131 asm_vm_call_method_double:
132         .set    noreorder                 /* XXX we need to recompute pv          */
133
134         aaddiu  sp,sp,-12*8               /* allocate stack space (only 11 needed)*/
135         ast     ra,0*8(sp)                /* save return address                  */
136
137         bal     L_asm_vm_call_method_compute_pv
138         ast     pv,1*8(sp)                /* procedure vector                     */
139 L_asm_vm_call_method_compute_pv:
140         aaddiu  pv,ra,-4*4
141
142         ast     s0,3*8(sp)                /* save callee saved register           */
143         ast     a0,4*8(sp)                /* save method PV                       */
144
145 #if SIZEOF_VOID_P == 8
146         sdc1    fss0,5*8(sp)              /* save non JavaABI saved flt registers */
147         sdc1    fss1,6*8(sp)
148         sdc1    fss2,7*8(sp)
149         sdc1    fss3,8*8(sp)
150         sdc1    fss4,9*8(sp)
151         sdc1    fss5,10*8(sp)
152 #endif
153
154         move    t0,a1                     /* address of data structure            */
155         move    t1,a2                     /* stack argument count                 */
156         move    s0,sp                     /* save stack pointer                   */
157
158 #if SIZEOF_VOID_P == 8
159
160         ld      a0,0*8(t0)
161         ld      a1,1*8(t0)
162         ld      a2,2*8(t0)
163         ld      a3,3*8(t0)
164         ld      a4,4*8(t0)
165         ld      a5,5*8(t0)
166         ld      a6,6*8(t0)
167         ld      a7,7*8(t0)
168
169         ldc1    fa0,8*8(t0)
170         ldc1    fa1,9*8(t0)
171         ldc1    fa2,10*8(t0)
172         ldc1    fa3,11*8(t0)
173         ldc1    fa4,12*8(t0)
174         ldc1    fa5,13*8(t0)
175         ldc1    fa6,14*8(t0)
176         ldc1    fa7,15*8(t0)
177
178 #else /* SIZEOF_VOID_P == 8 */
179
180 # if WORDS_BIGENDIAN == 1
181         lw      a0,0*8+4(t0)
182         lw      a1,1*8+4(t0)
183         lw      a2,2*8+4(t0)
184         lw      a3,3*8+4(t0)
185 # else
186         lw      a0,0*8(t0)
187         lw      a1,1*8(t0)
188         lw      a2,2*8(t0)
189         lw      a3,3*8(t0)
190 # endif
191
192 # if !defined(ENABLE_SOFT_FLOAT)
193         ldc1    fa0,4*8(t0)
194         ldc1    fa1,5*8(t0)
195 # endif
196
197 #endif /* SIZEOF_VOID_P == 8 */
198
199         beqz    t1,L_asm_vm_call_method_stack_copy_done
200         nop
201
202         sll     t2,t1,3                   /* calculate stackframe size (* 8)      */
203         asubu   sp,sp,t2                  /* create stackframe                    */
204         move    t2,sp                     /* temporary stack pointer              */
205
206 L_asm_vm_call_method_stack_copy_loop:
207 #if SIZEOF_VOID_P == 8
208         ld      t3,16*8(t0)               /* load argument                        */
209         sd      t3,0(t2)                  /* store argument on stack              */
210 #else
211 # if !defined(ENABLE_SOFT_FLOAT)
212         lw      t3,6*8+0(t0)              /* load argument                        */
213         lw      t4,6*8+4(t0)
214         sw      t3,0(t2)                  /* store argument on stack              */
215         sw      t4,4(t2)
216 # else
217 #  error implement me
218 # endif
219 #endif
220
221         aaddi   t1,t1,-1                  /* subtract 1 argument                  */
222         aaddi   t0,t0,8                   /* load address of next argument        */
223         aaddi   t2,t2,8                   /* increase stack pointer               */
224
225         bgtz    t1,L_asm_vm_call_method_stack_copy_loop
226         nop
227
228 L_asm_vm_call_method_stack_copy_done:
229         ala     mptr,4*8(s0)              /* get address of PV                    */
230         ald     pv,0*8(mptr)              /* load PV                              */
231         jalr    pv
232         nop
233 L_asm_vm_call_method_recompute_pv:
234 #if SIZEOF_VOID_P == 8
235         aaddiu  pv,ra,-76*4               /* recompute procedure vector           */
236 #else
237         aaddiu  pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)
238 #endif
239
240         .set    reorder                   /* XXX we need to recompute pv          */
241
242         move    sp,s0                     /* restore stack pointer                */
243
244 calljava_return2:
245         ald     ra,0*8(sp)                /* restore return address               */
246         ald     pv,1*8(sp)                /* restore procedure vector             */
247         ald     s0,3*8(sp)
248
249 #if SIZEOF_VOID_P == 8
250         ldc1    fss0,5*8(sp)              /* restore non JavaABI saved flt regs   */
251         ldc1    fss1,6*8(sp)
252         ldc1    fss2,7*8(sp)
253         ldc1    fss3,8*8(sp)
254         ldc1    fss4,9*8(sp)
255         ldc1    fss5,10*8(sp)
256 #endif
257
258         aaddiu  sp,sp,12*8                /* free stack space                     */
259         j       ra                        /* return                               */
260
261 asm_vm_call_method_exception_handler:
262         move    sp,s0                     /* restore stack pointer                */
263 #if SIZEOF_VOID_P == 4
264         aaddiu  sp,sp,-4*4                /* reserve space for 1 argument         */
265 #endif
266
267         move    a0,itmp1                  
268         jal     builtin_throw_exception
269 #if SIZEOF_VOID_P == 4
270         aaddiu  sp,sp,4*4
271 #endif
272 asm_vm_call_method_end:
273         b       calljava_return2
274
275         .end    asm_vm_call_method
276
277
278 /****************** function asm_call_jit_compiler *****************************
279 *                                                                              *
280 *   invokes the compiler for untranslated JavaVM methods.                      *
281 *                                                                              *
282 *   Register REG_ITEMP1 contains a pointer to the method info structure        *
283 *   (prepared by createcompilerstub). Using the return address in R31 and the  *
284 *   offset in the LDA instruction or using the value in methodptr R25 the      *
285 *   patching address for storing the method address can be computed:           *
286 *                                                                              *
287 *   method address was either loaded using                                     *
288 *   M_ALD (REG_PV, REG_PV, a)        ; invokestatic/special    ($28)           *
289 *   M_JSR (REG_RA, REG_PV);                                                    *
290 *   M_NOP                                                                      *
291 *   M_LDA (REG_PV, REG_RA, val)                                                *
292 *   or                                                                         *
293 *   M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25)           *
294 *   M_JSR (REG_RA, REG_PV);                                                    *
295 *   M_NOP                                                                      *
296 *   in the static case the method pointer can be computed using the            *
297 *   return address and the lda function following the jmp instruction          *
298 *                                                                              *
299 *******************************************************************************/
300
301         .ent    asm_call_jit_compiler
302
303 asm_call_jit_compiler:
304 #if SIZEOF_VOID_P == 8
305
306         aaddiu  sp,sp,-(ARG_CNT+2)*8  /* +2: keep stack 16-bytes aligned          */
307
308         ast     ra,0*8(sp)            /* save return address                      */
309
310         SAVE_ARGUMENT_REGISTERS(1)
311
312         move    a0,itmp1              /* pass methodinfo pointer                  */
313         move    a1,mptr               /* pass method pointer                      */
314         aaddiu  a2,sp,(ARG_CNT+2)*8   /* pass java sp                             */
315         move    a3,ra
316         jal     jit_asm_compile       /* call jit compiler                        */
317         move    pv,v0
318
319         ald     ra,0*8(sp)            /* restore return address                   */
320
321         RESTORE_ARGUMENT_REGISTERS(1)
322
323         aaddiu  sp,sp,(ARG_CNT+2)*8   /* remove stack frame                       */
324
325 #else /* SIZEOF_VOID_P == 8 */
326
327         aaddiu  sp,sp,-(ARG_CNT+2)*8  /* +4: keep stack 16-bytes aligned          */
328
329         ast     ra,4*4+0*4(sp)        /* save return address                      */
330
331         SAVE_ARGUMENT_REGISTERS(6)
332
333         move    a0,itmp1              /* pass methodinfo pointer                  */
334         move    a1,mptr               /* pass method pointer                      */
335         aaddiu  a2,sp,(ARG_CNT+2)*8   /* pass java sp                             */
336         move    a3,ra
337         jal     jit_asm_compile       /* call jit compiler                        */
338         move    pv,v0
339
340         ald     ra,4*4+0*4(sp)        /* restore return address                   */
341
342         RESTORE_ARGUMENT_REGISTERS(6)
343
344         aaddiu  sp,sp,(ARG_CNT+2)*8   /* remove stack frame                       */
345
346 #endif /* SIZEOF_VOID_P == 8 */
347
348         beqz    pv,L_asm_call_jit_compiler_exception
349
350         jr      pv                    /* and call method. The method returns      */
351                                       /* directly to the caller (ra).             */
352
353 L_asm_call_jit_compiler_exception:
354         aaddiu  sp,sp,-2*8
355         ast     ra,0*8(sp)
356         jal     exceptions_get_and_clear_exception
357         ald     ra,0*8(sp)
358         aaddiu  sp,sp,2*8
359
360         move    xptr,v0               /* get exception                            */
361         aaddiu  xpc,ra,-4             /* exception address is RA - 4              */
362         b       asm_handle_nat_exception
363
364         .end    asm_call_jit_compiler
365
366
367 /* asm_handle_exception ********************************************************
368
369    This function handles an exception. It does not use the usual calling
370    conventions. The exception pointer is passed in REG_ITMP1 and the
371    pc from the exception raising position is passed in REG_ITMP2. It searches
372    the local exception table for a handler. If no one is found, it unwinds
373    stacks and continues searching the callers.
374
375 *******************************************************************************/
376
377         .ent    asm_handle_nat_exception
378
379 asm_handle_nat_exception:
380 L_asm_handle_exception_stack_loop:
381 #if SIZEOF_VOID_P == 8
382         aaddiu  sp,sp,-6*8                  /* keep stack 16-byte aligned         */
383         ast     xptr,0*8(sp)                /* save exception pointer             */
384         ast     xpc,1*8(sp)                 /* save exception pc                  */
385         ast     ra,3*8(sp)                  /* save RA                            */
386         ast     zero,4*8(sp)                /* save maybe-leaf flag (cleared)     */
387 #else
388         aaddiu  sp,sp,-(4*4+6*8)            /* allocate stack                     */
389         ast     xptr,4*4+0*8(sp)            /* save exception pointer             */
390         ast     xpc,4*4+1*8(sp)             /* save exception pc                  */
391         ast     ra,4*4+3*8(sp)              /* save return address                */
392         ast     zero,4*4+4*8(sp)            /* save maybe-leaf flag (cleared)     */
393 #endif
394
395         move    a0,ra                       /* pass RA                            */
396         jal     md_codegen_get_pv_from_pc   /* get PV from RA                     */
397
398 #if SIZEOF_VOID_P == 8
399         ast     v0,2*8(sp)                  /* save PV                            */
400
401         ald     a0,0*8(sp)                  /* pass xptr                          */
402         ald     a1,1*8(sp)                  /* pass xpc                           */
403         move    a2,v0                       /* pass PV                            */
404         aaddiu  a3,sp,6*8                   /* pass Java SP                       */
405 #else
406         ast     v0,4*4+2*8(sp)              /* save data segment pointer          */
407
408         ald     a0,4*4+0*8(sp)              /* pass exception pointer             */
409         ald     a1,4*4+1*8(sp)              /* pass exception pc                  */
410         move    a2,v0                       /* pass data segment pointer          */
411         aaddiu  a3,sp,(4*4+6*8)             /* pass Java stack pointer            */
412 #endif
413
414         b       L_asm_handle_exception_continue
415
416         .aent    asm_handle_exception
417
418 asm_handle_exception:
419         aaddiu  sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
420
421         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
422         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
423
424 #if SIZEOF_VOID_P == 8
425         aaddiu  sp,sp,-6*8                  /* allocate stack                     */
426         ast     xptr,0*8(sp)                /* save exception pointer             */
427         ast     pv,2*8(sp)                  /* save PV                            */
428         ast     ra,3*8(sp)                  /* save RA                            */
429         addu    t0,zero,1                   /* set maybe-leaf flag                */
430         ast     t0,4*8(sp)                  /* save maybe-leaf flag               */
431 #else
432         aaddiu  sp,sp,-(4*4+6*8)            /* allocate stack                     */
433         ast     xptr,4*4+0*8(sp)            /* save exception pointer             */
434         ast     xpc,4*4+1*8(sp)             /* save exception pc                  */
435         ast     pv,4*4+2*8(sp)              /* save data segment pointer          */
436         ast     ra,4*4+3*8(sp)              /* save return address                */
437         addu    t0,zero,1                   /* set maybe-leaf flag                */
438         ast     t0,4*4+4*8(sp)              /* save maybe-leaf flag               */
439 #endif
440
441         move    a0,xptr                     /* pass xptr                          */
442         move    a1,xpc                      /* pass xpc                           */
443         move    a2,pv                       /* pass PV                            */
444
445 #if SIZEOF_VOID_P == 8
446         aaddiu  a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java SP                       */
447 #else
448         aaddiu  a3,sp,4*4+(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer        */
449 #endif
450
451 L_asm_handle_exception_continue:
452         jal     exceptions_handle_exception
453         
454         beqz    v0,L_asm_handle_exception_not_catched
455
456         move    xpc,v0                      /* move handlerpc into xpc            */
457
458 #if SIZEOF_VOID_P == 8
459         ald     xptr,0*8(sp)                /* restore exception pointer          */
460         ald     pv,2*8(sp)                  /* restore PV                         */
461         ald     ra,3*8(sp)                  /* restore RA                         */
462         ald     t0,4*8(sp)                  /* get maybe-leaf flag                */
463         aaddiu  sp,sp,6*8                   /* free stackframe                    */
464 #else
465         ald     xptr,4*4+0*8(sp)            /* restore exception pointer          */
466         ald     pv,4*4+2*8(sp)              /* restore data segment pointer       */
467         ald     ra,4*4+3*8(sp)              /* restore return address             */
468         ald     t0,4*4+4*8(sp)              /* get maybe-leaf flag                */
469         aaddiu  sp,sp,4*4+6*8               /* free stackframe                    */
470 #endif
471         
472         beqz    t0,L_asm_handle_exception_no_leaf
473
474         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
475         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
476         
477         aaddiu  sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
478
479 L_asm_handle_exception_no_leaf:
480         jr      xpc                         /* jump to the handler                */
481
482 L_asm_handle_exception_not_catched:
483 #if SIZEOF_VOID_P == 8
484         ald     xptr,0*8(sp)                /* restore xptr                       */
485         ald     pv,2*8(sp)                  /* restore PV                         */
486         ald     ra,3*8(sp)                  /* restore RA                         */
487         ald     t0,4*8(sp)                  /* get maybe-leaf flag                */
488         aaddiu  sp,sp,6*8                   /* free stackframe                    */
489 #else
490         ald     xptr,4*4+0*8(sp)            /* restore xptr                       */
491         ald     pv,4*4+2*8(sp)              /* restore PV                         */
492         ald     ra,4*4+3*8(sp)              /* restore RA                         */
493         ald     t0,4*4+4*8(sp)              /* get maybe-leaf flag                */
494         aaddiu  sp,sp,4*4+6*8               /* free stackframe                    */
495 #endif
496         
497         beqz    t0,L_asm_handle_exception_no_leaf_stack
498
499         aaddiu  sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
500         move    t0,zero                     /* clear the maybe-leaf flag          */
501
502 L_asm_handle_exception_no_leaf_stack:
503         lw      t1,FrameSize(pv)            /* get frame size                     */
504         aaddu   t1,sp,t1                    /* pointer to save area               */
505
506         lw      t2,IsLeaf(pv)               /* is leaf procedure                  */
507         bnez    t2,L_asm_handle_exception_no_ra_restore
508
509         ald     ra,-1*8(t1)                 /* restore ra                         */
510         aaddiu  t1,t1,-8                    /* t1--                               */
511
512 L_asm_handle_exception_no_ra_restore:
513         move    xpc,ra                      /* the new xpc is ra                  */
514         lw      t2,IntSave(pv)              /* t1 = saved int register count      */
515         ala     t3,ex_int2                  /* t3 = current pc                    */
516         sll     t2,t2,2                     /* t2 = register count * 4            */
517         asubu   t3,t3,t2                    /* t3 = IntSave - 4 * register count  */
518         jr      t3                          /* jump to save position              */
519
520         ald     s0,-8*8(t1)
521         ald     s1,-7*8(t1)
522         ald     s2,-6*8(t1)
523         ald     s3,-5*8(t1)
524         ald     s4,-4*8(t1)
525         ald     s5,-3*8(t1)
526         ald     s6,-2*8(t1)
527         ald     s7,-1*8(t1)
528
529 ex_int2:
530         sll     t2,t2,1               /* t2 = register count * 4 * 2              */
531         asubu   t1,t1,t2              /* t1 = t0 - 8 * register count             */
532
533         lw      t2,FltSave(pv)        /* t2 = saved flt register count            */
534         ala     t3,ex_flt2            /* t3 = current pc                          */
535         sll     t2,t2,2               /* t2 = register count * 4                  */
536         asubu   t3,t3,t2              /* t3 = ex_int_sav - 4 * register count     */
537         jr      t3                          /* jump to save position              */
538
539 #if SIZEOF_VOID_P == 8
540         ldc1    fs0,-4*8(t1)
541         ldc1    fs1,-3*8(t1)
542         ldc1    fs2,-2*8(t1)
543         ldc1    fs3,-1*8(t1)
544 #else /* SIZEOF_VOID_P == 8 */
545 # if !defined(ENABLE_SOFT_FLOAT)
546         ldc1    fs0,-4*8(t1)
547         ldc1    fs1,-3*8(t1)
548         ldc1    fs2,-2*8(t1)
549         ldc1    fs3,-1*8(t1)
550         ldc1    fs4,-1*8(t1)
551         ldc1    fs5,-1*8(t1)
552 # endif /* !defined(ENABLE_SOFT_FLOAT) */
553 #endif /* SIZEOF_VOID_P == 8 */
554
555 ex_flt2:
556         lw      t1,FrameSize(pv)            /* get frame size                     */
557         aaddu   sp,sp,t1                    /* unwind stack                       */
558         b       L_asm_handle_exception_stack_loop
559
560         .end    asm_handle_nat_exception
561
562
563 /* asm_abstractmethoderror *****************************************************
564
565    Creates and throws an AbstractMethodError.
566
567 *******************************************************************************/
568
569         .ent    asm_abstractmethoderror
570
571 asm_abstractmethoderror:
572         aaddiu  sp,sp,-2*8                  /* create stackframe                  */
573         ast     ra,0*8(sp)                  /* save return address                */
574         aaddiu  a0,sp,2*8                   /* pass java sp                       */
575         move    a1,ra                       /* pass exception address             */
576         jal     exceptions_asm_new_abstractmethoderror
577         ald     ra,0*8(sp)                  /* restore return address             */
578         aaddiu  sp,sp,2*8                   /* remove stackframe                  */
579
580         move    xptr,v0                     /* get exception pointer              */
581         aaddiu  xpc,ra,-4                   /* exception address is ra - 4        */
582         b       asm_handle_nat_exception
583
584         .end    asm_abstractmethoderror
585
586
587 #if defined(ENABLE_REPLACEMENT)
588                 
589 /* asm_replacement_out *********************************************************
590
591    This code is jumped to from the replacement-out stubs that are executed
592    when a thread reaches an activated replacement point.
593
594    The purpose of asm_replacement_out is to read out the parts of the
595    execution state that cannot be accessed from C code, store this state,
596    and then call the C function replace_me.
597
598    Stack layout:
599      16                 start of stack inside method to replace
600       0   rplpoint *    info on the replacement point that was reached
601
602    NOTE: itmp3 has been clobbered by the replacement-out stub!
603
604 *******************************************************************************/
605
606 /* some room to accomodate changes of the stack frame size during replacement */
607         /* XXX we should find a cleaner solution here */
608 #define REPLACEMENT_ROOM  512
609
610 #define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
611
612         .ent asm_replacement_out
613
614 asm_replacement_out:
615     /* create stack frame */
616         aaddiu  sp,sp,-REPLACEMENT_STACK_OFFSET
617
618         /* save registers in execution state */
619         ast     $0 ,( 0*8+offes_intregs)(sp)
620         ast     $1 ,( 1*8+offes_intregs)(sp)
621         ast     $2 ,( 2*8+offes_intregs)(sp)
622         ast     $3 ,( 3*8+offes_intregs)(sp)
623         ast     $4 ,( 4*8+offes_intregs)(sp)
624         ast     $5 ,( 5*8+offes_intregs)(sp)
625         ast     $6 ,( 6*8+offes_intregs)(sp)
626         ast     $7 ,( 7*8+offes_intregs)(sp)
627         ast     $8 ,( 8*8+offes_intregs)(sp)
628         ast     $9 ,( 9*8+offes_intregs)(sp)
629         ast     $10,(10*8+offes_intregs)(sp)
630         ast     $11,(11*8+offes_intregs)(sp)
631         ast     $12,(12*8+offes_intregs)(sp)
632         ast     $13,(13*8+offes_intregs)(sp)
633         ast     $14,(14*8+offes_intregs)(sp)
634         ast     $15,(15*8+offes_intregs)(sp)
635         ast     $16,(16*8+offes_intregs)(sp)
636         ast     $17,(17*8+offes_intregs)(sp)
637         ast     $18,(18*8+offes_intregs)(sp)
638         ast     $19,(19*8+offes_intregs)(sp)
639         ast     $20,(20*8+offes_intregs)(sp)
640         ast     $21,(21*8+offes_intregs)(sp)
641         ast     $22,(22*8+offes_intregs)(sp)
642         ast     $23,(23*8+offes_intregs)(sp)
643         ast     $24,(24*8+offes_intregs)(sp)
644         ast     $25,(25*8+offes_intregs)(sp)
645         ast     $26,(26*8+offes_intregs)(sp)
646         ast     $27,(27*8+offes_intregs)(sp)
647         ast     $28,(28*8+offes_intregs)(sp)
648         ast     $29,(29*8+offes_intregs)(sp)
649         ast     $30,(30*8+offes_intregs)(sp)
650         ast     $31,(31*8+offes_intregs)(sp)
651
652 #if SIZEOF_VOID_P == 8
653
654         sdc1    $f0 ,( 0*8+offes_fltregs)(sp)
655         sdc1    $f1 ,( 1*8+offes_fltregs)(sp)
656         sdc1    $f2 ,( 2*8+offes_fltregs)(sp)
657         sdc1    $f3 ,( 3*8+offes_fltregs)(sp)
658         sdc1    $f4 ,( 4*8+offes_fltregs)(sp)
659         sdc1    $f5 ,( 5*8+offes_fltregs)(sp)
660         sdc1    $f6 ,( 6*8+offes_fltregs)(sp)
661         sdc1    $f7 ,( 7*8+offes_fltregs)(sp)
662         sdc1    $f8 ,( 8*8+offes_fltregs)(sp)
663         sdc1    $f9 ,( 9*8+offes_fltregs)(sp)
664         sdc1    $f10,(10*8+offes_fltregs)(sp)
665         sdc1    $f11,(11*8+offes_fltregs)(sp)
666         sdc1    $f12,(12*8+offes_fltregs)(sp)
667         sdc1    $f13,(13*8+offes_fltregs)(sp)
668         sdc1    $f14,(14*8+offes_fltregs)(sp)
669         sdc1    $f15,(15*8+offes_fltregs)(sp)
670         sdc1    $f16,(16*8+offes_fltregs)(sp)
671         sdc1    $f17,(17*8+offes_fltregs)(sp)
672         sdc1    $f18,(18*8+offes_fltregs)(sp)
673         sdc1    $f19,(19*8+offes_fltregs)(sp)
674         sdc1    $f20,(20*8+offes_fltregs)(sp)
675         sdc1    $f21,(21*8+offes_fltregs)(sp)
676         sdc1    $f22,(22*8+offes_fltregs)(sp)
677         sdc1    $f23,(23*8+offes_fltregs)(sp)
678         sdc1    $f24,(24*8+offes_fltregs)(sp)
679         sdc1    $f25,(25*8+offes_fltregs)(sp)
680         sdc1    $f26,(26*8+offes_fltregs)(sp)
681         sdc1    $f27,(27*8+offes_fltregs)(sp)
682         sdc1    $f28,(28*8+offes_fltregs)(sp)
683         sdc1    $f29,(29*8+offes_fltregs)(sp)
684         sdc1    $f30,(30*8+offes_fltregs)(sp)
685         sdc1    $f31,(31*8+offes_fltregs)(sp)
686
687 #else /* SIZEOF_VOID_P == 8 */
688
689         sdc1    $f0 ,( 0*8+offes_fltregs)(sp)
690         sdc1    $f2 ,( 2*8+offes_fltregs)(sp)
691         sdc1    $f4 ,( 4*8+offes_fltregs)(sp)
692         sdc1    $f6 ,( 6*8+offes_fltregs)(sp)
693         sdc1    $f8 ,( 8*8+offes_fltregs)(sp)
694         sdc1    $f10,(10*8+offes_fltregs)(sp)
695         sdc1    $f12,(12*8+offes_fltregs)(sp)
696         sdc1    $f14,(14*8+offes_fltregs)(sp)
697         sdc1    $f16,(16*8+offes_fltregs)(sp)
698         sdc1    $f18,(18*8+offes_fltregs)(sp)
699         sdc1    $f20,(20*8+offes_fltregs)(sp)
700         sdc1    $f22,(22*8+offes_fltregs)(sp)
701         sdc1    $f24,(24*8+offes_fltregs)(sp)
702         sdc1    $f26,(26*8+offes_fltregs)(sp)
703         sdc1    $f28,(28*8+offes_fltregs)(sp)
704         sdc1    $f30,(30*8+offes_fltregs)(sp)
705
706 #endif /* SIZEOF_VOID_P == 8 */
707         
708         /* calculate sp of method */
709         aaddiu  itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
710         ast     itmp1,(offes_sp)(sp)
711
712         /* store pv */
713         ast     pv,(offes_pv)(sp)
714
715         /* call replace_me */
716         ald     a0,-(2*8)(itmp1)            /* arg0: rplpoint *                   */
717     move    a1,sp                       /* arg1: execution state              */
718     jal     replace_me                  /* call C function replace_me         */
719         jal     abort                       /* NEVER REACHED                      */
720
721         .end asm_replacement_out
722
723 /* asm_replacement_in **********************************************************
724
725    This code writes the given execution state and jumps to the replacement
726    code.
727
728    This function never returns!
729
730    NOTE: itmp3 is not restored!
731
732    C prototype:
733       void asm_replacement_in(executionstate *es);
734
735 *******************************************************************************/
736
737         .ent asm_replacement_in
738         
739 asm_replacement_in:
740         /* a0 == executionstate *es */
741
742         /* set new sp and pv */
743         ald     sp,(offes_sp)(a0)
744         ald     pv,(offes_pv)(a0)
745         
746         /* copy registers from execution state */
747         /* $0 is zero                     */
748         ald     $1 ,( 1*8+offes_intregs)(a0)
749         ald     $2 ,( 2*8+offes_intregs)(a0)
750         ald     $3 ,( 2*8+offes_intregs)(a0)
751         /* a0 is loaded below             */
752         ald     $5 ,( 5*8+offes_intregs)(a0)
753         ald     $6 ,( 6*8+offes_intregs)(a0)
754         ald     $7 ,( 7*8+offes_intregs)(a0)
755         ald     $8 ,( 8*8+offes_intregs)(a0)
756         ald     $9 ,( 9*8+offes_intregs)(a0)
757         ald     $10,(10*8+offes_intregs)(a0)
758         ald     $11,(11*8+offes_intregs)(a0)
759         ald     $12,(12*8+offes_intregs)(a0)
760         ald     $13,(13*8+offes_intregs)(a0)
761         ald     $14,(14*8+offes_intregs)(a0)
762         ald     $15,(15*8+offes_intregs)(a0)
763         ald     $16,(16*8+offes_intregs)(a0)
764         ald     $17,(17*8+offes_intregs)(a0)
765         ald     $18,(18*8+offes_intregs)(a0)
766         ald     $19,(19*8+offes_intregs)(a0)
767         ald     $20,(20*8+offes_intregs)(a0)
768         ald     $21,(21*8+offes_intregs)(a0)
769         ald     $22,(22*8+offes_intregs)(a0)
770         ald     $23,(23*8+offes_intregs)(a0)
771         ald     $24,(24*8+offes_intregs)(a0)
772         ald     $25,(25*8+offes_intregs)(a0)
773         ald     $26,(26*8+offes_intregs)(a0)
774         ald     $27,(27*8+offes_intregs)(a0)
775         ald     $28,(28*8+offes_intregs)(a0)
776         /* $29 is sp                      */
777         /* $30 is pv                      */
778         ald     $31,(31*8+offes_intregs)(a0)
779         
780 #if SIZEOF_VOID_P == 8
781
782         ldc1    $f0 ,( 0*8+offes_fltregs)(a0)
783         ldc1    $f1 ,( 1*8+offes_fltregs)(a0)
784         ldc1    $f2 ,( 2*8+offes_fltregs)(a0)
785         ldc1    $f3 ,( 3*8+offes_fltregs)(a0)
786         ldc1    $f4 ,( 4*8+offes_fltregs)(a0)
787         ldc1    $f5 ,( 5*8+offes_fltregs)(a0)
788         ldc1    $f6 ,( 6*8+offes_fltregs)(a0)
789         ldc1    $f7 ,( 7*8+offes_fltregs)(a0)
790         ldc1    $f8 ,( 8*8+offes_fltregs)(a0)
791         ldc1    $f9 ,( 9*8+offes_fltregs)(a0)
792         ldc1    $f10,(10*8+offes_fltregs)(a0)
793         ldc1    $f11,(11*8+offes_fltregs)(a0)
794         ldc1    $f12,(12*8+offes_fltregs)(a0)
795         ldc1    $f13,(13*8+offes_fltregs)(a0)
796         ldc1    $f14,(14*8+offes_fltregs)(a0)
797         ldc1    $f15,(15*8+offes_fltregs)(a0)
798         ldc1    $f16,(16*8+offes_fltregs)(a0)
799         ldc1    $f17,(17*8+offes_fltregs)(a0)
800         ldc1    $f18,(18*8+offes_fltregs)(a0)
801         ldc1    $f19,(19*8+offes_fltregs)(a0)
802         ldc1    $f20,(20*8+offes_fltregs)(a0)
803         ldc1    $f21,(21*8+offes_fltregs)(a0)
804         ldc1    $f22,(22*8+offes_fltregs)(a0)
805         ldc1    $f23,(23*8+offes_fltregs)(a0)
806         ldc1    $f24,(24*8+offes_fltregs)(a0)
807         ldc1    $f25,(25*8+offes_fltregs)(a0)
808         ldc1    $f26,(26*8+offes_fltregs)(a0)
809         ldc1    $f27,(27*8+offes_fltregs)(a0)
810         ldc1    $f28,(28*8+offes_fltregs)(a0)
811         ldc1    $f29,(29*8+offes_fltregs)(a0)
812         ldc1    $f30,(30*8+offes_fltregs)(a0)
813         ldc1    $f31,(31*8+offes_fltregs)(a0)
814
815 #else /* SIZEOF_VOID_P == 8 */
816
817         ldc1    $f0 ,( 0*8+offes_fltregs)(a0)
818         ldc1    $f2 ,( 2*8+offes_fltregs)(a0)
819         ldc1    $f4 ,( 4*8+offes_fltregs)(a0)
820         ldc1    $f6 ,( 6*8+offes_fltregs)(a0)
821         ldc1    $f8 ,( 8*8+offes_fltregs)(a0)
822         ldc1    $f10,(10*8+offes_fltregs)(a0)
823         ldc1    $f12,(12*8+offes_fltregs)(a0)
824         ldc1    $f14,(14*8+offes_fltregs)(a0)
825         ldc1    $f16,(16*8+offes_fltregs)(a0)
826         ldc1    $f18,(18*8+offes_fltregs)(a0)
827         ldc1    $f20,(20*8+offes_fltregs)(a0)
828         ldc1    $f22,(22*8+offes_fltregs)(a0)
829         ldc1    $f24,(24*8+offes_fltregs)(a0)
830         ldc1    $f26,(26*8+offes_fltregs)(a0)
831         ldc1    $f28,(28*8+offes_fltregs)(a0)
832         ldc1    $f30,(30*8+offes_fltregs)(a0)
833
834 #endif /* SIZEOF_VOID_P == 8 */
835
836         /* load new pc */
837
838         ald     itmp3,offes_pc(a0)
839
840         /* load a0 */
841         
842         ald     a0,(4*8+offes_intregs)(a0)
843
844         /* jump to new code */
845
846         jr      itmp3
847
848         .end asm_replacement_in
849
850 #endif /* defined(ENABLE_REPLACEMENT) */
851
852
853         .ent    compare_and_swap
854
855 compare_and_swap:
856 1:
857         all     v0,0(a0)
858         bne     v0,a1,2f
859         move    t0,a2
860         asc     t0,0(a0)
861         beqz    t0,1b
862 2:
863         sync
864         j       ra
865
866         .end    compare_and_swap
867
868
869 /* disable exec-stacks ********************************************************/
870
871 #if defined(__linux__) && defined(__ELF__)
872         .section .note.GNU-stack,"",%progbits
873 #endif
874
875
876 /*
877  * These are local overrides for various environment variables in Emacs.
878  * Please do not remove this and leave it at the end of the file, where
879  * Emacs will automagically detect them.
880  * ---------------------------------------------------------------------
881  * Local variables:
882  * mode: asm
883  * indent-tabs-mode: t
884  * c-basic-offset: 4
885  * tab-width: 4
886  * End:
887  * vim:noexpandtab:sw=4:ts=4:
888  */