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