c1b06d14e3dde7380ce2d3685061019c09e86cdb
[cacao.git] / mips / asmpart.S
1 /* -*- mode: asm; tab-width: 4 -*- */
2 /****************************** asmpart.c **************************************
3 *                                                                              *
4 *   is an assembly language file, but called .c to fake the preprocessor.      *
5 *   It contains the Java-C interface functions for Alpha processors.           *
6 *                                                                              *
7 *   Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst              *
8 *                                                                              *
9 *   See file COPYRIGHT for information on usage and disclaimer of warranties   *
10 *                                                                              *
11 *   Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at            *
12 *                                                                              *
13 *   Last Change: 1998/11/23                                                    *
14 *                                                                              *
15 *******************************************************************************/
16
17 #include "offsets.h"
18
19 #define zero    $0
20 #define itmp1   $1
21 #define v0      $2
22 #define itmp2   $3
23 #define a0      $4
24 #define a1      $5
25 #define a2      $6
26 #define a3      $7
27
28 #define a4      $8
29 #define a5      $9
30 #define a6      $10
31 #define a7      $11
32 #define t0      $12
33 #define t1      $13
34 #define t2      $14
35 #define t3      $15
36
37 #define s0      $16
38 #define s1      $17
39 #define s2      $18
40 #define s3      $19
41 #define s4      $20
42 #define s5      $21
43 #define s6      $22
44 #define s7      $23
45
46 #define t4      $24
47 #define itmp3   $25
48 #define k0      $26
49 #define k1      $27
50
51 #define gp      $28
52 #define sp      $29
53 #define s8      $30
54 #define ra      $31
55
56 #define pv      s8
57 #define t9      itmp3
58
59 #define xptr    itmp1
60 #define xpc     itmp2
61 #define mptr    itmp3
62 #define mptrreg 25
63
64 #define fv0     $f0
65 #define ft0     $f1
66 #define ft1     $f2
67 #define ft2     $f3
68 #define ft3     $f4
69 #define ft4     $f5
70 #define ft5     $f6
71 #define ft6     $f7
72
73 #define ft7     $f8
74 #define ft8     $f9
75 #define ft9     $f10
76 #define ft10    $f11
77 #define fa0     $f12
78 #define fa1     $f13
79 #define fa2     $f14
80 #define fa3     $f15
81
82 #define fa4     $f16
83 #define fa5     $f17
84 #define fa6     $f18
85 #define fa7     $f19
86 #define ft11    $f20
87 #define ft12    $f21
88 #define ft13    $f22
89 #define ft14    $f23
90
91 #define fs0     $f24
92 #define ft15    $f25
93 #define fs1     $f26
94 #define ft16    $f27
95 #define fs2     $f28
96 #define ft17    $f29
97 #define fs3     $f30
98 #define ft18    $f31
99
100 #define fss0    $f20
101 #define fss1    $f22
102 #define fss2    $f25
103 #define fss3    $f27
104 #define fss4    $f29
105 #define fss5    $f31
106
107 #define aaddu   daddu
108 #define asubu   dsubu
109 #define aaddiu  daddiu
110 #define ald     ld
111 #define ast     sd
112 #define ala     dla
113 #define asll    dsll
114 #define ashift  3
115
116 #define MethodPointer   -8
117 #define FrameSize       -12
118 #define IsSync          -16
119 #define IsLeaf          -20
120 #define IntSave         -24
121 #define FltSave         -28
122 #define ExTableSize     -32
123 #define ExTableStart    -32
124
125 #define ExEntrySize     -32
126 #define ExStartPC       -8
127 #define ExEndPC         -16
128 #define ExHandlerPC     -24
129 #define ExCatchType     -32
130
131
132         .text
133         .set    noat
134
135
136 /********************* exported functions and variables ***********************/
137
138         .globl has_no_x_instr_set
139         .globl synchronize_caches
140         .globl asm_calljavafunction
141         .globl asm_call_jit_compiler
142         .globl asm_dumpregistersandcall
143         .globl asm_handle_exception
144         .globl asm_handle_nat_exception
145         .globl asm_builtin_checkarraycast
146         .globl asm_builtin_checkcast
147         .globl asm_builtin_aastore
148         .globl asm_builtin_monitorenter
149         .globl asm_builtin_monitorexit
150         .globl asm_builtin_idiv
151         .globl asm_builtin_irem
152         .globl asm_builtin_ldiv
153         .globl asm_builtin_lrem
154         .globl asm_perform_threadswitch
155         .globl asm_initialize_thread_stack
156         .globl asm_switchstackandcall
157
158
159 /*************************** imported functions *******************************/
160
161         .globl jit_compile
162         .globl builtin_monitorexit
163         .globl builtin_throw_exception
164         .globl builtin_trace_exception
165         .globl class_java_lang_Object
166
167
168 /*********************** function has_no_x_instr_set ***************************
169 *                                                                              *
170 *   determines if the byte support instruction set (21164a and higher)         *
171 *   is available.                                                              *
172 *                                                                              *
173 *******************************************************************************/
174
175         .ent    has_no_x_instr_set
176 has_no_x_instr_set:
177
178         move    v0,zero                   /* result code 0 (not used for MIPS)    */
179         j       ra                        /* return                               */
180
181         .end    has_no_x_instr_set
182
183
184 /********************* function synchronize_caches ****************************/
185
186         .ent    synchronize_caches
187 synchronize_caches:
188
189 /*      li      a0,BCACHE          */     /* flush both caches                    */
190 /*      li      v0,SYS_cacheflush  */     /* Syscall number for cacheflush()      */
191 /*      syscall                    */     /* call cacheflush()                    */
192         j       ra                        /* return                               */
193
194         .end    synchronize_caches
195
196
197 #if 0
198
199 /********************* function asm_calljavafunction ****************************
200 *                                                                              *
201 *   This function calls a Java-method (which possibly needs compilation)       *
202 *   with up to 4 address parameters.                                           *
203 *                                                                              *
204 *   This functions calls the JIT-compiler which eventually translates the      *
205 *   method into machine code.                                                  *
206 *                                                                              *
207 *   A possibly throwed exception will be returned to the caller as function    *
208 *   return value, so the java method cannot return a fucntion value (this      *
209 *   function usually calls 'main' and '<clinit>' which do not return a         *
210 *   function value).                                                           *
211 *                                                                              *
212 *   C-prototype:                                                               *
213 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
214 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
215 *                                                                              *
216 *******************************************************************************/
217
218         .ent    asm_calljavafunction
219
220 call_name:
221
222         .ascii  "calljavafunction\0\0"
223
224         .align  3
225         .dword  0                         /* catch type all                       */
226         .dword  calljava_xhandler         /* handler pc                           */
227         .dword  calljava_xhandler         /* end pc                               */
228         .dword  asm_calljavafunction        /* start pc                             */
229         .word   1                         /* extable size                         */
230         .word   0                         /* fltsave                              */
231         .word   0                         /* intsave                              */
232         .word   0                         /* isleaf                               */
233         .word   0                         /* IsSync                               */
234         .word   80                        /* frame size                           */
235         .dword  0                         /* method pointer (pointer to name)     */
236
237 asm_calljavafunction:
238
239         aaddiu  sp,sp,-10*8               /* allocate stack space                 */
240         sd      ra,0(sp)                  /* save return address                  */
241
242         .set    noreorder
243         bal     call_java_pc
244         sd      pv,3*8(sp)                /* procedure vector                     */
245 call_java_pc:
246         aaddiu  pv,ra,-4*4
247
248         .set    reorder
249         
250         sdc1    fss0,4*8(sp)              /* save non JavaABI saved flt registers */
251         sdc1    fss1,5*8(sp)
252         sdc1    fss2,6*8(sp)
253         sdc1    fss3,7*8(sp)
254         sdc1    fss4,8*8(sp)
255         sdc1    fss5,9*8(sp)
256         sd      a0,2*8(sp)                /* save method pointer for compiler     */
257         aaddiu  itmp1,sp,16               /* pass pointer to methodptr via itmp1  */
258
259         move    a0,a1                     /* pass the remaining parameters        */
260         move    a1,a2
261         move    a2,a3
262         move    a3,a4
263
264         ala     mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
265         ast     mptr,1*8(sp)              /* store function address               */
266         move    mptr,sp                   /* set method pointer                   */
267
268         .set    noreorder
269         
270         ald     pv,1*8(mptr)              /* method call as in Java               */
271         jalr    pv                        /* call JIT compiler                    */
272         nop
273         aaddiu  pv,ra,-23*4               /* recompute procedure vector           */
274         move    v0,zero                   /* clear return value (exception ptr)   */
275
276         .set    reorder
277         
278 calljava_return:
279
280         ld      ra,0(sp)                  /* restore return address               */
281         ld      pv,3*8(sp)                /* restore procedure vector             */
282
283         ldc1    fss0,4*8(sp)              /* restore non JavaABI saved flt regs   */
284         ldc1    fss1,5*8(sp)
285         ldc1    fss2,6*8(sp)
286         ldc1    fss3,7*8(sp)
287         ldc1    fss4,8*8(sp)
288         ldc1    fss5,9*8(sp)
289         aaddiu  sp,sp,10*8                /* free stack space                     */
290         j       ra                        /* return                               */
291
292 calljava_xhandler:
293
294         move    a0,itmp1                  
295         jal     builtin_throw_exception
296         b       calljava_return
297
298         .end    asm_calljavafunction
299
300 #endif
301
302
303 /****************** function asm_call_jit_compiler *****************************
304 *                                                                              *
305 *   invokes the compiler for untranslated JavaVM methods.                      *
306 *                                                                              *
307 *   Register REG_ITEMP1 contains a pointer to the method info structure        *
308 *   (prepared by createcompilerstub). Using the return address in R31 and the  *
309 *   offset in the LDA instruction or using the value in methodptr R25 the      *
310 *   patching address for storing the method address can be computed:           *
311 *                                                                              *
312 *   method address was either loaded using                                     *
313 *   M_ALD (REG_PV, REG_PV, a)        ; invokestatic/special    ($28)           *
314 *   M_JSR (REG_RA, REG_PV);                                                    *
315 *   M_NOP                                                                      *
316 *   M_LDA (REG_PV, REG_RA, val)                                                *
317 *   or                                                                         *
318 *   M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25)           *
319 *   M_JSR (REG_RA, REG_PV);                                                    *
320 *   M_NOP                                                                      *
321 *   in the static case the method pointer can be computed using the            *
322 *   return address and the lda function following the jmp instruction          *
323 *                                                                              *
324 *******************************************************************************/
325
326
327         .ent    asm_call_jit_compiler
328 asm_call_jit_compiler:
329
330         lw      t0,-12(ra)            /* load instruction LD PV,xxx($y)           */
331         srl     t0,t0,21              /* shift right register number $y           */
332         and     t0,t0,31              /* isolate register number                  */
333         addiu   t0,t0,-mptrreg        /* test for REG_METHODPTR                   */
334         beqz    t0,noregchange       
335
336         lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
337         sll     t0,t0,16
338         sra     t0,t0,16              /* isolate offset                           */
339         aaddu   mptr,t0,ra            /* compute update address                   */
340
341 noregchange:
342
343         aaddiu  sp,sp,-18*8           /* allocate stack space                     */
344         sd      a0,0*8(sp)            /* save all argument registers              */
345         sd      a1,1*8(sp)            /* they could be used by method             */
346         sd      a2,2*8(sp)
347         sd      a3,3*8(sp)
348         sd      a4,4*8(sp)
349         sd      a5,5*8(sp)
350         sd      a6,6*8(sp)
351         sd      a7,7*8(sp)
352         sdc1    fa0,8*8(sp)
353         sdc1    fa1,9*8(sp)
354         sdc1    fa2,10*8(sp)
355         sdc1    fa3,11*8(sp)
356         sdc1    fa4,12*8(sp)
357         sdc1    fa5,13*8(sp)
358         sdc1    fa6,14*8(sp)
359         sdc1    fa7,15*8(sp)
360         sd      mptr,16*8(sp)         /* save method pointer                      */
361         sd      ra,17*8(sp)           /* save return address                      */
362
363         ald     a0,0(itmp1)           /* pass 'methodinfo' pointer to             */
364         jal     jit_compile           /* jit compiler                             */
365
366         ld      a0,0*8(sp)            /* restore argument registers               */
367         ld      a1,1*8(sp)            /* they could be used by method             */
368         ld      a2,2*8(sp)
369         ld      a3,3*8(sp)
370         ld      a4,4*8(sp)
371         ld      a5,5*8(sp)
372         ld      a6,6*8(sp)
373         ld      a7,7*8(sp)
374         ldc1    fa0,8*8(sp)
375         ldc1    fa1,9*8(sp)
376         ldc1    fa2,10*8(sp)
377         ldc1    fa3,11*8(sp)
378         ldc1    fa4,12*8(sp)
379         ldc1    fa5,13*8(sp)
380         ldc1    fa6,14*8(sp)
381         ldc1    fa7,15*8(sp)
382         ld      mptr,16*8(sp)         /* restore method pointer                   */
383         ld      ra,17*8(sp)           /* restore return address                      */
384         aaddiu  sp,sp,18*8            /* deallocate stack area                    */
385
386         lw      t0,-12(ra)            /* load instruction LDQ PV,xxx($yy)         */
387         sll     t0,t0,16
388         sra     t0,t0,16              /* isolate offset                           */
389
390         aaddu   t0,t0,mptr            /* compute update address via method pointer*/
391         ast     v0,0(t0)              /* save new method address there            */
392
393         move    pv,v0                 /* move method address into pv              */
394
395         jr      pv                    /* and call method. The method returns      */
396                                       /* directly to the caller (ra).             */
397
398         .end    asm_call_jit_compiler
399
400
401 /****************** function asm_dumpregistersandcall **************************
402 *                                                                              *
403 *   This funtion saves all callee saved (address) registers and calls the      *
404 *   function which is passed as parameter.                                     *
405 *                                                                              *
406 *   This function is needed by the garbage collector, which needs to access    *
407 *   all registers which are stored on the stack. Unused registers are          *
408 *   cleared to avoid interferances with the GC.                                *
409 *                                                                              *
410 *   void asm_dumpregistersandcall (functionptr f);                             *
411 *                                                                              *
412 *******************************************************************************/
413
414         .ent    asm_dumpregistersandcall
415 asm_dumpregistersandcall:
416         aaddiu  sp,sp,-10*8           /* allocate stack                           */
417         sd      ra,0(sp)              /* save return address                      */
418
419         sd      s0,1*8(sp)            /* save all callee saved registers          */
420         sd      s1,2*8(sp)
421         sd      s2,3*8(sp)
422         sd      s3,4*8(sp)
423         sd      s4,5*8(sp)
424         sd      s5,6*8(sp)
425         sd      s6,7*8(sp)
426         sd      s7,8*8(sp)
427         sd      s8,9*8(sp)
428
429         move    itmp3,a0
430         jalr    itmp3                 /* and call function                        */
431
432         ld      ra,0(sp)              /* restore return address                   */
433         aaddiu  sp,sp,10*8            /* deallocate stack                         */
434         j       ra                    /* return                                   */
435
436         .end    asm_dumpregistersandcall
437
438
439 /********************* function asm_handle_exception ***************************
440 *                                                                              *
441 *   This function handles an exception. It does not use the usual calling      *
442 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
443 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
444 *   the local exception table for a handler. If no one is found, it unwinds    *
445 *   stacks and continues searching the callers.                                *
446 *                                                                              *
447 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
448 *                                                                              *
449 *******************************************************************************/
450
451         .ent    asm_handle_nat_exception
452 asm_handle_nat_exception:
453
454         lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
455         sll     t0,t0,16
456         sra     t0,t0,16              /* isolate offset                           */
457         aaddu   pv,t0,ra              /* compute update address                   */
458
459         .aent    asm_handle_exception
460 asm_handle_exception:
461
462         aaddiu  sp,sp,-14*8           /* allocate stack                           */
463         sd      v0,0*8(sp)            /* save possible used registers             */
464         sd      t0,1*8(sp)            /* also registers used by trace_exception   */
465         sd      t1,2*8(sp)
466         sd      t2,3*8(sp)
467         sd      t3,4*8(sp)
468         sd      t4,5*8(sp)
469         sd      a0,6*8(sp)
470         sd      a1,7*8(sp)
471         sd      a2,8*8(sp)
472         sd      a3,9*8(sp)
473         sd      a4,10*8(sp)
474         sd      a5,11*8(sp)
475         sd      a6,12*8(sp)
476         sd      a7,13*8(sp)
477
478         addu    t3,zero,1             /* set no unwind flag                       */
479 ex_stack_loop:
480         aaddiu  sp,sp,-6*8            /* allocate stack                           */
481         sd      xptr,0*8(sp)          /* save used registers                      */
482         sd      xpc,1*8(sp)
483         sd      pv,2*8(sp)
484         sd      ra,3*8(sp)
485         sd      t3,4*8(sp)
486
487         move    a0,xptr
488         ald     a1,MethodPointer(pv)
489         move    a2,xpc
490         move    a3,t3
491         jal     builtin_trace_exception /* trace_exception(xptr,methodptr)        */
492         
493         ld      xptr,0*8(sp)          /* restore used register                    */
494         ld      xpc,1*8(sp)
495         ld      pv,2*8(sp)
496         ld      ra,3*8(sp)
497         ld      t3,4*8(sp)
498         aaddiu  sp,sp,6*8             /* deallocate stack                         */
499         
500         lw      t0,ExTableSize(pv)    /* t0 = exception table size                */
501         beqz    t0,empty_table        /* if empty table skip                      */
502         aaddiu  t1,pv,ExTableStart    /* t1 = start of exception table            */
503
504 ex_table_loop:
505         ald     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
506         slt     t2,t2,xpc             /* t2 = (xpc < startpc)                     */
507         beqz    t2,ex_table_cont      /* if (true) continue                       */
508         ald     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
509         slt     t2,t2,xpc             /* t2 = (xpc < endpc)                       */
510         bnez    t2,ex_table_cont      /* if (false) continue                      */
511         ald     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
512         beqz    a1,ex_handle_it       /* NULL catches everything                  */
513
514         ald     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
515         ald     a1,offobjvftbl(a1)    /* a1 = vftblptr(catchtype) class (not obj) */
516         lw      a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
517         lw      v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
518         lw      a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
519         subu    a0,a0,v0              /* a0 = baseval(xptr) - baseval(catchtype)  */
520         sltu    v0,a1,a0              /* v0 = xptr is instanceof catchtype        */
521         bnez    v0,ex_table_cont      /* if (false) continue                      */
522
523 ex_handle_it:
524
525         ald     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
526
527         beqz    t3,ex_jump            /* if (!(no stack unwinding) skip           */
528
529         ld      v0,0*8(sp)            /* restore possible used registers          */
530         ld      t0,1*8(sp)            /* also registers used by trace_exception   */
531         ld      t1,2*8(sp)
532         ld      t2,3*8(sp)
533         ld      t3,4*8(sp)
534         ld      t4,5*8(sp)
535         ld      a0,6*8(sp)
536         ld      a1,7*8(sp)
537         ld      a2,8*8(sp)
538         ld      a3,9*8(sp)
539         ld      a4,10*8(sp)
540         ld      a5,11*8(sp)
541         ld      a6,12*8(sp)
542         ld      a7,13*8(sp)
543         
544         aaddiu  sp,sp,14*8            /* deallocate stack                         */
545
546 ex_jump:
547         jr      xpc                   /* jump to the handler                      */
548
549 ex_table_cont:
550         aaddiu  t1,t1,ExEntrySize     /* next exception table entry               */
551         addiu   t0,t0,-1              /* decrement entry counter                  */
552         bgtz    t0,ex_table_loop      /* if (t0 > 0) next entry                   */
553
554 empty_table:
555         beqz    t3,ex_already_cleared /* if here the first time, then             */
556         aaddiu  sp,sp,14*8            /* deallocate stack and                     */
557         move    t3,zero               /* clear the no unwind flag                 */
558 ex_already_cleared:
559         lw      t0,IsSync(pv)         /* t0 = SyncOffset                          */
560         beqz    t0,no_monitor_exit    /* if zero no monitorexit                   */
561         aaddu   t0,sp,t0              /* add stackptr to Offset                   */
562         ald     a0,-8(t0)             /* load monitorexit pointer                 */
563
564         aaddiu  sp,sp,-8*8            /* allocate stack                           */
565         sd      t0,0*8(sp)            /* save used register                       */
566         sd      t1,1*8(sp)
567         sd      t3,2*8(sp)
568         sd      xptr,3*8(sp)
569         sd      xpc,4*8(sp)
570         sd      pv,5*8(sp)
571         sd      ra,6*8(sp)
572
573         jal     builtin_monitorexit   /* builtin_monitorexit(objectptr)           */
574         
575         ld      t0,0*8(sp)            /* restore used register                    */
576         ld      t1,1*8(sp)
577         ld      t3,2*8(sp)
578         ld      xptr,3*8(sp)
579         ld      xpc,4*8(sp)
580         ld      pv,5*8(sp)
581         ld      ra,6*8(sp)
582         aaddiu  sp,sp,8*8             /* deallocate stack                         */
583
584 no_monitor_exit:
585         lw      t0,FrameSize(pv)      /* t0 = frame size                          */
586         aaddu   sp,sp,t0              /* unwind stack                             */
587         move    t0,sp                 /* t0 = pointer to save area                */
588         lw      t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
589         bnez    t1,ex_no_restore      /* if (leaf) skip                           */
590         ld      ra,-8(t0)             /* restore ra                               */
591         aaddiu  t0,t0,-8              /* t0--                                     */
592 ex_no_restore:
593         move    xpc,ra                /* the new xpc is ra                        */
594         lw      t1,IntSave(pv)        /* t1 = saved int register count            */
595         ala     t2,ex_int2            /* t2 = current pc                          */
596         sll     t1,t1,2               /* t1 = register count * 4                  */
597         asubu   t2,t2,t1              /* t2 = ex_int_sav - 4 * register count     */
598         jr      t2                    /* jump to save position                    */
599         ld      s0,-8*8(t0)
600         ld      s1,-7*8(t0)
601         ld      s2,-6*8(t0)
602         ld      s3,-5*8(t0)
603         ld      s4,-4*8(t0)
604         ld      s5,-3*8(t0)
605         ld      s6,-2*8(t0)
606         ld      s7,-1*8(t0)
607 ex_int2:
608         sll     t1,t1,1               /* t1 = register count * 4 * 2              */
609         asubu   t0,t0,t1              /* t0 = t0 - 8 * register count             */
610
611         lw      t1,FltSave(pv)        /* t1 = saved flt register count            */
612         ala     t2,ex_flt2            /* t2 = current pc                          */
613         sll     t1,t1,2               /* t1 = register count * 4                  */
614         asubu   t2,t2,t1              /* t2 = ex_int_sav - 4 * register count     */
615         jr      t2                    /* jump to save position                    */
616         ldc1    fs0,-4*8(t0)
617         ldc1    fs1,-3*8(t0)
618         ldc1    fs2,-2*8(t0)
619         ldc1    fs3,-1*8(t0)
620 ex_flt2:
621         lw      t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
622         sll     t0,t0,16
623         sra     t0,t0,16              /* isolate offset                           */
624         aaddu   pv,t0,ra              /* compute update address                   */
625         b       ex_stack_loop
626
627         .end    asm_handle_nat_exception
628
629
630 /********************* function asm_builtin_monitorenter ***********************
631 *                                                                              *
632 *   Does null check and calls monitorenter or throws an exception              *
633 *                                                                              *
634 *******************************************************************************/
635
636         .ent    asm_builtin_monitorenter
637 asm_builtin_monitorenter:
638
639         beqz    a0,nb_monitorenter        /* if (null) throw exception            */
640         ala     t9,builtin_monitorenter   /* else call builtin_monitorenter       */
641         j       t9
642
643 nb_monitorenter:
644         ald     xptr,proto_java_lang_NullPointerException
645         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
646         b       asm_handle_nat_exception
647         .end    asm_builtin_monitorenter
648
649
650 /********************* function asm_builtin_monitorexit ************************
651 *                                                                              *
652 *   Does null check and calls monitorexit or throws an exception               *
653 *                                                                              *
654 *******************************************************************************/
655
656         .ent    asm_builtin_monitorexit
657 asm_builtin_monitorexit:
658
659         beqz    a0,nb_monitorexit         /* if (null) throw exception            */
660         ala     t9,builtin_monitorexit    /* else call builtin_monitorexit        */
661         j       t9
662
663 nb_monitorexit:
664         ald     xptr,proto_java_lang_NullPointerException
665         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
666         b       asm_handle_nat_exception
667         .end    asm_builtin_monitorexit
668
669
670 /************************ function asm_builtin_idiv ****************************
671 *                                                                              *
672 *   Does null check and calls idiv or throws an exception                      *
673 *                                                                              *
674 *******************************************************************************/
675
676         .ent    asm_builtin_idiv
677 asm_builtin_idiv:
678
679         beqz    a1,nb_idiv                /* if (null) throw exception            */
680         ala     itmp3,builtin_idiv        /* else call builtin_idiv               */
681         j       itmp3
682
683 nb_idiv:
684         ald     xptr,proto_java_lang_ArithmeticException
685         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
686         b       asm_handle_nat_exception
687         .end    asm_builtin_idiv
688
689
690 /************************ function asm_builtin_ldiv ****************************
691 *                                                                              *
692 *   Does null check and calls ldiv or throws an exception                      *
693 *                                                                              *
694 *******************************************************************************/
695
696         .ent    asm_builtin_ldiv
697 asm_builtin_ldiv:
698
699         beqz    a1,nb_ldiv                /* if (null) throw exception            */
700         ala     itmp3,builtin_ldiv        /* else call builtin_ldiv               */
701         j       itmp3
702
703 nb_ldiv:
704         ald     xptr,proto_java_lang_ArithmeticException
705         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
706         b       asm_handle_nat_exception
707         .end    asm_builtin_ldiv
708
709
710 /************************ function asm_builtin_irem ****************************
711 *                                                                              *
712 *   Does null check and calls irem or throws an exception                      *
713 *                                                                              *
714 *******************************************************************************/
715
716         .ent    asm_builtin_irem
717 asm_builtin_irem:
718
719         beqz    a1,nb_irem                /* if (null) throw exception            */
720         ala     t9,builtin_irem           /* else call builtin_irem               */
721         j       t9
722
723 nb_irem:
724         ald     xptr,proto_java_lang_ArithmeticException
725         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
726         b       asm_handle_nat_exception
727         .end    asm_builtin_irem
728
729
730 /************************ function asm_builtin_lrem ****************************
731 *                                                                              *
732 *   Does null check and calls lrem or throws an exception                      *
733 *                                                                              *
734 *******************************************************************************/
735
736         .ent    asm_builtin_lrem
737 asm_builtin_lrem:
738
739         beqz    a1,nb_lrem                /* if (null) throw exception            */
740         ala     t9,builtin_lrem           /* else call builtin_lrem               */
741         j       t9
742
743 nb_lrem:
744         ald     xptr,proto_java_lang_ArithmeticException
745         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
746         b       asm_handle_nat_exception
747         .end    asm_builtin_lrem
748
749
750 /******************* function asm_builtin_checkarraycast ***********************
751 *                                                                              *
752 *   Does the cast check and eventually throws an exception                     *
753 *                                                                              *
754 *******************************************************************************/
755
756         .ent    asm_builtin_checkarraycast
757 asm_builtin_checkarraycast:
758
759         aaddiu  sp,sp,-16                 /* allocate stack space                 */
760         sd      ra,0(sp)                  /* save return address                  */
761         sd      a0,8(sp)                  /* save object pointer                  */
762         jal     builtin_checkarraycast    /* builtin_checkarraycast               */
763         beqz    v0,nb_carray_throw        /* if (false) throw exception           */
764         ld      ra,0(sp)                  /* restore return address               */
765         ld      v0,8(sp)                  /* return object pointer                */
766         aaddiu  sp,sp,16                  /* deallocate stack                     */
767         j       ra                        /* return                               */
768
769 nb_carray_throw:
770         ald     xptr,proto_java_lang_ClassCastException
771         ld      ra,0(sp)                  /* restore return address               */
772         aaddiu  sp,sp,16                  /* free stack space                     */
773         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
774         b       asm_handle_nat_exception
775         .end    asm_builtin_checkarraycast
776
777
778 /********************* function asm_builtin_checkcast **************************
779 *                                                                              *
780 *   Does the cast check and eventually throws an exception                     *
781 *                                                                              *
782 *******************************************************************************/
783
784         .ent    asm_builtin_checkcast
785 asm_builtin_checkcast:
786
787         aaddiu  sp,sp,-16                 /* allocate stack space                 */
788         sd      ra,0(sp)                  /* save return address                  */
789         sd      a0,8(sp)                  /* save object pointer                  */
790         jal     builtin_checkcast         /* builtin_checkcast                    */
791         beqz    v0,nb_ccast_throw         /* if (false) throw exception           */
792         ld      ra,0(sp)                  /* restore return address               */
793         ld      v0,8(sp)                  /* return object pointer                */
794         aaddiu  sp,sp,16                  /* deallocate stack                     */
795         j       ra                        /* return                               */
796
797 nb_ccast_throw:
798         ald     xptr,proto_java_lang_ClassCastException
799         ld      ra,0(sp)                  /* restore return address               */
800         aaddiu  sp,sp,16                  /* free stack space                     */
801         aaddiu  xpc,ra,-4                 /* faulting address is return adress - 4*/
802         b       asm_handle_nat_exception
803         .end    asm_builtin_checkcast
804
805
806 /******************* function asm_builtin_aastore ******************************
807 *                                                                              *
808 *   Does the cast check and eventually throws an exception                     *
809 *   a0 = arrayref, a1 = index, a2 = value                                      *
810 *                                                                              *
811 *******************************************************************************/
812
813         .ent    asm_builtin_aastore
814 asm_builtin_aastore:
815
816         beqz    a0,nb_aastore_null        /* if null pointer throw exception      */
817         lw      t0,offarraysize(a0)       /* load size                            */
818         aaddiu  sp,sp,-32                 /* allocate stack space                 */
819         sd      ra,0(sp)                  /* save return address                  */
820         asll    t1,a1,ashift              /* add index*8 to arrayref              */
821         aaddu   t1,a0,t1                  /* add index * ashift to arrayref       */
822         sltu    t0,a1,t0                  /* do bound check                       */
823         beqz    t0,nb_aastore_bound       /* if out of bounds throw exception     */
824         move    a1,a2                     /* object is second argument            */
825         sd      t1,8(sp)                  /* save store position                  */
826         sd      a1,16(sp)                 /* save object                          */
827         jal     builtin_canstore          /* builtin_canstore(arrayref,object)    */
828         ld      ra,0(sp)                  /* restore return address               */
829         ld      a0,8(sp)                  /* restore store position               */
830         ld      a1,16(sp)                 /* restore object                       */
831         aaddiu  sp,sp,32                  /* free stack space                     */
832         beqz    v0,nb_aastore_throw       /* if (false) throw exception           */
833         ast     a1,offobjarrdata(a0)      /* store objectptr in array             */
834         j       ra                        /* return                               */
835
836 nb_aastore_null:
837         ald     xptr,proto_java_lang_NullPointerException
838         move    xpc,ra                    /* faulting address is return adress    */
839         b       asm_handle_nat_exception
840
841 nb_aastore_bound:
842         ald     xptr,proto_java_lang_ArrayIndexOutOfBoundsException
843         aaddiu  sp,sp,32                  /* free stack space                     */
844         move    xpc,ra                    /* faulting address is return adress    */
845         b       asm_handle_nat_exception
846
847 nb_aastore_throw:
848         ald     xptr,proto_java_lang_ArrayStoreException
849         move    xpc,ra                    /* faulting address is return adress    */
850         b       asm_handle_nat_exception
851
852         .end    asm_builtin_aastore
853
854
855 /******************* function asm_initialize_thread_stack **********************
856 *                                                                              *
857 *   u1* asm_initialize_thread_stack (void *func, u1 *stack);                   *
858 *                                                                              *
859 *   initialize a thread stack                                                  *
860 *                                                                              *
861 *******************************************************************************/
862
863         .ent    asm_initialize_thread_stack
864 asm_initialize_thread_stack:
865
866         aaddiu  a1,a1,-14*8     /* allocate save area                             */
867         sd      zero, 0*8(a1)   /* s0 initalize thread area                       */
868         sd      zero, 1*8(a1)   /* s1                                             */
869         sd      zero, 2*8(a1)   /* s2                                             */
870         sd      zero, 3*8(a1)   /* s3                                             */
871         sd      zero, 4*8(a1)   /* s4                                             */
872         sd      zero, 5*8(a1)   /* s5                                             */
873         sd      zero, 6*8(a1)   /* s6                                             */
874         sd      zero, 7*8(a1)   /* s7                                             */
875         sd      zero, 8*8(a1)   /* s8                                             */
876         sd      zero, 9*8(a1)   /* fs0                                            */
877         sd      zero,10*8(a1)   /* fs1                                            */
878         sd      zero,11*8(a1)   /* fs2                                            */
879         sd      zero,12*8(a1)   /* fs3                                            */
880         sd      a0, 13*8(a1)
881         move    v0,a1
882         j       ra              /* return                                         */
883         .end    asm_initialize_thread_stack
884
885
886 /******************* function asm_perform_threadswitch *************************
887 *                                                                              *
888 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
889 *                                                                              *
890 *   performs a threadswitch                                                    *
891 *                                                                              *
892 *******************************************************************************/
893
894         .ent    asm_perform_threadswitch
895 asm_perform_threadswitch:
896
897         aaddiu  sp,sp,-14*8     /* allocate new stack                             */
898         sd      s0,  0*8(sp)    /* save saved registers of old thread             */
899         sd      s1,  1*8(sp)
900         sd      s2,  2*8(sp)
901         sd      s3,  3*8(sp)
902         sd      s4,  4*8(sp)
903         sd      s5,  5*8(sp)
904         sd      s6,  6*8(sp)
905         sd      s7,  7*8(sp)
906         sd      s8,  8*8(sp)
907         sdc1    fs0, 9*8(sp)
908         sdc1    fs1,10*8(sp)
909         sdc1    fs2,11*8(sp)
910         sdc1    fs3,12*8(sp)
911         sd      ra, 13*8(sp)
912         ast     sp,0(a0)        /* save old stack pointer                         */
913         ast     sp,0(a2)        /* stackTop = old stack pointer                   */
914         ald     sp,0(a1)        /* load new stack pointer                         */
915         ld      s0,  0*8(sp)    /* load saved registers of new thread             */
916         ld      s1,  1*8(sp)
917         ld      s2,  2*8(sp)
918         ld      s3,  3*8(sp)
919         ld      s4,  4*8(sp)
920         ld      s5,  5*8(sp)
921         ld      s6,  6*8(sp)
922         ld      s7,  7*8(sp)
923         ld      s8,  8*8(sp)
924         ldc1    fs0, 9*8(sp)
925         ldc1    fs1,10*8(sp)
926         ldc1    fs2,11*8(sp)
927         ldc1    fs3,12*8(sp)
928         ld      ra, 13*8(sp)
929         aaddiu  sp,sp,14*8      /* deallocate new stack                           */
930         move    itmp3, ra
931         j       ra              /* return                                         */
932         .end    asm_perform_threadswitch
933
934
935 /********************* function asm_switchstackandcall *************************
936 *                                                                              *
937 *  void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
938 *                                                                              *
939 *   Switches to a new stack, calls a function and switches back.               *
940 *       a0      new stack pointer                                              *
941 *       a1      function pointer                                               *
942 *               a2              pointer to variable where stack top should be stored           *
943 *                                                                              *
944 *******************************************************************************/
945
946
947         .ent    asm_switchstackandcall
948 asm_switchstackandcall:
949         aaddiu  a0,a0,-16       /* allocate new stack                             */
950         sd      ra,0(a0)        /* save return address on new stack               */
951         sd      sp,8(a0)        /* save old stack pointer on new stack            */
952         sd      sp,0(a2)        /* save old stack pointer to variable             */
953         move    sp,a0           /* switch to new stack                            */
954         
955         move    itmp3,a1
956         jalr    itmp3           /* and call function                              */
957
958         ld      ra,0(sp)        /* load return address                            */
959         ld      sp,8(sp)        /* switch to old stack                            */
960
961         j       ra              /* return                                         */
962
963         .end    asm_switchstackandcall