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