GNU header update.
[cacao.git] / src / vm / jit / mips / asmpart.S
1 /* vm/jit/mips/asmpart.S - Java-C interface functions for mips
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28
29    $Id: asmpart.S 1735 2004-12-07 14:33:27Z twisti $
30
31 */
32
33
34 #include "config.h"
35 #include "vm/jit/mips/offsets.h"
36 #include "vm/jit/mips/asmoffsets.h"
37
38
39 #define zero    $0
40 #define itmp1   $1
41 #define v0      $2
42 #define itmp2   $3
43 #define a0      $4
44 #define a1      $5
45 #define a2      $6
46 #define a3      $7
47
48 #define a4      $8
49 #define a5      $9
50 #define a6      $10
51 #define a7      $11
52 #define t0      $12
53 #define t1      $13
54 #define t2      $14
55 #define t3      $15
56
57 #define s0      $16
58 #define s1      $17
59 #define s2      $18
60 #define s3      $19
61 #define s4      $20
62 #define s5      $21
63 #define s6      $22
64 #define s7      $23
65
66 #define t8      $24
67 #define itmp3   $25
68 #define k0      $26
69 #define k1      $27
70
71 #define gp      $28
72 #define sp      $29
73 #define s8      $30
74 #define ra      $31
75
76 #define pv      s8
77 #define t9      itmp3
78
79 #define xptr    itmp1
80 #define xpc     itmp2
81 #define mptr    itmp3
82 #define mptrreg 25
83
84 #define fv0     $f0
85 #define ft0     $f1
86 #define ft1     $f2
87 #define ft2     $f3
88 #define ft3     $f4
89 #define ft4     $f5
90 #define ft5     $f6
91 #define ft6     $f7
92
93 #define ft7     $f8
94 #define ft8     $f9
95 #define ft9     $f10
96 #define ft10    $f11
97 #define fa0     $f12
98 #define fa1     $f13
99 #define fa2     $f14
100 #define fa3     $f15
101
102 #define fa4     $f16
103 #define fa5     $f17
104 #define fa6     $f18
105 #define fa7     $f19
106 #define ft11    $f20
107 #define ft12    $f21
108 #define ft13    $f22
109 #define ft14    $f23
110
111 #define fs0     $f24
112 #define ft15    $f25
113 #define fs1     $f26
114 #define ft16    $f27
115 #define fs2     $f28
116 #define ft17    $f29
117 #define fs3     $f30
118 #define ft18    $f31
119
120 #define fss0    $f20
121 #define fss1    $f22
122 #define fss2    $f25
123 #define fss3    $f27
124 #define fss4    $f29
125 #define fss5    $f31
126
127 #define aaddu   daddu
128 #define asubu   dsubu
129 #define aaddiu  daddiu
130 #define ald     ld
131 #define ast     sd
132 #define ala     dla
133 #define asll    dsll
134 #define ashift  3
135
136
137         .text
138         .set    noat
139
140
141 /********************* exported functions and variables ***********************/
142
143         .globl asm_calljavafunction
144         .globl asm_calljavafunction2
145         .globl asm_calljavafunction2long
146         .globl asm_calljavafunction2double
147         .globl asm_call_jit_compiler
148         .globl asm_dumpregistersandcall
149         .globl asm_handle_exception
150         .globl asm_handle_nat_exception
151         .globl asm_check_clinit
152         .globl asm_builtin_checkarraycast
153         .globl asm_builtin_checkcast
154         .globl asm_builtin_aastore
155         .globl asm_builtin_monitorenter
156         .globl asm_builtin_monitorexit
157         .globl asm_builtin_idiv
158         .globl asm_builtin_irem
159         .globl asm_builtin_ldiv
160         .globl asm_builtin_lrem
161         .globl asm_perform_threadswitch
162         .globl asm_initialize_thread_stack
163         .globl asm_switchstackandcall
164         .globl asm_builtin_trace
165         .globl asm_builtin_exittrace
166         .globl asm_getclassvalues_atomic
167         .globl asm_criticalsections
168
169         .globl compare_and_swap
170
171
172 /*************************** imported functions *******************************/
173
174         .globl jit_compile
175         .globl _exceptionptr
176         .globl builtin_monitorexit
177         .globl builtin_throw_exception
178         .globl builtin_trace_exception
179         .globl class_java_lang_Object
180
181
182 /********************* function asm_calljavafunction ***************************
183 *                                                                              *
184 *   This function calls a Java-method (which possibly needs compilation)       *
185 *   with up to 4 address parameters.                                           *
186 *                                                                              *
187 *   This functions calls the JIT-compiler which eventually translates the      *
188 *   method into machine code.                                                  *
189 *                                                                              *
190 *   A possibly throwed exception will be returned to the caller as function    *
191 *   return value, so the java method cannot return a fucntion value (this      *
192 *   function usually calls 'main' and '<clinit>' which do not return a         *
193 *   function value).                                                           *
194 *                                                                              *
195 *   C-prototype:                                                               *
196 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
197 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
198 *                                                                              *
199 *******************************************************************************/
200
201         .ent    asm_calljavafunction
202
203 call_name:
204         .align  3
205
206         .dword  0                         /* catch type all                       */
207         .dword  calljava_xhandler         /* handler pc                           */
208         .dword  calljava_xhandler         /* end pc                               */
209         .dword  asm_calljavafunction      /* start pc                             */
210         .word   1                         /* extable size                         */
211         .word   0                         /* fltsave                              */
212         .word   0                         /* intsave                              */
213         .word   0                         /* isleaf                               */
214         .word   0                         /* IsSync                               */
215         .word   10*8                      /* frame size                           */
216         .dword  0                         /* method pointer (pointer to name)     */
217
218 asm_calljavafunction:
219         aaddiu  sp,sp,-10*8               /* allocate stack space                 */
220         sd      ra,0(sp)                  /* save return address                  */
221
222         .set    noreorder
223         bal     call_java_pc
224         sd      pv,3*8(sp)                /* procedure vector                     */
225 call_java_pc:
226         aaddiu  pv,ra,-4*4
227
228         .set    reorder
229         
230         sdc1    fss0,4*8(sp)              /* save non JavaABI saved flt registers */
231         sdc1    fss1,5*8(sp)
232         sdc1    fss2,6*8(sp)
233         sdc1    fss3,7*8(sp)
234         sdc1    fss4,8*8(sp)
235         sdc1    fss5,9*8(sp)
236         sd      a0,2*8(sp)                /* save method pointer for compiler     */
237         aaddiu  itmp1,sp,16               /* pass pointer to methodptr via itmp1  */
238
239         move    a0,a1                     /* pass the remaining parameters        */
240         move    a1,a2
241         move    a2,a3
242         move    a3,a4
243
244         ala     mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
245         ast     mptr,1*8(sp)              /* store function address               */
246         move    mptr,sp                   /* set method pointer                   */
247
248         .set    noreorder
249         
250         ald     pv,1*8(mptr)              /* method call as in Java               */
251         jalr    pv                        /* call JIT compiler                    */
252         nop
253         aaddiu  pv,ra,-23*4               /* recompute procedure vector           */
254 #if 0
255         move    v0,zero                   /* clear return value (exception ptr)   */
256 #else
257         nop
258 #endif
259
260 calljava_return:
261         ld      ra,0(sp)                  /* restore return address               */
262         ld      pv,3*8(sp)                /* restore procedure vector             */
263
264         ldc1    fss0,4*8(sp)              /* restore non JavaABI saved flt regs   */
265         ldc1    fss1,5*8(sp)
266         ldc1    fss2,6*8(sp)
267         ldc1    fss3,7*8(sp)
268         ldc1    fss4,8*8(sp)
269         ldc1    fss5,9*8(sp)
270         j       ra                        /* return                               */
271         aaddiu  sp,sp,10*8                /* free stack space                     */
272
273         .set    reorder
274         
275 calljava_xhandler:
276         move    a0,itmp1                  
277         jal     builtin_throw_exception
278         b       calljava_return
279
280         .end    asm_calljavafunction
281
282
283         .ent    asm_calljavafunction2
284
285 call_name2:
286         .align  3
287
288         .dword  0                         /* catch type all                       */
289         .dword  calljava_xhandler2        /* handler pc                           */
290         .dword  calljava_xhandler2        /* end pc                               */
291         .dword  asm_calljavafunction2     /* start pc                             */
292         .word   1                         /* extable size                         */
293         .word   0                         /* fltsave                              */
294         .word   1                         /* intsave                              */
295         .word   0                         /* isleaf                               */
296         .word   0                         /* IsSync                               */
297         .word   12*8                      /* frame size                           */
298         .dword  0                         /* method pointer (pointer to name)     */
299
300 asm_calljavafunction2:
301 asm_calljavafunction2double:
302 asm_calljavafunction2long:
303         aaddiu  sp,sp,-12*8               /* allocate stack space (only 11 needed)*/
304         sd      ra,0(sp)                  /* save return address                  */
305
306         .set    noreorder
307         bal     call_java_pc2
308         sd      pv,1*8(sp)                /* procedure vector                     */
309 call_java_pc2:
310         aaddiu  pv,ra,-4*4
311         sd      s7,3*8(sp)
312
313         .set    reorder
314         
315         sdc1    fss0,5*8(sp)              /* save non JavaABI saved flt registers */
316         sdc1    fss1,6*8(sp)
317         sdc1    fss2,7*8(sp)
318         sdc1    fss3,8*8(sp)
319         sdc1    fss4,9*8(sp)
320         sdc1    fss5,10*8(sp)
321         sd      a0,4*8(sp)                /* save method pointer for compiler     */
322         move    t0,a3
323         move    s7,a1
324
325         blez    s7,calljava_argsloaded
326         ald     a0,offjniitem(t0)
327         ldc1    fa0,offjniitem(t0)
328         daddi   s7,s7,-1
329         blez    s7,calljava_argsloaded
330
331         ald     a1,offjniitem+sizejniblock*1(t0)
332         ldc1    fa1,offjniitem+sizejniblock*1(t0)
333         daddi   s7,s7,-1
334         blez    s7,calljava_argsloaded
335
336         ald     a2,offjniitem+sizejniblock*2(t0)
337         ldc1    fa2,offjniitem+sizejniblock*2(t0)
338         daddi   s7,s7,-1
339         blez    s7,calljava_argsloaded
340
341         ald     a3,offjniitem+sizejniblock*3(t0)
342         ldc1    fa3,offjniitem+sizejniblock*3(t0)
343         daddi   s7,s7,-1
344         blez    s7,calljava_argsloaded
345
346         ald     a4,offjniitem+sizejniblock*4(t0)
347         ldc1    fa4,offjniitem+sizejniblock*4(t0)
348         daddi   s7,s7,-1
349         blez    s7,calljava_argsloaded
350
351         ald     a5,offjniitem+sizejniblock*5(t0)
352         ldc1    fa5,offjniitem+sizejniblock*5(t0)
353         daddi   s7,s7,-1
354         blez    s7,calljava_argsloaded
355
356         ald     a6,offjniitem+sizejniblock*6(t0)
357         ldc1    fa6,offjniitem+sizejniblock*6(t0)
358         daddi   s7,s7,-1
359         blez    s7,calljava_argsloaded
360
361         ald     a7,offjniitem+sizejniblock*7(t0)
362         ldc1    fa7,offjniitem+sizejniblock*7(t0)
363         daddi   s7,s7,-1
364                 
365 calljava_argsloaded:
366     move    t8,sp
367         blez    s7,calljava_nocopy
368         subu    t1,zero,s7
369         sll     t2,t1,3
370         daddu   sp,sp,t2
371         daddu   t2,t2,t8
372
373 calljava_copyloop:
374     ald     t3,offjniitem+sizejniblock*8(t0)
375         ast     t3,0(t2)
376         ala     t1,1(t1)
377         ala     t0,sizejniblock(t0)
378         ala     t2,8(t2)
379         bnez    t1,calljava_copyloop
380
381 calljava_nocopy:
382         ala     itmp1,32(t8)              /* pass pointer to methodptr via itmp1  */
383
384         ala     mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
385         ast     mptr,16(sp)               /* store function address               */
386         ala     mptr,8(t8)                /* set method pointer                   */
387
388         .set    noreorder
389         
390         ald     pv,8(mptr)                /* method call as in Java               */
391         jalr    pv                        /* call JIT compiler                    */
392         nop
393         aaddiu  pv,ra,-76*4               /* recompute procedure vector           */
394
395 calljava_return2:
396         ld      ra,0(sp)                  /* restore return address               */
397         ld      pv,8(sp)                  /* restore procedure vector             */
398         ld      s7,24(sp)
399
400         ldc1    fss0,5*8(sp)              /* restore non JavaABI saved flt regs   */
401         ldc1    fss1,6*8(sp)
402         ldc1    fss2,7*8(sp)
403         ldc1    fss3,8*8(sp)
404         ldc1    fss4,9*8(sp)
405         ldc1    fss5,10*8(sp)
406         j       ra                        /* return                               */
407         aaddiu  sp,sp,12*8                /* free stack space                     */
408
409         .set    reorder
410         
411 calljava_xhandler2:
412     sll     s7,s7,3
413         aaddu   sp,s7,sp
414         move    a0,itmp1                  
415         jal     builtin_throw_exception
416         b       calljava_return2
417
418         .end    asm_calljavafunction2
419
420
421 /****************** function asm_call_jit_compiler *****************************
422 *                                                                              *
423 *   invokes the compiler for untranslated JavaVM methods.                      *
424 *                                                                              *
425 *   Register REG_ITEMP1 contains a pointer to the method info structure        *
426 *   (prepared by createcompilerstub). Using the return address in R31 and the  *
427 *   offset in the LDA instruction or using the value in methodptr R25 the      *
428 *   patching address for storing the method address can be computed:           *
429 *                                                                              *
430 *   method address was either loaded using                                     *
431 *   M_ALD (REG_PV, REG_PV, a)        ; invokestatic/special    ($28)           *
432 *   M_JSR (REG_RA, REG_PV);                                                    *
433 *   M_NOP                                                                      *
434 *   M_LDA (REG_PV, REG_RA, val)                                                *
435 *   or                                                                         *
436 *   M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25)           *
437 *   M_JSR (REG_RA, REG_PV);                                                    *
438 *   M_NOP                                                                      *
439 *   in the static case the method pointer can be computed using the            *
440 *   return address and the lda function following the jmp instruction          *
441 *                                                                              *
442 *******************************************************************************/
443
444
445         .ent    asm_call_jit_compiler
446
447 asm_call_jit_compiler:
448         lw      t0,-12(ra)            /* load instruction LD PV,xxx($y)           */
449         srl     t0,t0,21              /* shift right register number $y           */
450         and     t0,t0,31              /* isolate register number                  */
451         addiu   t0,t0,-mptrreg        /* test for REG_METHODPTR                   */
452         beqz    t0,noregchange       
453
454         lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
455         sll     t0,t0,16
456         sra     t0,t0,16              /* isolate offset                           */
457         aaddu   mptr,t0,ra            /* compute update address                   */
458
459 noregchange:
460         aaddiu  sp,sp,-18*8           /* allocate stack space                     */
461         sd      a0,0*8(sp)            /* save all argument registers              */
462         sd      a1,1*8(sp)            /* they could be used by method             */
463         sd      a2,2*8(sp)
464         sd      a3,3*8(sp)
465         sd      a4,4*8(sp)
466         sd      a5,5*8(sp)
467         sd      a6,6*8(sp)
468         sd      a7,7*8(sp)
469         sdc1    fa0,8*8(sp)
470         sdc1    fa1,9*8(sp)
471         sdc1    fa2,10*8(sp)
472         sdc1    fa3,11*8(sp)
473         sdc1    fa4,12*8(sp)
474         sdc1    fa5,13*8(sp)
475         sdc1    fa6,14*8(sp)
476         sdc1    fa7,15*8(sp)
477         sd      mptr,16*8(sp)         /* save method pointer                      */
478         sd      ra,17*8(sp)           /* save return address                      */
479
480         ald     a0,0(itmp1)           /* pass 'methodinfo' pointer to             */
481         jal     jit_compile           /* jit compiler                             */
482
483         ld      a0,0*8(sp)            /* restore argument registers               */
484         ld      a1,1*8(sp)            /* they could be used by method             */
485         ld      a2,2*8(sp)
486         ld      a3,3*8(sp)
487         ld      a4,4*8(sp)
488         ld      a5,5*8(sp)
489         ld      a6,6*8(sp)
490         ld      a7,7*8(sp)
491         ldc1    fa0,8*8(sp)
492         ldc1    fa1,9*8(sp)
493         ldc1    fa2,10*8(sp)
494         ldc1    fa3,11*8(sp)
495         ldc1    fa4,12*8(sp)
496         ldc1    fa5,13*8(sp)
497         ldc1    fa6,14*8(sp)
498         ldc1    fa7,15*8(sp)
499         ld      mptr,16*8(sp)         /* restore method pointer                   */
500         ld      ra,17*8(sp)           /* restore return address                   */
501         aaddiu  sp,sp,18*8            /* deallocate stack area                    */
502
503         lw      t0,-12(ra)            /* load instruction LDQ PV,xxx($yy)         */
504         sll     t0,t0,16
505         sra     t0,t0,16              /* isolate offset                           */
506
507         aaddu   t0,t0,mptr            /* compute update address via method pointer*/
508         ast     v0,0(t0)              /* save new method address there            */
509
510         move    pv,v0                 /* move method address into pv              */
511
512         jr      pv                    /* and call method. The method returns      */
513                                       /* directly to the caller (ra).             */
514
515         .end    asm_call_jit_compiler
516
517
518 /********************* function asm_handle_exception ***************************
519 *                                                                              *
520 *   This function handles an exception. It does not use the usual calling      *
521 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
522 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
523 *   the local exception table for a handler. If no one is found, it unwinds    *
524 *   stacks and continues searching the callers.                                *
525 *                                                                              *
526 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
527 *                                                                              *
528 *******************************************************************************/
529
530         .ent    asm_handle_nat_exception
531
532 asm_handle_nat_exception:
533         lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
534         sll     t0,t0,16
535         sra     t0,t0,16              /* isolate offset                           */
536         aaddu   pv,t0,ra              /* compute update address                   */
537
538         .aent    asm_handle_exception
539
540 asm_handle_exception:
541         aaddiu  sp,sp,-14*8           /* allocate stack                           */
542         sd      v0,0*8(sp)            /* save possible used registers             */
543         sd      t0,1*8(sp)            /* also registers used by trace_exception   */
544         sd      t1,2*8(sp)
545         sd      t2,3*8(sp)
546         sd      t3,4*8(sp)
547         sd      t8,5*8(sp)
548         sd      a0,6*8(sp)
549         sd      a1,7*8(sp)
550         sd      a2,8*8(sp)
551         sd      a3,9*8(sp)
552         sd      a4,10*8(sp)
553         sd      a5,11*8(sp)
554         sd      a6,12*8(sp)
555         sd      a7,13*8(sp)
556
557         addu    t3,zero,1             /* set no unwind flag                       */
558 ex_stack_loop:
559         aaddiu  sp,sp,-6*8            /* allocate stack                           */
560         sd      xptr,0*8(sp)          /* save used registers                      */
561         sd      xpc,1*8(sp)
562         sd      pv,2*8(sp)
563         sd      ra,3*8(sp)
564         sd      t3,4*8(sp)
565
566         move    a0,xptr
567         ald     a1,MethodPointer(pv)
568         move    a2,xpc
569 /*      move    a3,t3 */
570         move    a3,zero
571         addu    a4,zero,1
572         jal     builtin_trace_exception /* trace_exception(xptr,methodptr)        */
573         
574         ld      xptr,0*8(sp)          /* restore used register                    */
575         ld      xpc,1*8(sp)
576         ld      pv,2*8(sp)
577         ld      ra,3*8(sp)
578         ld      t3,4*8(sp)
579         aaddiu  sp,sp,6*8             /* deallocate stack                         */
580         
581         lw      t0,ExTableSize(pv)    /* t0 = exception table size                */
582         beqz    t0,empty_table        /* if empty table skip                      */
583         aaddiu  t1,pv,ExTableStart    /* t1 = start of exception table            */
584
585 ex_table_loop:
586         ald     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
587         sle     t2,t2,xpc             /* t2 = (startpc <= xpc)                    */
588         beqz    t2,ex_table_cont      /* if (false) continue                      */
589         ald     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
590         slt     t2,xpc,t2             /* t2 = (xpc < endpc)                       */
591         beqz    t2,ex_table_cont      /* if (false) continue                      */
592         ald     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
593         beqz    a1,ex_handle_it       /* NULL catches everything                  */
594
595         lw      itmp3,offclassloaded(a1)
596         bnez    itmp3,L_class_loaded
597
598         aaddiu  sp,sp,-8*8            /* allocate stack                           */
599         sd      t0,0*8(sp)            /* save used register                       */
600         sd      t1,1*8(sp)
601         sd      t3,2*8(sp)
602         sd      xptr,3*8(sp)
603         sd      xpc,4*8(sp)
604         sd      pv,5*8(sp)
605         sd      ra,6*8(sp)
606         sd      a1,7*8(sp)
607                 
608         move    a0,a1
609         jal     class_load
610                 
611         ld      t0,0*8(sp)            /* restore used register                    */
612         ld      t1,1*8(sp)
613         ld      t3,2*8(sp)
614         ld      xptr,3*8(sp)
615         ld      xpc,4*8(sp)
616         ld      pv,5*8(sp)
617         ld      ra,6*8(sp)
618         ld      a1,7*8(sp)
619         aaddiu  sp,sp,8*8             /* deallocate stack                         */
620         
621 L_class_loaded:
622         lw      itmp3,offclasslinked(a1)
623         aaddiu  sp,sp,-8*8            /* allocate stack                           */
624         sd      a1,7*8(sp)
625         bnez    itmp3,L_class_linked
626
627         sd      t0,0*8(sp)            /* save used register                       */
628         sd      t1,1*8(sp)
629         sd      t3,2*8(sp)
630         sd      xptr,3*8(sp)
631         sd      xpc,4*8(sp)
632         sd      pv,5*8(sp)
633         sd      ra,6*8(sp)
634                 
635         move    a0,a1
636         jal     class_link
637                 
638         ld      t0,0*8(sp)            /* restore used register                    */
639         ld      t1,1*8(sp)
640         ld      t3,2*8(sp)
641         ld      xptr,3*8(sp)
642         ld      xpc,4*8(sp)
643         ld      pv,5*8(sp)
644         ld      ra,6*8(sp)
645
646 L_class_linked:
647 _crit_restart1:
648         ld      a1,7*8(sp)
649 _crit_begin1:
650         ald     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
651         ald     a1,offclassvftbl(a1)  /* a1 = vftblptr(catchtype) class (not obj) */
652         lw      a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
653         lw      v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
654         lw      a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
655 _crit_end1:
656         subu    a0,a0,v0              /* a0 = baseval(xptr) - baseval(catchtype)  */
657         sltu    v0,a1,a0              /* v0 = xptr is instanceof catchtype        */
658         aaddiu  sp,sp,8*8             /* deallocate stack                         */
659         bnez    v0,ex_table_cont      /* if (false) continue                      */
660
661 ex_handle_it:
662         ald     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
663
664         beqz    t3,ex_jump            /* if (!(no stack unwinding) skip           */
665
666         ld      v0,0*8(sp)            /* restore possible used registers          */
667         ld      t0,1*8(sp)            /* also registers used by trace_exception   */
668         ld      t1,2*8(sp)
669         ld      t2,3*8(sp)
670         ld      t3,4*8(sp)
671         ld      t8,5*8(sp)
672         ld      a0,6*8(sp)
673         ld      a1,7*8(sp)
674         ld      a2,8*8(sp)
675         ld      a3,9*8(sp)
676         ld      a4,10*8(sp)
677         ld      a5,11*8(sp)
678         ld      a6,12*8(sp)
679         ld      a7,13*8(sp)
680         
681         aaddiu  sp,sp,14*8            /* deallocate stack                         */
682
683 ex_jump:
684         jr      xpc                   /* jump to the handler                      */
685
686 ex_table_cont:
687         aaddiu  t1,t1,ExEntrySize     /* next exception table entry               */
688         addiu   t0,t0,-1              /* decrement entry counter                  */
689         bgtz    t0,ex_table_loop      /* if (t0 > 0) next entry                   */
690
691 empty_table:
692         beqz    t3,ex_already_cleared /* if here the first time, then             */
693         aaddiu  sp,sp,14*8            /* deallocate stack and                     */
694         move    t3,zero               /* clear the no unwind flag                 */
695 ex_already_cleared:
696         lw      t0,IsSync(pv)         /* t0 = SyncOffset                          */
697         beqz    t0,no_monitor_exit    /* if zero no monitorexit                   */
698         aaddu   t0,sp,t0              /* add stackptr to Offset                   */
699         ald     a0,-8(t0)             /* load monitorexit pointer                 */
700
701         aaddiu  sp,sp,-8*8            /* allocate stack                           */
702         sd      t0,0*8(sp)            /* save used register                       */
703         sd      t1,1*8(sp)
704         sd      t3,2*8(sp)
705         sd      xptr,3*8(sp)
706         sd      xpc,4*8(sp)
707         sd      pv,5*8(sp)
708         sd      ra,6*8(sp)
709
710         jal     builtin_monitorexit   /* builtin_monitorexit(objectptr)           */
711         
712         ld      t0,0*8(sp)            /* restore used register                    */
713         ld      t1,1*8(sp)
714         ld      t3,2*8(sp)
715         ld      xptr,3*8(sp)
716         ld      xpc,4*8(sp)
717         ld      pv,5*8(sp)
718         ld      ra,6*8(sp)
719         aaddiu  sp,sp,8*8             /* deallocate stack                         */
720
721 no_monitor_exit:
722         lw      t0,FrameSize(pv)      /* t0 = frame size                          */
723         aaddu   sp,sp,t0              /* unwind stack                             */
724         move    t0,sp                 /* t0 = pointer to save area                */
725         lw      t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
726         bnez    t1,ex_no_restore      /* if (leaf) skip                           */
727         ld      ra,-8(t0)             /* restore ra                               */
728         aaddiu  t0,t0,-8              /* t0--                                     */
729 ex_no_restore:
730         move    xpc,ra                /* the new xpc is ra                        */
731         lw      t1,IntSave(pv)        /* t1 = saved int register count            */
732         ala     t2,ex_int2            /* t2 = current pc                          */
733         sll     t1,t1,2               /* t1 = register count * 4                  */
734         asubu   t2,t2,t1              /* t2 = ex_int_sav - 4 * register count     */
735         jr      t2                    /* jump to save position                    */
736         ld      s0,-8*8(t0)
737         ld      s1,-7*8(t0)
738         ld      s2,-6*8(t0)
739         ld      s3,-5*8(t0)
740         ld      s4,-4*8(t0)
741         ld      s5,-3*8(t0)
742         ld      s6,-2*8(t0)
743         ld      s7,-1*8(t0)
744 ex_int2:
745         sll     t1,t1,1               /* t1 = register count * 4 * 2              */
746         asubu   t0,t0,t1              /* t0 = t0 - 8 * register count             */
747
748         lw      t1,FltSave(pv)        /* t1 = saved flt register count            */
749         ala     t2,ex_flt2            /* t2 = current pc                          */
750         sll     t1,t1,2               /* t1 = register count * 4                  */
751         asubu   t2,t2,t1              /* t2 = ex_int_sav - 4 * register count     */
752         jr      t2                    /* jump to save position                    */
753         ldc1    fs0,-4*8(t0)
754         ldc1    fs1,-3*8(t0)
755         ldc1    fs2,-2*8(t0)
756         ldc1    fs3,-1*8(t0)
757 ex_flt2:
758         lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
759         sll     t0,t0,16
760         sra     t0,t0,16              /* isolate offset                           */
761         aaddu   pv,t0,ra              /* compute update address                   */
762         b       ex_stack_loop
763
764         .end    asm_handle_nat_exception
765
766
767 /********************* asm_check_clinit ****************************************
768 *                                                                              *
769 *   Checks if class is initialized. If not, do it right now.                   *
770 *                                                                              *
771 *******************************************************************************/
772                 
773     .ent    asm_check_clinit
774
775 asm_check_clinit:
776         daddiu  sp,sp,-24*8
777
778         sd      ra,0*8(sp)            /* save return address                      */
779
780         sd      a0,1*8(sp)            /* save argument registers for leaf funcs   */
781         sd      a1,2*8(sp)
782         sd      a2,3*8(sp)
783         sd      a3,4*8(sp)
784         sd      a4,5*8(sp)
785         sd      a5,6*8(sp)
786         sd      a6,7*8(sp)
787         sd      a7,8*8(sp)
788
789         sd      t0,9*8(sp)
790         sd      t1,10*8(sp)
791         sd      t2,11*8(sp)
792         sd      t3,12*8(sp)
793         sd      t8,13*8(sp)
794
795         sdc1    fa0,14*8(sp)
796         sdc1    fa1,15*8(sp)
797         sdc1    fa2,16*8(sp)
798         sdc1    fa3,17*8(sp)
799         sdc1    fa4,18*8(sp)
800         sdc1    fa5,19*8(sp)
801         sdc1    fa6,20*8(sp)
802         sdc1    fa7,21*8(sp)
803
804         sd      itmp2,22*8(sp)        /* save machine code                        */
805
806                                       /* check if class is initialized            */
807         lw      itmp3,offclassinit(itmp1)
808         bnez    itmp3,L_is_initialized
809         
810         move    a0,itmp1              /* move class pointer to a0                 */
811         jal     class_init
812                 
813         beqz    v0,L_initializererror
814
815 L_is_initialized:
816         ld      ra,0*8(sp)            /* get return address                       */
817         ld      itmp1,22*8(sp)        /* get machine code                         */
818
819         daddiu  ra,ra,-2*4            /* go back 2 instructions (jal + nop delay) */
820         sw      itmp1,0(ra)           /* patch first instruction                  */
821         dsrl32  itmp1,itmp1,0         /* get high 32 bit                          */
822         sw      itmp1,4(ra)           /* patch second instruction                 */
823
824         move    a0,ra                 /* start of flush area                      */
825         addiu   a1,zero,2*4           /* 2 instruction words long                 */
826         jal     docacheflush          /* flush!                                   */
827         
828         ld      ra,0*8(sp)            /* restore return address                   */
829
830         ld      a0,1*8(sp)            /* restore argument registers               */
831         ld      a1,2*8(sp)
832         ld      a2,3*8(sp)
833         ld      a3,4*8(sp)
834         ld      a4,5*8(sp)
835         ld      a5,6*8(sp)
836         ld      a6,7*8(sp)
837         ld      a7,8*8(sp)
838
839         ld      t0,9*8(sp)
840         ld      t1,10*8(sp)
841         ld      t2,11*8(sp)
842         ld      t3,12*8(sp)
843         ld      t8,13*8(sp)
844
845         ldc1    fa0,14*8(sp)
846         ldc1    fa1,15*8(sp)
847         ldc1    fa2,16*8(sp)
848         ldc1    fa3,17*8(sp)
849         ldc1    fa4,18*8(sp)
850         ldc1    fa5,19*8(sp)
851         ldc1    fa6,20*8(sp)
852         ldc1    fa7,21*8(sp)
853
854         daddiu  sp,sp,24*8
855
856         daddiu  ra,ra,-2*4            /* go back 2 instructions (jal + nop delay) */
857         jr      ra
858
859 L_initializererror:
860 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
861         jal     builtin_asm_get_exceptionptrptr
862 #else
863         la      v0,_exceptionptr
864 #endif
865         ld      xptr,0(v0)            /* get the exception pointer                */
866         sd      zero,0(v0)            /* clear the exception pointer              */
867
868         ld      ra,0*8(sp)            /* restore return address                   */
869
870         ld      a0,1*8(sp)            /* restore argument registers               */
871         ld      a1,2*8(sp)
872         ld      a2,3*8(sp)
873         ld      a3,4*8(sp)
874         ld      a4,5*8(sp)
875         ld      a5,6*8(sp)
876         ld      a6,7*8(sp)
877         ld      a7,8*8(sp)
878
879         ld      t0,9*8(sp)
880         ld      t1,10*8(sp)
881         ld      t2,11*8(sp)
882         ld      t3,12*8(sp)
883         ld      t8,13*8(sp)
884
885         ldc1    fa0,14*8(sp)
886         ldc1    fa1,15*8(sp)
887         ldc1    fa2,16*8(sp)
888         ldc1    fa3,17*8(sp)
889         ldc1    fa4,18*8(sp)
890         ldc1    fa5,19*8(sp)
891         ldc1    fa6,20*8(sp)
892         ldc1    fa7,21*8(sp)
893
894         daddiu  sp,sp,24*8
895
896         aaddiu  xpc,ra,-4             /* faulting address is return adress - 4    */
897         b       asm_handle_exception
898
899         .end    asm_check_clinit
900
901                 
902 /********************* function asm_builtin_monitorenter ***********************
903 *                                                                              *
904 *   Does null check and calls monitorenter or throws an exception              *
905 *                                                                              *
906 *******************************************************************************/
907
908         .ent    asm_builtin_monitorenter
909
910 asm_builtin_monitorenter:
911         beqz    a0,nb_monitorenter        /* if (null) throw exception            */
912         ala     t9,builtin_monitorenter   /* else call builtin_monitorenter       */
913         j       t9
914
915 nb_monitorenter:
916         daddiu  sp,sp,-2*8
917         sd      ra,0*8(sp)
918         ald     a0,string_java_lang_NullPointerException
919         jal     new_exception
920         move    xptr,v0
921         ld      ra,0*8(sp)
922         daddiu  sp,sp,2*8
923
924         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
925         b       asm_handle_nat_exception
926
927         .end    asm_builtin_monitorenter
928
929
930 /********************* function asm_builtin_monitorexit ************************
931 *                                                                              *
932 *   Does null check and calls monitorexit or throws an exception               *
933 *                                                                              *
934 *******************************************************************************/
935
936         .ent    asm_builtin_monitorexit
937
938 asm_builtin_monitorexit:
939         beqz    a0,nb_monitorexit         /* if (null) throw exception            */
940         ala     t9,builtin_monitorexit    /* else call builtin_monitorexit        */
941         j       t9
942
943 nb_monitorexit:
944         daddiu  sp,sp,-2*8
945         sd      ra,0*8(sp)
946         jal     new_nullpointerexception
947         move    xptr,v0
948         ld      ra,0*8(sp)
949         daddiu  sp,sp,2*8
950
951         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
952         b       asm_handle_nat_exception
953
954         .end    asm_builtin_monitorexit
955
956
957 /************************ function asm_builtin_idiv ****************************
958 *                                                                              *
959 *   Does null check and calls idiv or throws an exception                      *
960 *                                                                              *
961 *******************************************************************************/
962
963         .ent    asm_builtin_idiv
964
965 asm_builtin_idiv:
966         beqz    a1,nb_idiv                /* if (null) throw exception            */
967         ala     itmp3,builtin_idiv        /* else call builtin_idiv               */
968         j       itmp3
969
970 nb_idiv:
971         daddiu  sp,sp,-2*8
972         sd      ra,0*8(sp)
973         jal     new_arithmeticexception
974         move    xptr,v0
975         ld      ra,0*8(sp)
976         daddiu  sp,sp,2*8
977
978         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
979         b       asm_handle_nat_exception
980
981         .end    asm_builtin_idiv
982
983
984 /************************ function asm_builtin_ldiv ****************************
985 *                                                                              *
986 *   Does null check and calls ldiv or throws an exception                      *
987 *                                                                              *
988 *******************************************************************************/
989
990         .ent    asm_builtin_ldiv
991
992 asm_builtin_ldiv:
993         beqz    a1,nb_ldiv                /* if (null) throw exception            */
994         ala     itmp3,builtin_ldiv        /* else call builtin_ldiv               */
995         j       itmp3
996
997 nb_ldiv:
998         daddiu  sp,sp,-2*8
999         sd      ra,0*8(sp)
1000         jal     new_arithmeticexception
1001         move    xptr,v0
1002         ld      ra,0*8(sp)
1003         daddiu  sp,sp,2*8
1004
1005         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
1006         b       asm_handle_nat_exception
1007
1008         .end    asm_builtin_ldiv
1009
1010
1011 /************************ function asm_builtin_irem ****************************
1012 *                                                                              *
1013 *   Does null check and calls irem or throws an exception                      *
1014 *                                                                              *
1015 *******************************************************************************/
1016
1017         .ent    asm_builtin_irem
1018
1019 asm_builtin_irem:
1020         beqz    a1,nb_irem                /* if (null) throw exception            */
1021         ala     t9,builtin_irem           /* else call builtin_irem               */
1022         j       t9
1023
1024 nb_irem:
1025         daddiu  sp,sp,-2*8
1026         sd      ra,0*8(sp)
1027         jal     new_arithmeticexception
1028         move    xptr,v0
1029         ld      ra,0*8(sp)
1030         daddiu  sp,sp,2*8
1031
1032         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
1033         b       asm_handle_nat_exception
1034
1035         .end    asm_builtin_irem
1036
1037
1038 /************************ function asm_builtin_lrem ****************************
1039 *                                                                              *
1040 *   Does null check and calls lrem or throws an exception                      *
1041 *                                                                              *
1042 *******************************************************************************/
1043
1044         .ent    asm_builtin_lrem
1045
1046 asm_builtin_lrem:
1047         beqz    a1,nb_lrem                /* if (null) throw exception            */
1048         ala     t9,builtin_lrem           /* else call builtin_lrem               */
1049         j       t9
1050
1051 nb_lrem:
1052         daddiu  sp,sp,-2*8
1053         sd      ra,0*8(sp)
1054         jal     new_arithmeticexception
1055         move    xptr,v0
1056         ld      ra,0*8(sp)
1057         daddiu  sp,sp,2*8
1058
1059         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
1060         b       asm_handle_nat_exception
1061
1062         .end    asm_builtin_lrem
1063
1064
1065 /******************* function asm_builtin_checkarraycast ***********************
1066 *                                                                              *
1067 *   Does the cast check and eventually throws an exception                     *
1068 *                                                                              *
1069 *******************************************************************************/
1070
1071         .ent    asm_builtin_checkarraycast
1072
1073 asm_builtin_checkarraycast:
1074         aaddiu  sp,sp,-16                 /* allocate stack space                 */
1075         sd      ra,0(sp)                  /* save return address                  */
1076         sd      a0,8(sp)                  /* save object pointer                  */
1077         jal     builtin_checkarraycast    /* builtin_checkarraycast               */
1078         beqz    v0,nb_carray_throw        /* if (false) throw exception           */
1079         ld      ra,0(sp)                  /* restore return address               */
1080         ld      v0,8(sp)                  /* return object pointer                */
1081         aaddiu  sp,sp,16                  /* deallocate stack                     */
1082         j       ra                        /* return                               */
1083
1084 nb_carray_throw:
1085         jal     new_classcastexception
1086         move    xptr,v0
1087
1088         ld      ra,0(sp)                  /* restore return address               */
1089         aaddiu  sp,sp,16                  /* free stack space                     */
1090         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
1091         b       asm_handle_nat_exception
1092
1093         .end    asm_builtin_checkarraycast
1094
1095
1096 /********************* function asm_builtin_checkcast **************************
1097 *                                                                              *
1098 *   Does the cast check and eventually throws an exception                     *
1099 *                                                                              *
1100 *******************************************************************************/
1101
1102         .ent    asm_builtin_checkcast
1103
1104 asm_builtin_checkcast:
1105         aaddiu  sp,sp,-16                 /* allocate stack space                 */
1106         sd      ra,0(sp)                  /* save return address                  */
1107         sd      a0,8(sp)                  /* save object pointer                  */
1108         jal     builtin_checkcast         /* builtin_checkcast                    */
1109         beqz    v0,nb_ccast_throw         /* if (false) throw exception           */
1110         ld      ra,0(sp)                  /* restore return address               */
1111         ld      v0,8(sp)                  /* return object pointer                */
1112         aaddiu  sp,sp,16                  /* deallocate stack                     */
1113         j       ra                        /* return                               */
1114
1115 nb_ccast_throw:
1116         jal     new_classcastexception
1117         move    xptr,v0
1118
1119         ld      ra,0(sp)                  /* restore return address               */
1120         aaddiu  sp,sp,16                  /* free stack space                     */
1121         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
1122         b       asm_handle_nat_exception
1123
1124         .end    asm_builtin_checkcast
1125
1126
1127 /******************* function asm_builtin_aastore ******************************
1128 *                                                                              *
1129 *   Does the cast check and eventually throws an exception                     *
1130 *   a0 = arrayref, a1 = index, a2 = value                                      *
1131 *                                                                              *
1132 *******************************************************************************/
1133
1134         .ent    asm_builtin_aastore
1135
1136 asm_builtin_aastore:
1137         beqz    a0,nb_aastore_null        /* if null pointer throw exception      */
1138         lw      t0,offarraysize(a0)       /* load size                            */
1139         aaddiu  sp,sp,-32                 /* allocate stack space                 */
1140         sd      ra,0(sp)                  /* save return address                  */
1141         asll    t1,a1,ashift              /* add index*8 to arrayref              */
1142         aaddu   t1,a0,t1                  /* add index * ashift to arrayref       */
1143         sltu    t0,a1,t0                  /* do bound check                       */
1144         beqz    t0,nb_aastore_bound       /* if out of bounds throw exception     */
1145         move    a1,a2                     /* object is second argument            */
1146         sd      t1,8(sp)                  /* save store position                  */
1147         sd      a1,16(sp)                 /* save object                          */
1148         jal     builtin_canstore          /* builtin_canstore(arrayref,object)    */
1149         ld      ra,0(sp)                  /* restore return address               */
1150         ld      a0,8(sp)                  /* restore store position               */
1151         ld      a1,16(sp)                 /* restore object                       */
1152         aaddiu  sp,sp,32                  /* free stack space                     */
1153         beqz    v0,nb_aastore_store       /* if (false) throw exception           */
1154         ast     a1,offobjarrdata(a0)      /* store objectptr in array             */
1155         j       ra                        /* return                               */
1156
1157 nb_aastore_null:
1158         daddiu  sp,sp,-2*8
1159         sd      ra,0*8(sp)
1160         jal     new_nullpointerexception
1161         move    xptr,v0
1162         ld      ra,0*8(sp)
1163         daddiu  sp,sp,2*8
1164         
1165         move    xpc,ra                    /* faulting address is return adress    */
1166         b       asm_handle_nat_exception
1167
1168 nb_aastore_bound:
1169         daddiu  sp,sp,-2*8
1170         sd      ra,0*8(sp)
1171         move    a0,a1                     /* move index into a0                   */
1172         jal     new_arrayindexoutofboundsexception
1173         move    xptr,v0
1174         ld      ra,0*8(sp)
1175         daddiu  sp,sp,2*8
1176
1177         aaddiu  sp,sp,32                  /* free stack space                     */
1178         move    xpc,ra                    /* faulting address is return adress    */
1179         b       asm_handle_nat_exception
1180
1181 nb_aastore_store:
1182         daddiu  sp,sp,-2*8
1183         sd      ra,0*8(sp)
1184         jal     new_arraystoreexception
1185         move    xptr,v0
1186         ld      ra,0*8(sp)
1187         daddiu  sp,sp,2*8
1188
1189         move    xpc,ra                    /* faulting address is return adress    */
1190         b       asm_handle_nat_exception
1191
1192         .end    asm_builtin_aastore
1193
1194
1195 /******************* function asm_initialize_thread_stack **********************
1196 *                                                                              *
1197 *   u1* asm_initialize_thread_stack (void *func, u1 *stack);                   *
1198 *                                                                              *
1199 *   initialize a thread stack                                                  *
1200 *                                                                              *
1201 *******************************************************************************/
1202
1203         .ent    asm_initialize_thread_stack
1204
1205 asm_initialize_thread_stack:
1206         aaddiu  a1,a1,-14*8     /* allocate save area                             */
1207         sd      zero, 0*8(a1)   /* s0 initalize thread area                       */
1208         sd      zero, 1*8(a1)   /* s1                                             */
1209         sd      zero, 2*8(a1)   /* s2                                             */
1210         sd      zero, 3*8(a1)   /* s3                                             */
1211         sd      zero, 4*8(a1)   /* s4                                             */
1212         sd      zero, 5*8(a1)   /* s5                                             */
1213         sd      zero, 6*8(a1)   /* s6                                             */
1214         sd      zero, 7*8(a1)   /* s7                                             */
1215         sd      zero, 8*8(a1)   /* s8                                             */
1216         sd      zero, 9*8(a1)   /* fs0                                            */
1217         sd      zero,10*8(a1)   /* fs1                                            */
1218         sd      zero,11*8(a1)   /* fs2                                            */
1219         sd      zero,12*8(a1)   /* fs3                                            */
1220         sd      a0, 13*8(a1)
1221         move    v0,a1
1222         j       ra              /* return                                         */
1223
1224         .end    asm_initialize_thread_stack
1225
1226
1227 /******************* function asm_perform_threadswitch *************************
1228 *                                                                              *
1229 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1230 *                                                                              *
1231 *   performs a threadswitch                                                    *
1232 *                                                                              *
1233 *******************************************************************************/
1234
1235         .ent    asm_perform_threadswitch
1236
1237 asm_perform_threadswitch:
1238         aaddiu  sp,sp,-14*8     /* allocate new stack                             */
1239         sd      s0,  0*8(sp)    /* save saved registers of old thread             */
1240         sd      s1,  1*8(sp)
1241         sd      s2,  2*8(sp)
1242         sd      s3,  3*8(sp)
1243         sd      s4,  4*8(sp)
1244         sd      s5,  5*8(sp)
1245         sd      s6,  6*8(sp)
1246         sd      s7,  7*8(sp)
1247         sd      s8,  8*8(sp)
1248         sdc1    fs0, 9*8(sp)
1249         sdc1    fs1,10*8(sp)
1250         sdc1    fs2,11*8(sp)
1251         sdc1    fs3,12*8(sp)
1252         sd      ra, 13*8(sp)
1253         ast     sp,0(a0)        /* save old stack pointer                         */
1254         ast     sp,0(a2)        /* stackTop = old stack pointer                   */
1255         ald     sp,0(a1)        /* load new stack pointer                         */
1256         ld      s0,  0*8(sp)    /* load saved registers of new thread             */
1257         ld      s1,  1*8(sp)
1258         ld      s2,  2*8(sp)
1259         ld      s3,  3*8(sp)
1260         ld      s4,  4*8(sp)
1261         ld      s5,  5*8(sp)
1262         ld      s6,  6*8(sp)
1263         ld      s7,  7*8(sp)
1264         ld      s8,  8*8(sp)
1265         ldc1    fs0, 9*8(sp)
1266         ldc1    fs1,10*8(sp)
1267         ldc1    fs2,11*8(sp)
1268         ldc1    fs3,12*8(sp)
1269         ld      ra, 13*8(sp)
1270         aaddiu  sp,sp,14*8      /* deallocate new stack                           */
1271         move    itmp3, ra
1272         j       ra              /* return                                         */
1273
1274         .end    asm_perform_threadswitch
1275
1276
1277 /********************* function asm_switchstackandcall *************************
1278 *                                                                              *
1279 *  void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
1280 *                                                                              *
1281 *   Switches to a new stack, calls a function and switches back.               *
1282 *       a0      new stack pointer                                              *
1283 *       a1      function pointer                                               *
1284 *               a2              pointer to variable where stack top should be stored           *
1285 *                                                                              *
1286 *******************************************************************************/
1287
1288         .ent    asm_switchstackandcall
1289
1290 asm_switchstackandcall:
1291         aaddiu  a0,a0,-16       /* allocate new stack                             */
1292         sd      ra,0(a0)        /* save return address on new stack               */
1293         sd      sp,8(a0)        /* save old stack pointer on new stack            */
1294         sd      sp,0(a2)        /* save old stack pointer to variable             */
1295         move    sp,a0           /* switch to new stack                            */
1296         
1297         move    itmp3,a1
1298         move    a0,a3
1299         jalr    itmp3           /* and call function                              */
1300
1301         ld      ra,0(sp)        /* load return address                            */
1302         ld      sp,8(sp)        /* switch to old stack                            */
1303
1304         j       ra              /* return                                         */
1305
1306         .end    asm_switchstackandcall
1307
1308
1309         .ent    asm_getclassvalues_atomic
1310
1311 asm_getclassvalues_atomic:
1312 _crit_restart2:
1313 _crit_begin2:
1314         lw      t0,offbaseval(a0)
1315         lw      t1,offdiffval(a0)
1316         lw      t2,offbaseval(a1)
1317 _crit_end2:
1318         sw      t0,offcast_super_baseval(a2)
1319         sw      t1,offcast_super_diffval(a2)
1320         sw      t2,offcast_sub_baseval(a2)
1321         j       ra
1322
1323         .end    asm_getclassvalues_atomic
1324
1325     .data
1326
1327 asm_criticalsections:
1328 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1329     .dword  _crit_begin1
1330     .dword  _crit_end1
1331     .dword  _crit_restart1
1332     .dword  _crit_begin2
1333     .dword  _crit_end2
1334     .dword  _crit_restart2
1335 #endif
1336     .dword  0
1337
1338
1339         .text
1340
1341         .ent    compare_and_swap
1342 compare_and_swap:
1343 1:
1344         lld             v0,0(a0)
1345         bne             v0,a1,2f
1346         move    t0,a2
1347         scd             t0,0(a0)
1348         beqz    t0,1b
1349 2:
1350         sync
1351         j               ra
1352         .end    compare_and_swap
1353 /*
1354  * These are local overrides for various environment variables in Emacs.
1355  * Please do not remove this and leave it at the end of the file, where
1356  * Emacs will automagically detect them.
1357  * ---------------------------------------------------------------------
1358  * Local variables:
1359  * mode: asm
1360  * indent-tabs-mode: t
1361  * c-basic-offset: 4
1362  * tab-width: 4
1363  * End:
1364  */