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