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