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