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