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