bidirectional layout of vftbl/interfaces added
[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_signal_exception
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 perform_alpha_threadswitch
104         .globl initialize_thread_stack
105         .globl asm_switchstackandcall
106
107
108 /*************************** imported variables *******************************/
109
110         .globl newcompiler
111
112
113 /*************************** imported functions *******************************/
114
115         .globl compiler_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         /* end 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         ldgp    gp,0(pv)
204         lda     sp,-32(sp)                /* allocate stack space                 */
205         stq     gp,24(sp)                 /* save global pointer                  */
206         stq     ra,0(sp)                  /* save return address                  */
207
208         stq     a0,16(sp)                 /* save method pointer for compiler     */
209         lda     v0,16(sp)                 /* pass pointer to method pointer via v0*/
210
211         mov     a1,a0                     /* pass the remaining parameters        */
212         mov     a2,a1
213         mov     a3,a2
214         mov     a4,a3
215
216         lda     $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
217         stq     $28,8(sp)                 /* store function address               */
218         mov     sp,$28                    /* set method pointer                   */
219
220         ldq     pv,8($28)                 /* method call as in Java               */
221         jmp     ra,(pv)                   /* call JIT compiler                    */
222 calljava_jit:
223         lda     pv,-64(ra)                /* asm_calljavamethod-calljava_jit !!!!!*/
224
225 calljava_return:
226
227         ldq     ra,0(sp)                  /* restore return address               */
228         ldq     gp,24(sp)                 /* restore global pointer               */
229         lda     sp,32(sp)                 /* free stack space                     */
230         ldl     v0,newcompiler            /* load newcompiler flag                */
231         subq    v0,1,v0                   /* negate for clearing v0               */
232         beq     v0,calljava_ret           /* if newcompiler skip ex copying       */
233         mov     $1,v0                     /* pass exception to caller (C)         */
234 calljava_ret:
235         jmp     zero,(ra)
236
237 calljava_xhandler:
238
239         ldq     gp,24(sp)                 /* restore global pointer               */
240         mov     itmp1,a0
241         jsr     ra,builtin_throw_exception
242         ldq     ra,0(sp)                  /* restore return address               */
243         lda     sp,32(sp)                 /* free stack space                     */
244         jmp     zero,(ra)
245         .end    asm_calljavamethod
246
247
248 /****************** function asm_call_jit_compiler *****************************
249 *                                                                              *
250 *   invokes the compiler for untranslated JavaVM methods.                      *
251 *                                                                              *
252 *   Register R0 contains a pointer to the method info structure (prepared      *
253 *   by createcompilerstub). Using the return address in R26 and the            *
254 *   offset in the LDA instruction or using the value in methodptr R28 the      *
255 *   patching address for storing the method address can be computed:           *
256 *                                                                              *
257 *   method address was either loaded using                                     *
258 *   M_LDQ (REG_PV, REG_PV, a)        ; invokestatic/special    ($27)           *
259 *   M_LDA (REG_PV, REG_RA, low)                                                *
260 *   M_LDAH(REG_PV, REG_RA, high)     ; optional                                *
261 *   or                                                                         *
262 *   M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28)           *
263 *   in the static case the method pointer can be computed using the            *
264 *   return address and the lda function following the jmp instruction          *
265 *                                                                              *
266 *******************************************************************************/
267
268
269         .ent    asm_call_jit_compiler
270 asm_call_jit_compiler:
271
272         ldgp    gp,0(pv)
273         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
274         srl     t8,16,t8              /* shift right register number $yy          */
275         and     t8,31,t8              /* isolate register number                  */
276         subl    t8,28,t8              /* test for REG_METHODPTR                   */
277         beq     t8,noregchange       
278         ldl     t8,0(ra)              /* load instruction LDA PV,xxx(RA)          */
279         sll     t8,48,t8
280         sra     t8,48,t8              /* isolate offset                           */
281         addq    t8,ra,$28             /* compute update address                   */
282         ldl     t8,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
283         srl     t8,16,t8              /* isolate instruction code                 */
284         lda     t8,-0x177b(t8)        /* test for LDAH                            */
285         bne     t8,noregchange       
286         ldl     t8,0(ra)              /* load instruction LDA PV,xxx(RA)          */
287         sll     t8,16,t8              /* compute high offset                      */
288         addl    t8,0,t8               /* sign extend high offset                  */
289         addq    t8,$28,$28            /* compute update address                   */
290 noregchange:
291         lda     sp,-14*8(sp)          /* reserve stack space                      */
292         stq     a0,0*8(sp)            /* save all argument registers              */
293         stq     a1,1*8(sp)            /* they could be used by method             */
294         stq     a2,2*8(sp)
295         stq     a3,3*8(sp)
296         stq     a4,4*8(sp)
297         stq     a5,5*8(sp)
298         stt     $f16,6*8(sp)
299         stt     $f17,7*8(sp)
300         stt     $f18,8*8(sp)
301         stt     $f19,9*8(sp)
302         stt     $f20,10*8(sp)
303         stt     $f21,11*8(sp)
304         stq     $28,12*8(sp)          /* save method pointer                      */
305         stq     ra,13*8(sp)           /* save return address                      */
306
307         ldq     a0,0(v0)              /* pass 'methodinfo' pointer to             */
308         jsr     ra,compiler_compile   /* compiler                                 */
309         ldgp    gp,0(ra)
310
311         call_pal PAL_imb              /* synchronise instruction cache            */
312
313         ldq     a0,0*8(sp)            /* load argument registers                  */
314         ldq     a1,1*8(sp)
315         ldq     a2,2*8(sp)
316         ldq     a3,3*8(sp)
317         ldq     a4,4*8(sp)
318         ldq     a5,5*8(sp)
319         ldt     $f16,6*8(sp)
320         ldt     $f17,7*8(sp)
321         ldt     $f18,8*8(sp)
322         ldt     $f19,9*8(sp)
323         ldt     $f20,10*8(sp)
324         ldt     $f21,11*8(sp)
325         ldq     $28,12*8(sp)          /* load method pointer                      */
326         ldq     ra,13*8(sp)           /* load return address                      */
327         lda     sp,14*8(sp)           /* deallocate stack area                    */
328
329         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
330         sll     t8,48,t8
331         sra     t8,48,t8              /* isolate offset                           */
332
333         addq    t8,$28,t8             /* compute update address via method pointer*/
334         stq     v0,0(t8)              /* save new method address there            */
335
336         mov     v0,pv                 /* load method address into pv              */
337
338         jmp     zero,(pv)             /* and call method. The method returns      */
339                                       /* directly to the caller (ra).             */
340
341         .end    asm_call_jit_compiler
342
343
344 /****************** function asm_dumpregistersandcall **************************
345 *                                                                              *
346 *   This funtion saves all callee saved registers and calls the function       *
347 *   which is passed as parameter.                                              *
348 *                                                                              *
349 *   This function is needed by the garbage collector, which needs to access    *
350 *   all registers which are stored on the stack. Unused registers are          *
351 *   cleared to avoid interferances with the GC.                                *
352 *                                                                              *
353 *   void asm_dumpregistersandcall (functionptr f);                             *
354 *                                                                              *
355 *******************************************************************************/
356
357         .ent    asm_dumpregistersandcall
358 asm_dumpregistersandcall:
359         lda     sp,-16*8(sp)          /* allocate stack                           */
360         stq     ra,0(sp)              /* save return address                      */
361
362         stq     s0,1*8(sp)            /* save all callee saved registers          */
363         stq     s1,2*8(sp)            /* intialize the remaining registers        */
364         stq     s2,3*8(sp)
365         stq     s3,4*8(sp)
366         stq     s4,5*8(sp)
367         stq     s5,6*8(sp)
368         stq     s6,7*8(sp)
369         stt     $f2,8*8(sp)
370         stt     $f3,9*8(sp)
371         stt     $f4,10*8(sp)
372         stt     $f5,11*8(sp)
373         stt     $f6,12*8(sp)
374         stt     $f7,13*8(sp)
375         stt     $f8,14*8(sp)
376         stt     $f9,15*8(sp)
377
378         clr     v0                   /* intialize the remaining registers         */
379         clr     t0
380         clr     t1
381         clr     t2
382         clr     t3
383         clr     t4
384         clr     t5
385         clr     t6
386         clr     t7
387         clr     a1
388         clr     a2
389         clr     a3
390         clr     a4
391         clr     a5
392         clr     t8
393         clr     t9
394         clr     t10
395         clr     t11
396         clr     t12
397         clr     $28
398         clr     $29
399         cpys    $f31,$f31,$f0
400         cpys    $f31,$f31,$f1
401         cpys    $f31,$f31,$f10
402         cpys    $f31,$f31,$f11
403         cpys    $f31,$f31,$f12
404         cpys    $f31,$f31,$f13
405         cpys    $f31,$f31,$f14
406         cpys    $f31,$f31,$f15
407         cpys    $f31,$f31,$f16
408         cpys    $f31,$f31,$f17
409         cpys    $f31,$f31,$f18
410         cpys    $f31,$f31,$f19
411         cpys    $f31,$f31,$f20
412         cpys    $f31,$f31,$f21
413         cpys    $f31,$f31,$f22
414         cpys    $f31,$f31,$f23
415         cpys    $f31,$f31,$f24
416         cpys    $f31,$f31,$f25
417         cpys    $f31,$f31,$f26
418         cpys    $f31,$f31,$f27
419         cpys    $f31,$f31,$f28
420         cpys    $f31,$f31,$f29
421         cpys    $f31,$f31,$f30
422
423         mov     a0,pv                 /* load function pointer                    */
424         jmp     ra,(pv)               /* and call function                        */
425
426         ldq     ra,0(sp)              /* load return address                      */
427         lda     sp,16*8(sp)           /* deallocate stack                         */
428         jmp     zero,(ra)             /* return                                   */
429
430         .end    asm_dumpregistersandcall
431
432
433 /********************* function asm_handle_exception ***************************
434 *                                                                              *
435 *   This function handles an exception. It does not use the usual calling      *
436 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
437 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
438 *   the local exception table for a handler. If no one is found, it unwinds    *
439 *   stacks and continues searching the callers.                                *
440 *                                                                              *
441 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
442 *                                                                              *
443 *******************************************************************************/
444
445         .ent    asm_handle_nat_exception
446 asm_handle_nat_exception:
447
448         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
449         sll     t0,48,t0
450         sra     t0,48,t0              /* isolate offset                           */
451         addq    t0,ra,pv              /* compute update address                   */
452         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
453         srl     t0,16,t0              /* isolate instruction code                 */
454         lda     t0,-0x177b(t0)        /* test for LDAH                            */
455         bne     t0,asm_handle_exception       
456         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
457         sll     t0,16,t0              /* compute high offset                      */
458         addl    t0,0,t0               /* sign extend high offset                  */
459         addq    t0,pv,pv              /* compute update address                   */
460
461         .aent    asm_handle_exception
462 asm_handle_exception:
463
464         lda     sp,-18*8(sp)          /* allocate stack                           */
465         stq     t0,0*8(sp)            /* save possible used registers             */
466         stq     t1,1*8(sp)            /* also registers used by trace_exception   */
467         stq     t2,2*8(sp)
468         stq     t3,3*8(sp)
469         stq     t4,4*8(sp)
470         stq     t5,5*8(sp)
471         stq     t6,6*8(sp)
472         stq     t7,7*8(sp)
473         stq     t8,8*8(sp)
474         stq     t9,9*8(sp)
475         stq     t10,10*8(sp)
476         stq     v0,11*8(sp)
477         stq     a0,12*8(sp)
478         stq     a1,13*8(sp)
479         stq     a2,14*8(sp)
480         stq     a3,15*8(sp)
481         stq     a4,16*8(sp)
482         stq     a5,17*8(sp)
483
484         lda     t3,1(zero)            /* set no unwind flag                       */
485 ex_stack_loop:
486         lda     sp,-5*8(sp)           /* allocate stack                           */
487         stq     xptr,0*8(sp)          /* save used register                       */
488         stq     xpc,1*8(sp)
489         stq     pv,2*8(sp)
490         stq     ra,3*8(sp)
491         stq     t3,4*8(sp)
492
493         mov     xptr,a0
494         ldq     a1,MethodPointer(pv)
495         mov     xpc,a2
496         mov     t3,a3
497         br      ra,ex_trace           /* set ra for gp loading                    */
498 ex_trace:
499         ldgp    gp,0(ra)              /* load gp                                  */
500         jsr     ra,builtin_trace_exception /* trace_exception(xptr,methodptr)     */
501         
502         ldq     xptr,0*8(sp)          /* restore used register                    */
503         ldq     xpc,1*8(sp)
504         ldq     pv,2*8(sp)
505         ldq     ra,3*8(sp)
506         ldq     t3,4*8(sp)
507         lda     sp,5*8(sp)            /* deallocate stack                         */
508         
509         ldl     t0,ExTableSize(pv)    /* t0 = exception table size                */
510         beq     t0,empty_table        /* if empty table skip                      */
511         lda     t1,ExTableStart(pv)   /* t1 = start of exception table            */
512
513 ex_table_loop:
514         ldq     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
515         cmple   t2,xpc,t2             /* t2 = (startpc <= xpc)                    */
516         beq     t2,ex_table_cont      /* if (false) continue                      */
517         ldq     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
518         cmplt   xpc,t2,t2             /* t2 = (xpc < endpc)                       */
519         beq     t2,ex_table_cont      /* if (false) continue                      */
520         ldq     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
521         beq     a1,ex_handle_it       /* NULL catches everything                  */
522
523         ldq     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
524         ldq     a1,offobjvftbl(a1)    /* a1 = vftblptr(catchtype) class (not obj) */
525         ldl     a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
526         ldl     v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
527         ldl     a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
528         subl    a0,v0,a0              /* a0 = baseval(xptr) - baseval(catchtype)  */
529         cmpule  a0,a1,v0              /* v0 = xptr is instanceof catchtype        */
530         beq     v0,ex_table_cont      /* if (false) continue                      */
531
532 ex_handle_it:
533
534         ldq     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
535
536         beq     t3,ex_jump            /* if (!(no stack unwinding) skip           */
537
538         ldq     t0,0*8(sp)            /* restore possible used registers          */
539         ldq     t1,1*8(sp)            /* also registers used by trace_exception   */
540         ldq     t2,2*8(sp)
541         ldq     t3,3*8(sp)
542         ldq     t4,4*8(sp)
543         ldq     t5,5*8(sp)
544         ldq     t6,6*8(sp)
545         ldq     t7,7*8(sp)
546         ldq     t8,8*8(sp)
547         ldq     t9,9*8(sp)
548         ldq     t10,10*8(sp)
549         ldq     v0,11*8(sp)
550         ldq     a0,12*8(sp)
551         ldq     a1,13*8(sp)
552         ldq     a2,14*8(sp)
553         ldq     a3,15*8(sp)
554         ldq     a4,16*8(sp)
555         ldq     a5,17*8(sp)
556         lda     sp,18*8(sp)           /* deallocate stack                         */
557
558 ex_jump:
559         jmp     zero,(xpc)            /* jump to the handler                      */
560
561 ex_table_cont:
562         lda     t1,ExEntrySize(t1)    /* next exception table entry               */
563         subl    t0,1,t0               /* decrement entry counter                  */
564         bgt     t0,ex_table_loop      /* if (t0 > 0) next entry                   */
565
566 empty_table:
567         beq     t3,ex_already_cleared /* if here the first time, then             */
568         lda     sp,18*8(sp)           /* deallocate stack and                     */
569         clr     t3                    /* clear the no unwind flag                 */
570 ex_already_cleared:
571         ldl     t0,IsSync(pv)         /* t0 = SyncOffset                          */
572         beq     t0,no_monitor_exit    /* if zero no monitorexit                   */
573         addq    sp,t0,t0              /* add Offset to stackptr                   */
574         ldq     a0,-8(t0)             /* load monitorexit pointer                 */
575
576         lda     sp,-7*8(sp)           /* allocate stack                           */
577         stq     t0,0*8(sp)            /* save used register                       */
578         stq     t1,1*8(sp)
579         stq     t3,2*8(sp)
580         stq     xptr,3*8(sp)
581         stq     xpc,4*8(sp)
582         stq     pv,5*8(sp)
583         stq     ra,6*8(sp)
584
585         br      ra,ex_mon_load        /* set ra for gp loading                    */
586 ex_mon_load:
587         ldgp    gp,0(ra)              /* load gp                                  */
588         jsr     ra,builtin_monitorexit/* builtin_monitorexit(objectptr)           */
589         
590         ldq     t0,0*8(sp)            /* restore used register                    */
591         ldq     t1,1*8(sp)
592         ldq     t3,2*8(sp)
593         ldq     xptr,3*8(sp)
594         ldq     xpc,4*8(sp)
595         ldq     pv,5*8(sp)
596         ldq     ra,6*8(sp)
597         lda     sp,7*8(sp)            /* deallocate stack                         */
598
599 no_monitor_exit:
600         ldl     t0,FrameSize(pv)      /* t0 = frame size                          */
601         addq    sp,t0,sp              /* unwind stack                             */
602         mov     sp,t0                 /* t0 = pointer to save area                */
603         ldl     t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
604         bne     t1,ex_no_restore      /* if (leaf) skip                           */
605         ldq     ra,-8(t0)             /* restore ra                               */
606         lda     t0,-8(t0)             /* t0--                                     */
607 ex_no_restore:
608         mov     ra,xpc                /* the new xpc is ra                        */
609         ldl     t1,IntSave(pv)        /* t1 = saved int register count            */
610         br      t2,ex_int1            /* t2 = current pc                          */
611 ex_int1:
612         lda     t2,44(t2)             /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
613         negl    t1,t1                 /* negate register count                    */
614         s4addq  t1,t2,t2              /* t2 = ex_int_sav - 4 * register count     */
615         jmp     zero,(t2)             /* jump to save position                    */
616         ldq     s0,-56(t0)
617         ldq     s1,-48(t0)
618         ldq     s2,-40(t0)
619         ldq     s3,-32(t0)
620         ldq     s4,-24(t0)
621         ldq     s5,-16(t0)
622         ldq     s6,-8(t0)
623 ex_int2:
624         s8addq  t1,t0,t0              /* t0 = t0 - 8 * register count             */
625
626         ldl     t1,FltSave(pv)        /* t1 = saved flt register count            */
627         br      t2,ex_flt1            /* t2 = current pc                          */
628 ex_flt1:
629         lda     t2,48(t2)             /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
630         negl    t1,t1                 /* negate register count                    */
631         s4addq  t1,t2,t2              /* t2 = ex_flt_sav - 4 * register count     */
632         jmp     zero,(t2)             /* jump to save position                    */
633         ldt     $f2,-64(t0)
634         ldt     $f3,-56(t0)
635         ldt     $f4,-48(t0)
636         ldt     $f5,-40(t0)
637         ldt     $f6,-32(t0)
638         ldt     $f7,-24(t0)
639         ldt     $f8,-16(t0)
640         ldt     $f9,-8(t0)
641 ex_flt2:
642         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
643         sll     t0,48,t0
644         sra     t0,48,t0              /* isolate offset                           */
645         addq    t0,ra,pv              /* compute update address                   */
646         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
647         srl     t0,16,t0              /* isolate instruction code                 */
648         lda     t0,-0x177b(t0)        /* test for LDAH                            */
649         bne     t0,ex_stack_loop       
650         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
651         sll     t0,16,t0              /* compute high offset                      */
652         addl    t0,0,t0               /* sign extend high offset                  */
653         addq    t0,pv,pv              /* compute update address                   */
654         br      ex_stack_loop
655
656         .end    asm_handle_exception
657
658
659 /********************* function asm_signal_exception ***************************
660 *                                                                              *
661 *   This function handles an exception which was catched by a signal.          *
662 *                                                                              *
663 *   void asm_signal_exception (exceptionptr, signalcontext);                   *
664 *                                                                              *
665 *******************************************************************************/
666
667 #define     sigctxstack  0*8   /* sigstack state to restore                   */
668 #define     sigctxmask   1*8   /* signal mask to restore                      */
669 #define     sigctxpc     2*8   /* pc at time of signal                        */
670 #define     sigctxpsl    3*8   /* psl to retore                               */
671 #define     sigctxr00    4*8   /* processor regs 0 to 31                      */
672 #define     sigctxr01    5*8
673 #define     sigctxr02    6*8
674 #define     sigctxr03    7*8
675 #define     sigctxr04    8*8
676 #define     sigctxr05    9*8
677 #define     sigctxr06   10*8
678 #define     sigctxr07   11*8
679 #define     sigctxr08   12*8
680 #define     sigctxr09   13*8
681 #define     sigctxr10   14*8
682 #define     sigctxr11   15*8
683 #define     sigctxr12   16*8
684 #define     sigctxr13   17*8
685 #define     sigctxr14   18*8
686 #define     sigctxr15   19*8
687 #define     sigctxr16   20*8
688 #define     sigctxr17   21*8
689 #define     sigctxr18   22*8
690 #define     sigctxr19   23*8
691 #define     sigctxr20   24*8
692 #define     sigctxr21   25*8
693 #define     sigctxr22   26*8
694 #define     sigctxr23   27*8
695 #define     sigctxr24   28*8
696 #define     sigctxr25   29*8
697 #define     sigctxr26   30*8
698 #define     sigctxr27   31*8
699 #define     sigctxr28   32*8
700 #define     sigctxr29   33*8
701 #define     sigctxr30   34*8
702 #define     sigctxr31   35*8
703
704 #define     sigctxfpuse 36*8   /* fp has been used                            */
705 #define     sigctxf00   37*8   /* fp regs 0 to 31                             */
706 #define     sigctxf01   38*8
707 #define     sigctxf02   39*8
708 #define     sigctxf03   40*8
709 #define     sigctxf04   41*8
710 #define     sigctxf05   42*8
711 #define     sigctxf06   43*8
712 #define     sigctxf07   44*8
713 #define     sigctxf08   45*8
714 #define     sigctxf09   46*8
715 #define     sigctxf10   47*8
716 #define     sigctxf11   48*8
717 #define     sigctxf12   49*8
718 #define     sigctxf13   50*8
719 #define     sigctxf14   51*8
720 #define     sigctxf15   52*8
721 #define     sigctxf16   53*8
722 #define     sigctxf17   54*8
723 #define     sigctxf18   55*8
724 #define     sigctxf19   56*8
725 #define     sigctxf20   57*8
726 #define     sigctxf21   58*8
727 #define     sigctxf22   59*8
728 #define     sigctxf23   60*8
729 #define     sigctxf24   61*8
730 #define     sigctxf25   62*8
731 #define     sigctxf26   63*8
732 #define     sigctxf27   64*8
733 #define     sigctxf28   65*8
734 #define     sigctxf29   66*8
735 #define     sigctxf30   67*8
736 #define     sigctxf31   68*8
737
738 #define     sigctxhfpcr 69*8   /* floating point control register             */
739 #define     sigctxsfpcr 70*8   /* software fpcr                               */
740
741         .ent    asm_signal_exception
742 asm_signal_exception:
743
744         mov     a0,xptr
745         mov     a1,sp
746         ldq     xpc,sigctxpc(sp)
747         ldq     v0,sigctxr00(sp)   /* restore possible used registers             */
748         ldq     t0,sigctxr01(sp)
749         ldq     t1,sigctxr02(sp)
750         ldq     t2,sigctxr03(sp)
751         ldq     t3,sigctxr04(sp)
752         ldq     t4,sigctxr05(sp)
753         ldq     t5,sigctxr06(sp)
754         ldq     t6,sigctxr07(sp)
755         ldq     t7,sigctxr08(sp)
756         ldq     s0,sigctxr09(sp)
757         ldq     s1,sigctxr10(sp)
758         ldq     s2,sigctxr11(sp)
759         ldq     s3,sigctxr12(sp)
760         ldq     s4,sigctxr13(sp)
761         ldq     s5,sigctxr14(sp)
762         ldq     s6,sigctxr15(sp)
763         ldq     a0,sigctxr16(sp)
764         ldq     a1,sigctxr17(sp)
765         ldq     a2,sigctxr18(sp)
766         ldq     a3,sigctxr19(sp)
767         ldq     a4,sigctxr20(sp)
768         ldq     a5,sigctxr21(sp)
769         ldq     t8,sigctxr22(sp)
770         ldq     t9,sigctxr23(sp)
771         ldq     t10,sigctxr24(sp)
772         ldq     ra,sigctxr26(sp)
773         ldq     pv,sigctxr27(sp)
774         ldq     sp,sigctxr30(sp)
775         br      asm_handle_nat_exception
776         .end    asm_signal_exception
777
778
779 /********************* function asm_builtin_monitorenter ***********************
780 *                                                                              *
781 *   Does null check and calls monitorenter or throws an exception              *
782 *                                                                              *
783 *******************************************************************************/
784
785         .ent    asm_builtin_monitorenter
786 asm_builtin_monitorenter:
787
788         ldgp    gp,0(pv)
789         lda     pv,builtin_monitorenter
790         beq     a0,nb_monitorenter        /* if (null) throw exception            */
791         jmp     zero,(pv)                 /* else call builtin_monitorenter       */
792
793 nb_monitorenter:
794         ldq     xptr,proto_java_lang_NullPointerException
795         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
796         br      asm_handle_nat_exception
797         .end    asm_builtin_monitorenter
798
799
800 /********************* function asm_builtin_monitorexit ************************
801 *                                                                              *
802 *   Does null check and calls monitorexit or throws an exception               *
803 *                                                                              *
804 *******************************************************************************/
805
806         .ent    asm_builtin_monitorexit
807 asm_builtin_monitorexit:
808
809         ldgp    gp,0(pv)
810         lda     pv,builtin_monitorexit
811         beq     a0,nb_monitorexit         /* if (null) throw exception            */
812         jmp     zero,(pv)                 /* else call builtin_monitorexit        */
813
814 nb_monitorexit:
815         ldq     xptr,proto_java_lang_NullPointerException
816         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
817         br      asm_handle_nat_exception
818         .end    asm_builtin_monitorenter
819
820
821 /************************ function asm_builtin_idiv ****************************
822 *                                                                              *
823 *   Does null check and calls idiv or throws an exception                      *
824 *                                                                              *
825 *******************************************************************************/
826
827         .ent    asm_builtin_idiv
828 asm_builtin_idiv:
829
830         ldgp    gp,0(pv)
831         lda     pv,builtin_idiv
832         beq     a1,nb_idiv                /* if (null) throw exception            */
833         jmp     zero,(pv)                 /* else call builtin_idiv               */
834
835 nb_idiv:
836         ldq     xptr,proto_java_lang_ArithmeticException
837         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
838         br      asm_handle_nat_exception
839         .end    asm_builtin_idiv
840
841
842 /************************ function asm_builtin_ldiv ****************************
843 *                                                                              *
844 *   Does null check and calls ldiv or throws an exception                      *
845 *                                                                              *
846 *******************************************************************************/
847
848         .ent    asm_builtin_ldiv
849 asm_builtin_ldiv:
850
851         ldgp    gp,0(pv)
852         lda     pv,builtin_ldiv
853         beq     a1,nb_ldiv                /* if (null) throw exception            */
854         jmp     zero,(pv)                 /* else call builtin_ldiv               */
855
856 nb_ldiv:
857         ldq     xptr,proto_java_lang_ArithmeticException
858         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
859         br      asm_handle_nat_exception
860         .end    asm_builtin_ldiv
861
862
863 /************************ function asm_builtin_irem ****************************
864 *                                                                              *
865 *   Does null check and calls irem or throws an exception                      *
866 *                                                                              *
867 *******************************************************************************/
868
869         .ent    asm_builtin_irem
870 asm_builtin_irem:
871
872         ldgp    gp,0(pv)
873         lda     pv,builtin_irem
874         beq     a1,nb_irem                /* if (null) throw exception            */
875         jmp     zero,(pv)                 /* else call builtin_irem               */
876
877 nb_irem:
878         ldq     xptr,proto_java_lang_ArithmeticException
879         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
880         br      asm_handle_nat_exception
881         .end    asm_builtin_irem
882
883
884 /************************ function asm_builtin_lrem ****************************
885 *                                                                              *
886 *   Does null check and calls lrem or throws an exception                      *
887 *                                                                              *
888 *******************************************************************************/
889
890         .ent    asm_builtin_lrem
891 asm_builtin_lrem:
892
893         ldgp    gp,0(pv)
894         lda     pv,builtin_lrem
895         beq     a1,nb_lrem                /* if (null) throw exception            */
896         jmp     zero,(pv)                 /* else call builtin_lrem               */
897
898 nb_lrem:
899         ldq     xptr,proto_java_lang_ArithmeticException
900         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
901         br      asm_handle_nat_exception
902         .end    asm_builtin_lrem
903
904
905 /******************* function asm_builtin_checkarraycast ***********************
906 *                                                                              *
907 *   Does the cast check and eventually throws an exception                     *
908 *                                                                              *
909 *******************************************************************************/
910
911         .ent    asm_builtin_checkarraycast
912 asm_builtin_checkarraycast:
913
914         ldgp    gp,0(pv)
915         lda     sp,-16(sp)                /* allocate stack space                 */
916         stq     ra,0(sp)                  /* save return address                  */
917         stq     a0,8(sp)                  /* save object pointer                  */
918         jsr     ra,builtin_checkarraycast /* builtin_checkarraycast               */
919         ldgp    gp,0(ra)
920         beq     v0,nb_carray_throw        /* if (false) throw exception           */
921         ldq     ra,0(sp)                  /* restore return address               */
922         ldq     v0,8(sp)                  /* return object pointer                */
923         lda     sp,16(sp)                 /* free stack space                     */
924         jmp     zero,(ra)
925
926 nb_carray_throw:
927         ldq     xptr,proto_java_lang_ClassCastException
928         ldq     ra,0(sp)                  /* restore return address               */
929         lda     sp,16(sp)                 /* free stack space                     */
930         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
931         br      asm_handle_nat_exception
932         .end    asm_builtin_checkarraycast
933
934
935 /******************* function asm_builtin_aastore ******************************
936 *                                                                              *
937 *   Does the cast check and eventually throws an exception                     *
938 *                                                                              *
939 *******************************************************************************/
940
941         .ent    asm_builtin_aastore
942 asm_builtin_aastore:
943
944         ldgp    gp,0(pv)
945         beq     a0,nb_aastore_null        /* if null pointer throw exception      */
946         ldl     t0,offarraysize(a0)       /* load size                            */
947         lda     sp,-24(sp)                /* allocate stack space                 */
948         stq     ra,0(sp)                  /* save return address                  */
949         s8addq  a1,a0,t1                  /* add index*8 to arrayref              */
950         cmpult  a1,t0,t0                  /* do bound check                       */
951         beq     t0,nb_aastore_bound       /* if out of bounds throw exception     */
952         mov     a2,a1                     /* object is second argument            */
953         stq     t1,8(sp)                  /* save store position                  */
954         stq     a1,16(sp)                 /* save object                          */
955         jsr     ra,builtin_canstore       /* builtin_canstore(arrayref,object)    */
956         ldgp    gp,0(ra)
957         ldq     ra,0(sp)                  /* restore return address               */
958         ldq     a0,8(sp)                  /* restore store position               */
959         ldq     a1,16(sp)                 /* restore object                       */
960         lda     sp,24(sp)                 /* free stack space                     */
961         beq     v0,nb_aastore_throw       /* if (false) throw exception           */
962         stq     a1,offobjarrdata(a0)      /* store objectptr in array             */
963         jmp     zero,(ra)
964
965 nb_aastore_null:
966         ldq     xptr,proto_java_lang_NullPointerException
967         mov     ra,xpc                    /* faulting address is return adress    */
968         br      asm_handle_nat_exception
969
970 nb_aastore_bound:
971         ldq     xptr,proto_java_lang_ArrayIndexOutOfBoundsException
972         lda     sp,24(sp)                 /* free stack space                     */
973         mov     ra,xpc                    /* faulting address is return adress    */
974         br      asm_handle_nat_exception
975
976 nb_aastore_throw:
977         ldq     xptr,proto_java_lang_ArrayStoreException
978         mov     ra,xpc                    /* faulting address is return adress    */
979         br      asm_handle_nat_exception
980
981         .end    asm_builtin_aastore
982
983
984 /********************** function initialize_thread_stack ***********************
985 *                                                                              *
986 *   initialized a thread stack                                                 *
987 *                                                                              *
988 *******************************************************************************/
989
990         .ent    initialize_thread_stack
991 initialize_thread_stack:
992
993         lda     a1,-128(a1)
994         stq     zero, 0(a1)
995         stq     zero, 8(a1)
996         stq     zero, 16(a1)
997         stq     zero, 24(a1)
998         stq     zero, 32(a1)
999         stq     zero, 40(a1)
1000         stq     zero, 48(a1)
1001         stt     fzero, 56(a1)
1002         stt     fzero, 64(a1)
1003         stt     fzero, 72(a1)
1004         stt     fzero, 80(a1)
1005         stt     fzero, 88(a1)
1006         stt     fzero, 96(a1)
1007         stt     fzero, 104(a1)
1008         stt     fzero, 112(a1)
1009         stq     a0, 120(a1)
1010         mov     a1, v0
1011         jmp     zero,(ra)
1012         .end    initialize_thread_stack
1013
1014
1015 /******************* function perform_alpha_threadswitch ***********************
1016 *                                                                              *
1017 *   void perform_alpha_threadswitch (u1 **from, u1 **to, u1 **stackTop);       *
1018 *   performs a threadswitch                                                    *
1019 *                                                                              *
1020 *******************************************************************************/
1021
1022         .ent    perform_alpha_threadswitch
1023 perform_alpha_threadswitch:
1024
1025         subq    sp,128,sp                                 
1026         stq     s0, 0(sp)
1027         stq     s1, 8(sp)
1028         stq     s2, 16(sp)
1029         stq     s3, 24(sp)
1030         stq     s4, 32(sp)
1031         stq     s5, 40(sp)
1032         stq     s6, 48(sp)
1033         stt     sf0, 56(sp)
1034         stt     sf1, 64(sp)
1035         stt     sf2, 72(sp)
1036         stt     sf3, 80(sp)
1037         stt     sf4, 88(sp)
1038         stt     sf5, 96(sp)
1039         stt     sf6, 104(sp)
1040         stt     sf7, 112(sp)
1041         stq     ra, 120(sp)
1042         stq     sp, 0(a0)
1043         stq     sp, 0(a2)
1044         ldq     sp, 0(a1)
1045         ldq     s0, 0(sp)
1046         ldq     s1, 8(sp)
1047         ldq     s2, 16(sp)
1048         ldq     s3, 24(sp)
1049         ldq     s4, 32(sp)
1050         ldq     s5, 40(sp)
1051         ldq     s6, 48(sp)
1052         ldt     sf0, 56(sp)
1053         ldt     sf1, 64(sp)
1054         ldt     sf2, 72(sp)
1055         ldt     sf3, 80(sp)
1056         ldt     sf4, 88(sp)
1057         ldt     sf5, 96(sp)
1058         ldt     sf6, 104(sp)
1059         ldt     sf7, 112(sp)
1060         ldq     ra, 120(sp)
1061         mov     ra, t12
1062         addq    sp, 128, sp
1063         jmp     zero,(ra)
1064         .end    perform_alpha_threadswitch
1065
1066
1067 /********************* function asm_switchstackandcall *************************
1068 *                                                                              *
1069 *   Switches to a new stack, calls a function and switches back.               *
1070 *       a0      new stack pointer                                              *
1071 *       a1      function pointer                                               *
1072 *                                                                              *
1073 *******************************************************************************/
1074
1075
1076         .ent    asm_switchstackandcall
1077 asm_switchstackandcall:
1078         lda     a0,-2*8(a0)             /* allocate new stack                                 */
1079         stq     ra,0(a0)                /* save return address                                */
1080         stq     sp,1*8(a0)              /* save old stack pointer                             */
1081         mov     a0,sp                   /* switch to new stack                                */
1082         
1083         mov     a1,pv                   /* load function pointer                              */
1084         jmp     ra,(pv)                 /* and call funciton                                  */
1085
1086         ldq     ra,0(sp)                /* load return address                                */
1087         ldq     sp,1*8(sp)              /* switch to old stack                                */
1088
1089         jmp     zero,(ra)               /* return                                             */
1090
1091         .end    asm_switchstackandcall