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