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