asmpart.c is now asmpart.S
[cacao.git] / alpha / 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 *            Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at            *
13 *                                                                              *
14 *   Last Change: 1998/11/01                                                    *
15 *                                                                              *
16 *******************************************************************************/
17
18 #include "offsets.h"
19
20 #define v0      $0
21
22 #define t0      $1
23 #define t1      $2
24 #define t2      $3
25 #define t3      $4
26 #define t4      $5
27 #define t5      $6
28 #define t6      $7
29 #define t7      $8
30
31 #define s0      $9
32 #define s1      $10
33 #define s2      $11
34 #define s3      $12
35 #define s4      $13
36 #define s5      $14
37 #define s6      $15
38
39 #define a0      $16
40 #define a1      $17
41 #define a2      $18
42 #define a3      $19
43 #define a4      $20
44 #define a5      $21
45
46 #define t8      $22
47 #define t9      $23
48 #define t10     $24
49 #define t11     $25
50 #define ra      $26
51 #define t12     $27
52
53 #define pv      t12
54 #define AT      $at
55 #define gp      $29
56 #define sp      $30
57 #define zero    $31
58
59 #define itmp1   $25
60 #define itmp2   $28
61 #define itmp3   $29
62
63 #define xptr    itmp1
64 #define xpc     itmp2
65
66 #define sf0     $f2
67 #define sf1     $f3
68 #define sf2     $f4
69 #define sf3     $f5
70 #define sf4     $f6
71 #define sf5     $f7
72 #define sf6     $f8
73 #define sf7     $f9
74
75 #define fzero   $f31
76
77
78 #define PAL_imb 134
79
80         .text
81         .set    noat
82         .set    noreorder
83
84
85 /********************* exported functions and variables ***********************/
86
87         .globl has_no_x_instr_set
88         .globl synchronize_caches
89         .globl asm_calljavamethod
90         .globl asm_calljavafunction
91         .globl asm_call_jit_compiler
92         .globl asm_dumpregistersandcall
93         .globl asm_handle_exception
94         .globl asm_handle_nat_exception
95         .globl asm_builtin_checkcast    
96         .globl asm_builtin_checkarraycast
97         .globl asm_builtin_aastore
98         .globl asm_builtin_monitorenter
99         .globl asm_builtin_monitorexit
100         .globl asm_builtin_idiv
101         .globl asm_builtin_irem
102         .globl asm_builtin_ldiv
103         .globl asm_builtin_lrem
104         .globl asm_perform_threadswitch
105         .globl asm_initialize_thread_stack
106         .globl asm_switchstackandcall
107         .globl asm_getcallingmethod
108
109 /*************************** imported variables *******************************/
110
111         .globl newcompiler
112
113
114 /*************************** imported functions *******************************/
115
116         .globl jit_compile
117         .globl builtin_monitorexit
118         .globl builtin_throw_exception
119         .globl builtin_trace_exception
120         .globl class_java_lang_Object
121
122
123 /*********************** function has_no_x_instr_set ***************************
124 *                                                                              *
125 *   determines if the byte support instruction set (21164a and higher)         *
126 *   is available.                                                              *
127 *                                                                              *
128 *******************************************************************************/
129
130         .ent    has_no_x_instr_set
131 has_no_x_instr_set:
132
133         .long   0x47e03c20                /* amask   1,v0                         */
134         jmp     zero,(ra)                 /* return                               */
135
136         .end    has_no_x_instr_set
137
138
139 /********************* function synchronize_caches ****************************/
140
141         .ent    synchronize_caches
142 synchronize_caches:
143
144         call_pal PAL_imb                  /* synchronise instruction cache        */
145         jmp     zero,(ra)                 /* return                               */
146
147         .end    synchronize_caches
148
149
150 /********************* function asm_calljavamethod *****************************
151 *                                                                              *
152 *   This function calls a Java-method (which possibly needs compilation)       *
153 *   with up to 4 parameters.                                                   *
154 *                                                                              *
155 *   This functions calls the JIT-compiler which eventually translates the      *
156 *   method into machine code.                                                  *
157 *                                                                              *
158 *   An possibly throwed exception will be returned to the caller as function   *
159 *   return value, so the java method cannot return a fucntion value (this      *
160 *   function usually calls 'main' and '<clinit>' which do not return a         *
161 *   function value).                                                           *
162 *                                                                              *
163 *   C-prototype:                                                               *
164 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
165 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
166 *                                                                              *
167 *******************************************************************************/
168
169 #define         MethodPointer   -8
170 #define         FrameSize       -12
171 #define     IsSync          -16
172 #define     IsLeaf          -20
173 #define     IntSave         -24
174 #define     FltSave         -28
175 #define     ExTableSize     -32
176 #define     ExTableStart    -32
177
178 #define     ExEntrySize     -32
179 #define     ExStartPC       -8
180 #define     ExEndPC         -16
181 #define     ExHandlerPC     -24
182 #define     ExCatchType     -32
183
184         .ent    asm_calljavamethod
185
186 call_name:
187         .ascii  "calljavamethod\0\0"
188
189         .align  3
190         .quad   0                         /* catch type all                       */
191         .quad   calljava_xhandler         /* handler pc                           */
192         .quad   calljava_xhandler         /* end pc                               */
193         .quad   asm_calljavamethod        /* start pc                             */
194         .long   1                         /* extable size                         */
195         .long   0                         /* fltsave                              */
196         .long   0                         /* intsave                              */
197         .long   0                         /* isleaf                               */
198         .long   0                         /* IsSync                               */
199         .long   32                        /* frame size                           */
200         .quad   0                         /* method pointer (pointer to name)     */
201
202 asm_calljavamethod:
203
204         ldgp    gp,0(pv)
205         lda     sp,-32(sp)                /* allocate stack space                 */
206         stq     gp,24(sp)                 /* save global pointer                  */
207         stq     ra,0(sp)                  /* save return address                  */
208
209         stq     a0,16(sp)                 /* save method pointer for compiler     */
210         lda     v0,16(sp)                 /* pass pointer to method pointer via v0*/
211
212         mov     a1,a0                     /* pass the remaining parameters        */
213         mov     a2,a1
214         mov     a3,a2
215         mov     a4,a3
216
217         lda     $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
218         stq     $28,8(sp)                 /* store function address               */
219         mov     sp,$28                    /* set method pointer                   */
220
221         ldq     pv,8($28)                 /* method call as in Java               */
222         jmp     ra,(pv)                   /* call JIT compiler                    */
223 calljava_jit:
224         lda     pv,-64(ra)                /* asm_calljavamethod-calljava_jit !!!!!*/
225
226 calljava_return:
227
228         ldq     ra,0(sp)                  /* restore return address               */
229         ldq     gp,24(sp)                 /* restore global pointer               */
230         lda     sp,32(sp)                 /* free stack space                     */
231         ldl     v0,newcompiler            /* load newcompiler flag                */
232         subq    v0,1,v0                   /* negate for clearing v0               */
233         beq     v0,calljava_ret           /* if newcompiler skip ex copying       */
234         mov     $1,v0                     /* pass exception to caller (C)         */
235 calljava_ret:
236         jmp     zero,(ra)
237
238 calljava_xhandler:
239
240         ldq     gp,24(sp)                 /* restore global pointer               */
241         mov     itmp1,a0
242         jsr     ra,builtin_throw_exception
243         ldq     ra,0(sp)                  /* restore return address               */
244         lda     sp,32(sp)                 /* free stack space                     */
245         jmp     zero,(ra)
246         .end    asm_calljavamethod
247
248
249 /********************* function asm_calljavafunction ***************************
250 *                                                                              *
251 *   This function calls a Java-method (which possibly needs compilation)       *
252 *   with up to 4 address parameters.                                           *
253 *                                                                              *
254 *   This functions calls the JIT-compiler which eventually translates the      *
255 *   method into machine code.                                                  *
256 *                                                                              *
257 *   C-prototype:                                                               *
258 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
259 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
260 *                                                                              *
261 *******************************************************************************/
262
263         .ent    asm_calljavafunction
264
265 call_name2:
266         .ascii  "calljavafunction\0\0"
267
268         .align  3
269         .quad   0                         /* catch type all                       */
270         .quad   calljava_xhandler2        /* handler pc                           */
271         .quad   calljava_xhandler2        /* end pc                               */
272         .quad   asm_calljavafunction      /* start pc                             */
273         .long   1                         /* extable size                         */
274         .long   0                         /* fltsave                              */
275         .long   0                         /* intsave                              */
276         .long   0                         /* isleaf                               */
277         .long   0                         /* IsSync                               */
278         .long   32                        /* frame size                           */
279         .quad   0                         /* method pointer (pointer to name)     */
280
281 asm_calljavafunction:
282
283         ldgp    gp,0(pv)
284         lda     sp,-32(sp)                /* allocate stack space                 */
285         stq     gp,24(sp)                 /* save global pointer                  */
286         stq     ra,0(sp)                  /* save return address                  */
287
288         stq     a0,16(sp)                 /* save method pointer for compiler     */
289         lda     v0,16(sp)                 /* pass pointer to method pointer via v0*/
290
291         mov     a1,a0                     /* pass the remaining parameters        */
292         mov     a2,a1
293         mov     a3,a2
294         mov     a4,a3
295
296         lda     $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
297         stq     $28,8(sp)                 /* store function address               */
298         mov     sp,$28                    /* set method pointer                   */
299
300         ldq     pv,8($28)                 /* method call as in Java               */
301         jmp     ra,(pv)                   /* call JIT compiler                    */
302 calljava_jit2:
303         lda     pv,-64(ra)                /* asm_calljavafunction-calljava_jit !!!!!*/
304
305 calljava_return2:
306
307         ldq     ra,0(sp)                  /* restore return address               */
308         ldq     gp,24(sp)                 /* restore global pointer               */
309         lda     sp,32(sp)                 /* free stack space                     */
310
311 /*      ldl     v0,newcompiler */         /* load newcompiler flag                */
312 /*      subq    v0,1,v0        */         /* negate for clearing v0               */
313 /*      beq     v0,calljava_ret*/         /* if newcompiler skip ex copying       */
314 /*      mov     $1,v0 */                  /* pass exception to caller (C)         */
315 calljava_ret2:
316         jmp     zero,(ra)
317
318 calljava_xhandler2:
319
320         ldq     gp,24(sp)                 /* restore global pointer               */
321         mov     itmp1,a0
322         jsr     ra,builtin_throw_exception
323         ldq     ra,0(sp)                  /* restore return address               */
324         lda     sp,32(sp)                 /* free stack space                     */
325         jmp     zero,(ra)
326         .end    asm_calljavafunction
327                                                 
328
329 /****************** function asm_call_jit_compiler *****************************
330 *                                                                              *
331 *   invokes the compiler for untranslated JavaVM methods.                      *
332 *                                                                              *
333 *   Register R0 contains a pointer to the method info structure (prepared      *
334 *   by createcompilerstub). Using the return address in R26 and the            *
335 *   offset in the LDA instruction or using the value in methodptr R28 the      *
336 *   patching address for storing the method address can be computed:           *
337 *                                                                              *
338 *   method address was either loaded using                                     *
339 *   M_LDQ (REG_PV, REG_PV, a)        ; invokestatic/special    ($27)           *
340 *   M_LDA (REG_PV, REG_RA, low)                                                *
341 *   M_LDAH(REG_PV, REG_RA, high)     ; optional                                *
342 *   or                                                                         *
343 *   M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28)           *
344 *   in the static case the method pointer can be computed using the            *
345 *   return address and the lda function following the jmp instruction          *
346 *                                                                              *
347 *******************************************************************************/
348
349
350         .ent    asm_call_jit_compiler
351 asm_call_jit_compiler:
352
353         ldgp    gp,0(pv)
354         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
355         srl     t8,16,t8              /* shift right register number $yy          */
356         and     t8,31,t8              /* isolate register number                  */
357         subl    t8,28,t8              /* test for REG_METHODPTR                   */
358         beq     t8,noregchange       
359         ldl     t8,0(ra)              /* load instruction LDA PV,xxx(RA)          */
360         sll     t8,48,t8
361         sra     t8,48,t8              /* isolate offset                           */
362         addq    t8,ra,$28             /* compute update address                   */
363         ldl     t8,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
364         srl     t8,16,t8              /* isolate instruction code                 */
365         lda     t8,-0x177b(t8)        /* test for LDAH                            */
366         bne     t8,noregchange       
367         ldl     t8,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
368         sll     t8,16,t8              /* compute high offset                      */
369         addl    t8,0,t8               /* sign extend high offset                  */
370         addq    t8,$28,$28            /* compute update address                   */
371 noregchange:
372         lda     sp,-14*8(sp)          /* reserve stack space                      */
373         stq     a0,0*8(sp)            /* save all argument registers              */
374         stq     a1,1*8(sp)            /* they could be used by method             */
375         stq     a2,2*8(sp)
376         stq     a3,3*8(sp)
377         stq     a4,4*8(sp)
378         stq     a5,5*8(sp)
379         stt     $f16,6*8(sp)
380         stt     $f17,7*8(sp)
381         stt     $f18,8*8(sp)
382         stt     $f19,9*8(sp)
383         stt     $f20,10*8(sp)
384         stt     $f21,11*8(sp)
385         stq     $28,12*8(sp)          /* save method pointer                      */
386         stq     ra,13*8(sp)           /* save return address                      */
387
388         ldq     a0,0(v0)              /* pass 'methodinfo' pointer to             */
389         jsr     ra,jit_compile        /* jit compiler                             */
390         ldgp    gp,0(ra)
391
392         call_pal PAL_imb              /* synchronise instruction cache            */
393
394         ldq     a0,0*8(sp)            /* load argument registers                  */
395         ldq     a1,1*8(sp)
396         ldq     a2,2*8(sp)
397         ldq     a3,3*8(sp)
398         ldq     a4,4*8(sp)
399         ldq     a5,5*8(sp)
400         ldt     $f16,6*8(sp)
401         ldt     $f17,7*8(sp)
402         ldt     $f18,8*8(sp)
403         ldt     $f19,9*8(sp)
404         ldt     $f20,10*8(sp)
405         ldt     $f21,11*8(sp)
406         ldq     $28,12*8(sp)          /* load method pointer                      */
407         ldq     ra,13*8(sp)           /* load return address                      */
408         lda     sp,14*8(sp)           /* deallocate stack area                    */
409
410         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
411         sll     t8,48,t8
412         sra     t8,48,t8              /* isolate offset                           */
413
414         addq    t8,$28,t8             /* compute update address via method pointer*/
415         stq     v0,0(t8)              /* save new method address there            */
416
417         mov     v0,pv                 /* load method address into pv              */
418
419         jmp     zero,(pv)             /* and call method. The method returns      */
420                                       /* directly to the caller (ra).             */
421
422         .end    asm_call_jit_compiler
423
424
425 /****************** function asm_dumpregistersandcall **************************
426 *                                                                              *
427 *   This funtion saves all callee saved registers and calls the function       *
428 *   which is passed as parameter.                                              *
429 *                                                                              *
430 *   This function is needed by the garbage collector, which needs to access    *
431 *   all registers which are stored on the stack. Unused registers are          *
432 *   cleared to avoid interferances with the GC.                                *
433 *                                                                              *
434 *   void asm_dumpregistersandcall (functionptr f);                             *
435 *                                                                              *
436 *******************************************************************************/
437
438         .ent    asm_dumpregistersandcall
439 asm_dumpregistersandcall:
440         lda     sp,-16*8(sp)          /* allocate stack                           */
441         stq     ra,0(sp)              /* save return address                      */
442
443         stq     s0,1*8(sp)            /* save all callee saved registers          */
444         stq     s1,2*8(sp)            /* intialize the remaining registers        */
445         stq     s2,3*8(sp)
446         stq     s3,4*8(sp)
447         stq     s4,5*8(sp)
448         stq     s5,6*8(sp)
449         stq     s6,7*8(sp)
450         stt     $f2,8*8(sp)
451         stt     $f3,9*8(sp)
452         stt     $f4,10*8(sp)
453         stt     $f5,11*8(sp)
454         stt     $f6,12*8(sp)
455         stt     $f7,13*8(sp)
456         stt     $f8,14*8(sp)
457         stt     $f9,15*8(sp)
458
459         clr     v0                   /* intialize the remaining registers         */
460         clr     t0
461         clr     t1
462         clr     t2
463         clr     t3
464         clr     t4
465         clr     t5
466         clr     t6
467         clr     t7
468         clr     a1
469         clr     a2
470         clr     a3
471         clr     a4
472         clr     a5
473         clr     t8
474         clr     t9
475         clr     t10
476         clr     t11
477         clr     t12
478         clr     $28
479         clr     $29
480         cpys    $f31,$f31,$f0
481         cpys    $f31,$f31,$f1
482         cpys    $f31,$f31,$f10
483         cpys    $f31,$f31,$f11
484         cpys    $f31,$f31,$f12
485         cpys    $f31,$f31,$f13
486         cpys    $f31,$f31,$f14
487         cpys    $f31,$f31,$f15
488         cpys    $f31,$f31,$f16
489         cpys    $f31,$f31,$f17
490         cpys    $f31,$f31,$f18
491         cpys    $f31,$f31,$f19
492         cpys    $f31,$f31,$f20
493         cpys    $f31,$f31,$f21
494         cpys    $f31,$f31,$f22
495         cpys    $f31,$f31,$f23
496         cpys    $f31,$f31,$f24
497         cpys    $f31,$f31,$f25
498         cpys    $f31,$f31,$f26
499         cpys    $f31,$f31,$f27
500         cpys    $f31,$f31,$f28
501         cpys    $f31,$f31,$f29
502         cpys    $f31,$f31,$f30
503
504         mov     a0,pv                 /* load function pointer                    */
505         jmp     ra,(pv)               /* and call function                        */
506
507         ldq     ra,0(sp)              /* load return address                      */
508         lda     sp,16*8(sp)           /* deallocate stack                         */
509         jmp     zero,(ra)             /* return                                   */
510
511         .end    asm_dumpregistersandcall
512
513
514 /********************* function asm_handle_exception ***************************
515 *                                                                              *
516 *   This function handles an exception. It does not use the usual calling      *
517 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
518 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
519 *   the local exception table for a handler. If no one is found, it unwinds    *
520 *   stacks and continues searching the callers.                                *
521 *                                                                              *
522 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
523 *                                                                              *
524 *******************************************************************************/
525
526         .ent    asm_handle_nat_exception
527 asm_handle_nat_exception:
528
529         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
530         sll     t0,48,t0
531         sra     t0,48,t0              /* isolate offset                           */
532         addq    t0,ra,pv              /* compute update address                   */
533         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
534         srl     t0,16,t0              /* isolate instruction code                 */
535         lda     t0,-0x177b(t0)        /* test for LDAH                            */
536         bne     t0,asm_handle_exception       
537         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
538         sll     t0,16,t0              /* compute high offset                      */
539         addl    t0,0,t0               /* sign extend high offset                  */
540         addq    t0,pv,pv              /* compute update address                   */
541
542         .aent    asm_handle_exception
543 asm_handle_exception:
544
545         lda     sp,-18*8(sp)          /* allocate stack                           */
546         stq     t0,0*8(sp)            /* save possible used registers             */
547         stq     t1,1*8(sp)            /* also registers used by trace_exception   */
548         stq     t2,2*8(sp)
549         stq     t3,3*8(sp)
550         stq     t4,4*8(sp)
551         stq     t5,5*8(sp)
552         stq     t6,6*8(sp)
553         stq     t7,7*8(sp)
554         stq     t8,8*8(sp)
555         stq     t9,9*8(sp)
556         stq     t10,10*8(sp)
557         stq     v0,11*8(sp)
558         stq     a0,12*8(sp)
559         stq     a1,13*8(sp)
560         stq     a2,14*8(sp)
561         stq     a3,15*8(sp)
562         stq     a4,16*8(sp)
563         stq     a5,17*8(sp)
564
565         lda     t3,1(zero)            /* set no unwind flag                       */
566 ex_stack_loop:
567         lda     sp,-5*8(sp)           /* allocate stack                           */
568         stq     xptr,0*8(sp)          /* save used register                       */
569         stq     xpc,1*8(sp)
570         stq     pv,2*8(sp)
571         stq     ra,3*8(sp)
572         stq     t3,4*8(sp)
573
574         mov     xptr,a0
575         ldq     a1,MethodPointer(pv)
576         mov     xpc,a2
577         mov     t3,a3
578         br      ra,ex_trace           /* set ra for gp loading                    */
579 ex_trace:
580         ldgp    gp,0(ra)              /* load gp                                  */
581         jsr     ra,builtin_trace_exception /* trace_exception(xptr,methodptr)     */
582         
583         ldq     xptr,0*8(sp)          /* restore used register                    */
584         ldq     xpc,1*8(sp)
585         ldq     pv,2*8(sp)
586         ldq     ra,3*8(sp)
587         ldq     t3,4*8(sp)
588         lda     sp,5*8(sp)            /* deallocate stack                         */
589         
590         ldl     t0,ExTableSize(pv)    /* t0 = exception table size                */
591         beq     t0,empty_table        /* if empty table skip                      */
592         lda     t1,ExTableStart(pv)   /* t1 = start of exception table            */
593
594 ex_table_loop:
595         ldq     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
596         cmple   t2,xpc,t2             /* t2 = (startpc <= xpc)                    */
597         beq     t2,ex_table_cont      /* if (false) continue                      */
598         ldq     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
599         cmplt   xpc,t2,t2             /* t2 = (xpc < endpc)                       */
600         beq     t2,ex_table_cont      /* if (false) continue                      */
601         ldq     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
602         beq     a1,ex_handle_it       /* NULL catches everything                  */
603
604         ldq     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
605         ldq     a1,offobjvftbl(a1)    /* a1 = vftblptr(catchtype) class (not obj) */
606         ldl     a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
607         ldl     v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
608         ldl     a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
609         subl    a0,v0,a0              /* a0 = baseval(xptr) - baseval(catchtype)  */
610         cmpule  a0,a1,v0              /* v0 = xptr is instanceof catchtype        */
611         beq     v0,ex_table_cont      /* if (false) continue                      */
612
613 ex_handle_it:
614
615         ldq     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
616
617         beq     t3,ex_jump            /* if (!(no stack unwinding) skip           */
618
619         ldq     t0,0*8(sp)            /* restore possible used registers          */
620         ldq     t1,1*8(sp)            /* also registers used by trace_exception   */
621         ldq     t2,2*8(sp)
622         ldq     t3,3*8(sp)
623         ldq     t4,4*8(sp)
624         ldq     t5,5*8(sp)
625         ldq     t6,6*8(sp)
626         ldq     t7,7*8(sp)
627         ldq     t8,8*8(sp)
628         ldq     t9,9*8(sp)
629         ldq     t10,10*8(sp)
630         ldq     v0,11*8(sp)
631         ldq     a0,12*8(sp)
632         ldq     a1,13*8(sp)
633         ldq     a2,14*8(sp)
634         ldq     a3,15*8(sp)
635         ldq     a4,16*8(sp)
636         ldq     a5,17*8(sp)
637         lda     sp,18*8(sp)           /* deallocate stack                         */
638
639 ex_jump:
640         jmp     zero,(xpc)            /* jump to the handler                      */
641
642 ex_table_cont:
643         lda     t1,ExEntrySize(t1)    /* next exception table entry               */
644         subl    t0,1,t0               /* decrement entry counter                  */
645         bgt     t0,ex_table_loop      /* if (t0 > 0) next entry                   */
646
647 empty_table:
648         beq     t3,ex_already_cleared /* if here the first time, then             */
649         lda     sp,18*8(sp)           /* deallocate stack and                     */
650         clr     t3                    /* clear the no unwind flag                 */
651 ex_already_cleared:
652         ldl     t0,IsSync(pv)         /* t0 = SyncOffset                          */
653         beq     t0,no_monitor_exit    /* if zero no monitorexit                   */
654         addq    sp,t0,t0              /* add stackptr to Offset                   */
655         ldq     a0,-8(t0)             /* load monitorexit pointer                 */
656
657         lda     sp,-7*8(sp)           /* allocate stack                           */
658         stq     t0,0*8(sp)            /* save used register                       */
659         stq     t1,1*8(sp)
660         stq     t3,2*8(sp)
661         stq     xptr,3*8(sp)
662         stq     xpc,4*8(sp)
663         stq     pv,5*8(sp)
664         stq     ra,6*8(sp)
665
666         br      ra,ex_mon_load        /* set ra for gp loading                    */
667 ex_mon_load:
668         ldgp    gp,0(ra)              /* load gp                                  */
669         jsr     ra,builtin_monitorexit/* builtin_monitorexit(objectptr)           */
670         
671         ldq     t0,0*8(sp)            /* restore used register                    */
672         ldq     t1,1*8(sp)
673         ldq     t3,2*8(sp)
674         ldq     xptr,3*8(sp)
675         ldq     xpc,4*8(sp)
676         ldq     pv,5*8(sp)
677         ldq     ra,6*8(sp)
678         lda     sp,7*8(sp)            /* deallocate stack                         */
679
680 no_monitor_exit:
681         ldl     t0,FrameSize(pv)      /* t0 = frame size                          */
682         addq    sp,t0,sp              /* unwind stack                             */
683         mov     sp,t0                 /* t0 = pointer to save area                */
684         ldl     t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
685         bne     t1,ex_no_restore      /* if (leaf) skip                           */
686         ldq     ra,-8(t0)             /* restore ra                               */
687         lda     t0,-8(t0)             /* t0--                                     */
688 ex_no_restore:
689         mov     ra,xpc                /* the new xpc is ra                        */
690         ldl     t1,IntSave(pv)        /* t1 = saved int register count            */
691         br      t2,ex_int1            /* t2 = current pc                          */
692 ex_int1:
693         lda     t2,44(t2)             /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
694         negl    t1,t1                 /* negate register count                    */
695         s4addq  t1,t2,t2              /* t2 = ex_int_sav - 4 * register count     */
696         jmp     zero,(t2)             /* jump to save position                    */
697         ldq     s0,-56(t0)
698         ldq     s1,-48(t0)
699         ldq     s2,-40(t0)
700         ldq     s3,-32(t0)
701         ldq     s4,-24(t0)
702         ldq     s5,-16(t0)
703         ldq     s6,-8(t0)
704 ex_int2:
705         s8addq  t1,t0,t0              /* t0 = t0 - 8 * register count             */
706
707         ldl     t1,FltSave(pv)        /* t1 = saved flt register count            */
708         br      t2,ex_flt1            /* t2 = current pc                          */
709 ex_flt1:
710         lda     t2,48(t2)             /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
711         negl    t1,t1                 /* negate register count                    */
712         s4addq  t1,t2,t2              /* t2 = ex_flt_sav - 4 * register count     */
713         jmp     zero,(t2)             /* jump to save position                    */
714         ldt     $f2,-64(t0)
715         ldt     $f3,-56(t0)
716         ldt     $f4,-48(t0)
717         ldt     $f5,-40(t0)
718         ldt     $f6,-32(t0)
719         ldt     $f7,-24(t0)
720         ldt     $f8,-16(t0)
721         ldt     $f9,-8(t0)
722 ex_flt2:
723         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
724         sll     t0,48,t0
725         sra     t0,48,t0              /* isolate offset                           */
726         addq    t0,ra,pv              /* compute update address                   */
727         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
728         srl     t0,16,t0              /* isolate instruction code                 */
729         lda     t0,-0x177b(t0)        /* test for LDAH                            */
730         bne     t0,ex_stack_loop       
731         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
732         sll     t0,16,t0              /* compute high offset                      */
733         addl    t0,0,t0               /* sign extend high offset                  */
734         addq    t0,pv,pv              /* compute update address                   */
735         br      ex_stack_loop
736
737         .end    asm_handle_nat_exception
738
739
740 /********************* function asm_builtin_monitorenter ***********************
741 *                                                                              *
742 *   Does null check and calls monitorenter or throws an exception              *
743 *                                                                              *
744 *******************************************************************************/
745
746         .ent    asm_builtin_monitorenter
747 asm_builtin_monitorenter:
748
749         ldgp    gp,0(pv)
750         lda     pv,builtin_monitorenter
751         beq     a0,nb_monitorenter        /* if (null) throw exception            */
752         jmp     zero,(pv)                 /* else call builtin_monitorenter       */
753
754 nb_monitorenter:
755         ldq     xptr,proto_java_lang_NullPointerException
756         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
757         br      asm_handle_nat_exception
758         .end    asm_builtin_monitorenter
759
760
761 /********************* function asm_builtin_monitorexit ************************
762 *                                                                              *
763 *   Does null check and calls monitorexit or throws an exception               *
764 *                                                                              *
765 *******************************************************************************/
766
767         .ent    asm_builtin_monitorexit
768 asm_builtin_monitorexit:
769
770         ldgp    gp,0(pv)
771         lda     pv,builtin_monitorexit
772         beq     a0,nb_monitorexit         /* if (null) throw exception            */
773         jmp     zero,(pv)                 /* else call builtin_monitorexit        */
774
775 nb_monitorexit:
776         ldq     xptr,proto_java_lang_NullPointerException
777         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
778         br      asm_handle_nat_exception
779         .end    asm_builtin_monitorexit
780
781
782 /************************ function asm_builtin_idiv ****************************
783 *                                                                              *
784 *   Does null check and calls idiv or throws an exception                      *
785 *                                                                              *
786 *******************************************************************************/
787
788         .ent    asm_builtin_idiv
789 asm_builtin_idiv:
790
791         ldgp    gp,0(pv)
792         lda     pv,builtin_idiv
793         beq     a1,nb_idiv                /* if (null) throw exception            */
794         jmp     zero,(pv)                 /* else call builtin_idiv               */
795
796 nb_idiv:
797         ldq     xptr,proto_java_lang_ArithmeticException
798         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
799         br      asm_handle_nat_exception
800         .end    asm_builtin_idiv
801
802
803 /************************ function asm_builtin_ldiv ****************************
804 *                                                                              *
805 *   Does null check and calls ldiv or throws an exception                      *
806 *                                                                              *
807 *******************************************************************************/
808
809         .ent    asm_builtin_ldiv
810 asm_builtin_ldiv:
811
812         ldgp    gp,0(pv)
813         lda     pv,builtin_ldiv
814         beq     a1,nb_ldiv                /* if (null) throw exception            */
815         jmp     zero,(pv)                 /* else call builtin_ldiv               */
816
817 nb_ldiv:
818         ldq     xptr,proto_java_lang_ArithmeticException
819         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
820         br      asm_handle_nat_exception
821         .end    asm_builtin_ldiv
822
823
824 /************************ function asm_builtin_irem ****************************
825 *                                                                              *
826 *   Does null check and calls irem or throws an exception                      *
827 *                                                                              *
828 *******************************************************************************/
829
830         .ent    asm_builtin_irem
831 asm_builtin_irem:
832
833         ldgp    gp,0(pv)
834         lda     pv,builtin_irem
835         beq     a1,nb_irem                /* if (null) throw exception            */
836         jmp     zero,(pv)                 /* else call builtin_irem               */
837
838 nb_irem:
839         ldq     xptr,proto_java_lang_ArithmeticException
840         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
841         br      asm_handle_nat_exception
842         .end    asm_builtin_irem
843
844
845 /************************ function asm_builtin_lrem ****************************
846 *                                                                              *
847 *   Does null check and calls lrem or throws an exception                      *
848 *                                                                              *
849 *******************************************************************************/
850
851         .ent    asm_builtin_lrem
852 asm_builtin_lrem:
853
854         ldgp    gp,0(pv)
855         lda     pv,builtin_lrem
856         beq     a1,nb_lrem                /* if (null) throw exception            */
857         jmp     zero,(pv)                 /* else call builtin_lrem               */
858
859 nb_lrem:
860         ldq     xptr,proto_java_lang_ArithmeticException
861         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
862         br      asm_handle_nat_exception
863         .end    asm_builtin_lrem
864
865
866  /*********************** function new_builtin_checkcast ************************
867  *                                                                              *
868  *   Does the cast check and eventually throws an exception                     *
869  *                                                                              *
870  *******************************************************************************/
871
872     .ent    asm_builtin_checkcast
873 asm_builtin_checkcast:
874
875     ldgp    gp,0(pv)
876     lda     sp,-16(sp)                  # allocate stack space
877     stq     ra,0(sp)                    # save return address
878     stq     a0,8(sp)                    # save object pointer
879     jsr     ra,builtin_checkcast        # builtin_checkcast
880     ldgp    gp,0(ra)
881     beq     v0,nb_ccast_throw           # if (false) throw exception
882     ldq     ra,0(sp)                    # restore return address
883     ldq     v0,8(sp)                    # return object pointer
884     lda     sp,16(sp)                   # free stack space
885     jmp     zero,(ra)
886
887 nb_ccast_throw:
888     ldq     xptr,proto_java_lang_ClassCastException
889     ldq     ra,0(sp)                    # restore return address
890     lda     sp,16(sp)                   # free stack space
891     lda     xpc,-4(ra)                  # faulting address is return adress - 4
892     br      asm_handle_nat_exception
893     .end    asm_builtin_checkcast
894
895                 
896 /******************* function asm_builtin_checkarraycast ***********************
897 *                                                                              *
898 *   Does the cast check and eventually throws an exception                     *
899 *                                                                              *
900 *******************************************************************************/
901
902         .ent    asm_builtin_checkarraycast
903 asm_builtin_checkarraycast:
904
905         ldgp    gp,0(pv)
906         lda     sp,-16(sp)                /* allocate stack space                 */
907         stq     ra,0(sp)                  /* save return address                  */
908         stq     a0,8(sp)                  /* save object pointer                  */
909         jsr     ra,builtin_checkarraycast /* builtin_checkarraycast               */
910         ldgp    gp,0(ra)
911         beq     v0,nb_carray_throw        /* if (false) throw exception           */
912         ldq     ra,0(sp)                  /* restore return address               */
913         ldq     v0,8(sp)                  /* return object pointer                */
914         lda     sp,16(sp)                 /* free stack space                     */
915         jmp     zero,(ra)
916
917 nb_carray_throw:
918         ldq     xptr,proto_java_lang_ClassCastException
919         ldq     ra,0(sp)                  /* restore return address               */
920         lda     sp,16(sp)                 /* free stack space                     */
921         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
922         br      asm_handle_nat_exception
923         .end    asm_builtin_checkarraycast
924
925
926 /******************* function asm_builtin_aastore ******************************
927 *                                                                              *
928 *   Does the cast check and eventually throws an exception                     *
929 *                                                                              *
930 *******************************************************************************/
931
932         .ent    asm_builtin_aastore
933 asm_builtin_aastore:
934
935         ldgp    gp,0(pv)
936         beq     a0,nb_aastore_null        /* if null pointer throw exception      */
937         ldl     t0,offarraysize(a0)       /* load size                            */
938         lda     sp,-24(sp)                /* allocate stack space                 */
939         stq     ra,0(sp)                  /* save return address                  */
940         s8addq  a1,a0,t1                  /* add index*8 to arrayref              */
941         cmpult  a1,t0,t0                  /* do bound check                       */
942         beq     t0,nb_aastore_bound       /* if out of bounds throw exception     */
943         mov     a2,a1                     /* object is second argument            */
944         stq     t1,8(sp)                  /* save store position                  */
945         stq     a1,16(sp)                 /* save object                          */
946         jsr     ra,builtin_canstore       /* builtin_canstore(arrayref,object)    */
947         ldgp    gp,0(ra)
948         ldq     ra,0(sp)                  /* restore return address               */
949         ldq     a0,8(sp)                  /* restore store position               */
950         ldq     a1,16(sp)                 /* restore object                       */
951         lda     sp,24(sp)                 /* free stack space                     */
952         beq     v0,nb_aastore_throw       /* if (false) throw exception           */
953         stq     a1,offobjarrdata(a0)      /* store objectptr in array             */
954         jmp     zero,(ra)
955
956 nb_aastore_null:
957         ldq     xptr,proto_java_lang_NullPointerException
958         mov     ra,xpc                    /* faulting address is return adress    */
959         br      asm_handle_nat_exception
960
961 nb_aastore_bound:
962         ldq     xptr,proto_java_lang_ArrayIndexOutOfBoundsException
963         lda     sp,24(sp)                 /* free stack space                     */
964         mov     ra,xpc                    /* faulting address is return adress    */
965         br      asm_handle_nat_exception
966
967 nb_aastore_throw:
968         ldq     xptr,proto_java_lang_ArrayStoreException
969         mov     ra,xpc                    /* faulting address is return adress    */
970         br      asm_handle_nat_exception
971
972         .end    asm_builtin_aastore
973
974
975 /******************* function asm_initialize_thread_stack **********************
976 *                                                                              *
977 *   initialized a thread stack                                                 *
978 *                                                                              *
979 *******************************************************************************/
980
981         .ent    asm_initialize_thread_stack
982 asm_initialize_thread_stack:
983
984         lda     a1,-128(a1)
985         stq     zero, 0(a1)
986         stq     zero, 8(a1)
987         stq     zero, 16(a1)
988         stq     zero, 24(a1)
989         stq     zero, 32(a1)
990         stq     zero, 40(a1)
991         stq     zero, 48(a1)
992         stt     fzero, 56(a1)
993         stt     fzero, 64(a1)
994         stt     fzero, 72(a1)
995         stt     fzero, 80(a1)
996         stt     fzero, 88(a1)
997         stt     fzero, 96(a1)
998         stt     fzero, 104(a1)
999         stt     fzero, 112(a1)
1000         stq     a0, 120(a1)
1001         mov     a1, v0
1002         jmp     zero,(ra)
1003         .end    asm_initialize_thread_stack
1004
1005
1006 /******************* function asm_perform_threadswitch *************************
1007 *                                                                              *
1008 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1009 *                                                                              *
1010 *   performs a threadswitch                                                    *
1011 *                                                                              *
1012 *******************************************************************************/
1013
1014         .ent    asm_perform_threadswitch
1015 asm_perform_threadswitch:
1016
1017         subq    sp,128,sp
1018         stq     s0, 0(sp)
1019         stq     s1, 8(sp)
1020         stq     s2, 16(sp)
1021         stq     s3, 24(sp)
1022         stq     s4, 32(sp)
1023         stq     s5, 40(sp)
1024         stq     s6, 48(sp)
1025         stt     sf0, 56(sp)
1026         stt     sf1, 64(sp)
1027         stt     sf2, 72(sp)
1028         stt     sf3, 80(sp)
1029         stt     sf4, 88(sp)
1030         stt     sf5, 96(sp)
1031         stt     sf6, 104(sp)
1032         stt     sf7, 112(sp)
1033         stq     ra, 120(sp)
1034         stq     sp, 0(a0)
1035         stq     sp, 0(a2)
1036         ldq     sp, 0(a1)
1037         ldq     s0, 0(sp)
1038         ldq     s1, 8(sp)
1039         ldq     s2, 16(sp)
1040         ldq     s3, 24(sp)
1041         ldq     s4, 32(sp)
1042         ldq     s5, 40(sp)
1043         ldq     s6, 48(sp)
1044         ldt     sf0, 56(sp)
1045         ldt     sf1, 64(sp)
1046         ldt     sf2, 72(sp)
1047         ldt     sf3, 80(sp)
1048         ldt     sf4, 88(sp)
1049         ldt     sf5, 96(sp)
1050         ldt     sf6, 104(sp)
1051         ldt     sf7, 112(sp)
1052         ldq     ra, 120(sp)
1053         mov     ra, pv
1054         addq    sp, 128, sp
1055         jmp     zero,(ra)
1056         .end    asm_perform_threadswitch
1057
1058
1059 /********************* function asm_switchstackandcall *************************
1060 *                                                                              *
1061 *  void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
1062 *                                                                              *
1063 *   Switches to a new stack, calls a function and switches back.               *
1064 *       a0      new stack pointer                                              *
1065 *       a1      function pointer                                               *
1066 *               a2              pointer to variable where stack top should be stored           *
1067 *                                                                              *
1068 *******************************************************************************/
1069
1070
1071         .ent    asm_switchstackandcall
1072 asm_switchstackandcall:
1073         lda     a0,-2*8(a0)     /* allocate new stack                                 */
1074         stq     ra,0(a0)        /* save return address on new stack                   */
1075         stq     sp,1*8(a0)      /* save old stack pointer on new stack                */
1076         stq sp,0(a2)        /* save old stack pointer to variable                 */
1077         mov     a0,sp           /* switch to new stack                                */
1078         
1079         mov     a1,pv           /* load function pointer                              */
1080         jmp     ra,(pv)         /* and call function                                  */
1081
1082         ldq     ra,0(sp)        /* load return address                                */
1083         ldq     sp,1*8(sp)      /* switch to old stack                                */
1084
1085         jmp     zero,(ra)       /* return                                             */
1086
1087         .end    asm_switchstackandcall
1088
1089                 
1090 /********************* function asm_getcallingmethod ***************************
1091 *                                                                              *
1092 *   classinfo *asm_getcallingmethodclass ();                                                               *
1093 *                                                                                                                                                          *    
1094 *   goes back stack frames to get the calling method                                               *       
1095 *                                                                                                                                                          *    
1096 *                               t2 .. sp                                                                                                       *
1097 *                               t3 .. ra                                                                                                       *
1098 *                               t4 .. pv                                                                                                       *
1099 *                                                                              *
1100 *******************************************************************************/
1101
1102
1103         .ent    asm_getcallingmethod
1104 asm_getcallingmethod:
1105
1106         ldq             t3,16(sp)             /* load return address of native function   */                            
1107         addq    sp,24,t2                          /* skip frames of C-Function and nativestub */        
1108                 
1109     /* determine pv (t3) of java-function from ra */
1110
1111         ldl     t0,0(t3)              /* load instruction LDA PV,xxx(RA)          */
1112         sll     t0,48,t0
1113         sra     t0,48,t0              /* isolate offset                           */
1114         addq    t0,t3,t4              /* compute update address                   */
1115         ldl     t0,4(t3)              /* load instruction LDAH PV,xxx(PV)         */
1116         srl     t0,16,t0              /* isolate instruction code                 */
1117         lda     t0,-0x177b(t0)        /* test for LDAH                            */
1118         bne     t0,pv_ok1       
1119         ldl     t0,0(t3)              /* load instruction LDA PV,xxx(RA)          */
1120         sll     t0,16,t0              /* compute high offset                      */
1121         addl    t0,0,t0               /* sign extend high offset                  */
1122         addq    t0,t4,t4              /* compute update address                   */
1123
1124 pv_ok1:                 
1125         ldl     t0,FrameSize(t4)      /* t0 = frame size                          */            
1126         addq    t2,t0,t2                          /* skip frame of java function                          */
1127         ldq             t3,-8(t2)                         /* load new ra                              */                                                                
1128
1129     /* determine pv (t3) of java-function from ra */
1130
1131         ldl     t0,0(t3)              /* load instruction LDA PV,xxx(RA)          */
1132         sll     t0,48,t0
1133         sra     t0,48,t0              /* isolate offset                           */
1134         addq    t0,t3,t4              /* compute update address                   */
1135         ldl     t0,4(t3)              /* load instruction LDAH PV,xxx(PV)         */
1136         srl     t0,16,t0              /* isolate instruction code                 */
1137         lda     t0,-0x177b(t0)        /* test for LDAH                            */
1138         bne     t0,pv_ok2
1139         ldl     t0,0(t3)              /* load instruction LDA PV,xxx(RA)          */
1140         sll     t0,16,t0              /* compute high offset                      */
1141         addl    t0,0,t0               /* sign extend high offset                  */
1142         addq    t0,t4,t4              /* compute update address                   */
1143
1144 pv_ok2:         
1145         ldq     v0,MethodPointer(t4)  /*                                                                                  */
1146
1147                                                                                 
1148         jmp     zero,(ra)                                 /* return                                   */
1149
1150         .end    asm_getcallingmethod
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164