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