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