- float register defines (couldn't find a header file at least on osf)
[cacao.git] / src / vm / jit / alpha / asmpart.S
1 /* src/vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29
30    Changes: Joseph Wenninger
31             Christian Thalinger
32
33    $Id: asmpart.S 2399 2005-04-27 12:53:03Z twisti $
34
35 */
36
37
38 #include "config.h"        
39 #include "vm/jit/alpha/offsets.h"
40 #include "vm/jit/alpha/asmoffsets.h"
41
42
43 #define v0      $0
44
45 #define t0      $1
46 #define t1      $2
47 #define t2      $3
48 #define t3      $4
49 #define t4      $5
50 #define t5      $6
51 #define t6      $7
52 #define t7      $8
53
54 #define s0      $9
55 #define s1      $10
56 #define s2      $11
57 #define s3      $12
58 #define s4      $13
59 #define s5      $14
60 #define s6      $15
61
62 #define a0      $16
63 #define a1      $17
64 #define a2      $18
65 #define a3      $19
66 #define a4      $20
67 #define a5      $21
68
69 #define t8      $22
70 #define t9      $23
71 #define t10     $24
72 #define t11     $25
73 #define ra      $26
74 #define t12     $27
75
76 #define pv      t12
77 #define AT      $at
78 #define gp      $29
79 #define sp      $30
80 #define zero    $31
81
82 #define itmp1   t11
83 #define itmp2   $28
84 #define itmp3   gp
85
86 #define xptr    itmp1
87 #define xpc     itmp2
88
89
90 #define ft0     $f1
91
92 #define fs0     $f2
93 #define fs1     $f3
94 #define fs2     $f4
95 #define fs3     $f5
96 #define fs4     $f6
97 #define fs5     $f7
98 #define fs6     $f8
99 #define fs7     $f9
100
101 #define ft1     $f10
102 #define ft2     $f11
103 #define ft3     $f12
104 #define ft4     $f13
105 #define ft5     $f14
106 #define ft6     $f15
107
108 #define fa0     $f16
109 #define fa1     $f17
110 #define fa2     $f18
111 #define fa3     $f19
112 #define fa4     $f20
113 #define fa5     $f21
114
115 #define ft7     $f22
116 #define ft8     $f23
117 #define ft9     $f24
118 #define ft10    $f25
119 #define ft11    $f26
120 #define ft12    $f27
121 #define ft13    $f28
122 #define ft14    $f29
123 #define ft15    $f20
124
125 #define fzero   $f31
126
127 #define ftmp1   ft13
128 #define ftmp2   ft14
129 #define ftmp3   ft15
130
131 #define PAL_imb 0x86
132
133
134 /* save and restore macros ****************************************************/
135
136 #define SAVE_ARGUMENT_REGISTERS(off) \
137         stq     a0,(0+(off))*8(sp)      ; \
138         stq     a1,(1+(off))*8(sp)      ; \
139         stq     a2,(2+(off))*8(sp)      ; \
140         stq     a3,(3+(off))*8(sp)      ; \
141         stq     a4,(4+(off))*8(sp)      ; \
142         stq     a5,(5+(off))*8(sp)      ; \
143         \
144         stt     fa0,(6+(off))*8(sp)     ; \
145         stt     fa1,(7+(off))*8(sp)     ; \
146         stt     fa2,(8+(off))*8(sp)     ; \
147         stt     fa3,(9+(off))*8(sp)     ; \
148         stt     fa4,(10+(off))*8(sp)    ; \
149         stt     fa5,(11+(off))*8(sp)    ;
150
151 #define RESTORE_ARGUMENT_REGISTERS(off) \
152         ldq     a0,(0+(off))*8(sp)      ; \
153         ldq     a1,(1+(off))*8(sp)      ; \
154         ldq     a2,(2+(off))*8(sp)      ; \
155         ldq     a3,(3+(off))*8(sp)      ; \
156         ldq     a4,(4+(off))*8(sp)      ; \
157         ldq     a5,(5+(off))*8(sp)      ; \
158         \
159         ldt     fa0,(6+(off))*8(sp)     ; \
160         ldt     fa1,(7+(off))*8(sp)     ; \
161         ldt     fa2,(8+(off))*8(sp)     ; \
162         ldt     fa3,(9+(off))*8(sp)     ; \
163         ldt     fa4,(10+(off))*8(sp)    ; \
164         ldt     fa5,(11+(off))*8(sp)    ;
165                 
166 #define SAVE_TEMPORARY_REGISTERS(off) \
167         stq     t0,(0+(off))*8(sp)       ; \
168         stq     t1,(1+(off))*8(sp)       ; \
169         stq     t2,(2+(off))*8(sp)       ; \
170         stq     t3,(3+(off))*8(sp)       ; \
171         stq     t4,(4+(off))*8(sp)       ; \
172         stq     t5,(5+(off))*8(sp)       ; \
173         stq     t6,(6+(off))*8(sp)       ; \
174         stq     t7,(7+(off))*8(sp)       ; \
175         stq     t8,(8+(off))*8(sp)       ; \
176         stq     t9,(9+(off))*8(sp)       ; \
177         stq     t10,(10+(off))*8(sp)     ; \
178         \
179         stt     ft0,(11+(off))*8(sp)     ; \
180         stt     ft1,(12+(off))*8(sp)     ; \
181         stt     ft2,(13+(off))*8(sp)     ; \
182         stt     ft3,(14+(off))*8(sp)     ; \
183         stt     ft4,(15+(off))*8(sp)     ; \
184         stt     ft5,(16+(off))*8(sp)     ; \
185         stt     ft6,(17+(off))*8(sp)     ; \
186         stt     ft7,(18+(off))*8(sp)     ; \
187         stt     ft8,(19+(off))*8(sp)     ; \
188         stt     ft9,(20+(off))*8(sp)     ; \
189         stt     ft10,(21+(off))*8(sp)    ; \
190         stt     ft11,(22+(off))*8(sp)    ; \
191         stt     ft12,(23+(off))*8(sp)    ; \
192         stt     ft13,(24+(off))*8(sp)    ; \
193         stt     ft14,(25+(off))*8(sp)    ; \
194         stt     ft15,(26+(off))*8(sp)    ; 
195
196
197 #define RESTORE_TEMPORARY_REGISTERS(off) \
198         ldq     t0,(0+(off))*8(sp)       ; \
199         ldq     t1,(1+(off))*8(sp)       ; \
200         ldq     t2,(2+(off))*8(sp)       ; \
201         ldq     t3,(3+(off))*8(sp)       ; \
202         ldq     t4,(4+(off))*8(sp)       ; \
203         ldq     t5,(5+(off))*8(sp)       ; \
204         ldq     t6,(6+(off))*8(sp)       ; \
205         ldq     t7,(7+(off))*8(sp)       ; \
206         ldq     t8,(8+(off))*8(sp)       ; \
207         ldq     t9,(9+(off))*8(sp)       ; \
208         ldq     t10,(10+(off))*8(sp)     ; \
209         \
210         ldt     ft0,(11+(off))*8(sp)     ; \
211         ldt     ft1,(12+(off))*8(sp)     ; \
212         ldt     ft2,(13+(off))*8(sp)     ; \
213         ldt     ft3,(14+(off))*8(sp)     ; \
214         ldt     ft4,(15+(off))*8(sp)     ; \
215         ldt     ft5,(16+(off))*8(sp)     ; \
216         ldt     ft6,(17+(off))*8(sp)     ; \
217         ldt     ft7,(18+(off))*8(sp)     ; \
218         ldt     ft8,(19+(off))*8(sp)     ; \
219         ldt     ft9,(20+(off))*8(sp)     ; \
220         ldt     ft10,(21+(off))*8(sp)    ; \
221         ldt     ft11,(22+(off))*8(sp)    ; \
222         ldt     ft12,(23+(off))*8(sp)    ; \
223         ldt     ft13,(24+(off))*8(sp)    ; \
224         ldt     ft14,(25+(off))*8(sp)    ; \
225         ldt     ft15,(26+(off))*8(sp)    ; 
226
227
228         .text
229         .set    noat
230         .set    noreorder
231
232
233 /********************* exported functions and variables ***********************/
234
235         .globl asm_sync_instruction_cache
236         .globl has_no_x_instr_set
237
238         .globl asm_calljavafunction
239         .globl asm_calljavafunction_int
240
241         .globl asm_calljavafunction2
242         .globl asm_calljavafunction2int
243         .globl asm_calljavafunction2long
244         .globl asm_calljavafunction2float
245         .globl asm_calljavafunction2double
246
247         .globl asm_call_jit_compiler
248         .globl asm_throw_and_handle_exception
249         .globl asm_throw_and_handle_nat_exception
250         .globl asm_throw_and_handle_arithmetic_exception
251         .globl asm_throw_and_handle_arrayindexoutofbounds_exception
252         .globl asm_handle_exception
253         .globl asm_handle_nat_exception
254
255         .globl asm_wrapper_patcher
256
257         .globl asm_builtin_checkarraycast
258         .globl asm_builtin_aastore
259
260         .globl asm_builtin_idiv
261         .globl asm_builtin_irem
262         .globl asm_builtin_ldiv
263         .globl asm_builtin_lrem
264
265         .globl asm_perform_threadswitch
266         .globl asm_initialize_thread_stack
267         .globl asm_switchstackandcall
268         .globl asm_criticalsections
269         .globl asm_getclassvalues_atomic
270         .globl asm_prepare_native_stackinfo
271         .globl asm_remove_native_stackinfo
272         .globl asm_refillin_and_handle_exception
273
274
275 /* asm_sync_instruction_cache **************************************************
276
277    XXX
278
279 *******************************************************************************/
280
281         .ent    asm_sync_instruction_cache
282
283 asm_sync_instruction_cache:
284         call_pal PAL_imb              /* synchronize instruction cache            */
285         jmp     zero,(ra)
286
287         .end    asm_sync_instruction_cache
288
289 /*********************** function has_no_x_instr_set ***************************
290 *                                                                              *
291 *   determines if the byte support instruction set (21164a and higher)         *
292 *   is available.                                                              *
293 *                                                                              *
294 *******************************************************************************/
295
296         .ent    has_no_x_instr_set
297 has_no_x_instr_set:
298
299         .long   0x47e03c20                /* amask   1,v0                         */
300         jmp     zero,(ra)                 /* return                               */
301
302         .end    has_no_x_instr_set
303
304
305 /********************* function asm_calljavafunction ***************************
306 *                                                                              *
307 *   This function calls a Java-method (which possibly needs compilation)       *
308 *   with up to 4 address parameters.                                           *
309 *                                                                              *
310 *   This functions calls the JIT-compiler which eventually translates the      *
311 *   method into machine code.                                                  *
312 *                                                                              *
313 *   C-prototype:                                                               *
314 *    javaobject_header *asm_calljavafunction (methodinfo *m,                   *
315 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
316 *                                                                              *
317 *******************************************************************************/
318
319         .ent    asm_calljavafunction
320
321 call_name:
322         .ascii  "calljavafunction\0\0"
323
324         .align  2 /*3*/
325         .quad   0                         /* catch type all                       */
326         .quad   calljava_xhandler         /* handler pc                           */
327         .quad   calljava_xhandler         /* end pc                               */
328         .quad   asm_calljavafunction      /* start pc                             */
329         .long   1                         /* extable size                         */
330         .long   0                         /* PADDING */
331         .quad   0                         /* line number table start             */
332         .quad   0                         /* line number table size             */
333         .long   0                         /* PADDING */
334         .long   0                         /* fltsave */
335         .long   0                         /* intsave                              */
336         .long   0                         /* isleaf                               */
337         .long   0                         /* IsSync                               */
338         .long   32                        /* frame size                           */
339         .quad   0                         /* method pointer (pointer to name)     */
340
341 asm_calljavafunction:
342 asm_calljavafunction_int:
343         ldgp    gp,0(pv)
344         lda     sp,-32(sp)                /* allocate stack space                 */
345         stq     gp,24(sp)                 /* save global pointer                  */
346         stq     ra,0(sp)                  /* save return address                  */
347
348         stq     a0,16(sp)                 /* save method pointer for compiler     */
349         lda     v0,16(sp)                 /* pass pointer to method pointer via v0*/
350
351         mov     a1,a0                     /* pass the remaining parameters        */
352         mov     a2,a1
353         mov     a3,a2
354         mov     a4,a3
355
356         lda     $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
357         stq     $28,8(sp)                 /* store function address               */
358         mov     sp,$28                    /* set method pointer                   */
359
360         ldq     pv,8($28)                 /* method call as in Java               */
361         jmp     ra,(pv)                   /* call JIT compiler                    */
362 calljava_jit:
363         lda     pv,-64(ra)                /* asm_calljavafunction-calljava_jit !!!!!*/
364
365 calljava_return:
366         ldq     ra,0(sp)                  /* restore return address               */
367         ldq     gp,24(sp)                 /* restore global pointer               */
368         lda     sp,32(sp)                 /* free stack space                     */
369
370 calljava_ret:
371         jmp     zero,(ra)
372
373 calljava_xhandler:
374         ldq     gp,24(sp)                 /* restore global pointer               */
375         mov     xptr,a0
376         jsr     ra,builtin_throw_exception
377         ldq     ra,0(sp)                  /* restore return address               */
378         lda     sp,32(sp)                 /* free stack space                     */
379         mov     zero,v0                   /* return NULL                          */
380         jmp     zero,(ra)
381         .end    asm_calljavafunction
382
383
384
385
386         .ent    asm_calljavafunction2
387
388 call_name2:
389         .align  3
390
391         .quad   0                         /* catch type all                       */
392         .quad   calljava_xhandler2        /* handler pc                           */
393         .quad   calljava_xhandler2        /* end pc                               */
394         .quad   asm_calljavafunction2     /* start pc                             */
395         .long   1                         /* extable size                         */
396         .long   0                         /* PADDING */
397         .quad   0                         /* line number table start             */
398         .quad   0                         /* line number table size             */
399         .long   0                         /* PADDING */
400         .long   0                         /* fltsave                              */
401         .long   1                         /* intsave                              */
402         .long   0                         /* isleaf                               */
403         .long   0                         /* IsSync                               */
404         .long   40                        /* frame size                           */
405         .quad   0                         /* method pointer (pointer to name)     */
406
407 asm_calljavafunction2:
408 asm_calljavafunction2int:
409 asm_calljavafunction2long:
410 asm_calljavafunction2float:
411 asm_calljavafunction2double:
412         ldgp    gp,0(pv)
413         lda     sp,-40(sp)                /* allocate stack space                 */
414         stq     ra,0(sp)                  /* save return address                  */
415         stq     s6,24(sp)
416         stq     gp,8(sp)                  /* save global pointer                  */
417
418         stq     a0,32(sp)                 /* save method pointer for compiler     */
419         mov     a3,t0                     /* pointer to arg block                 */
420         mov     a1,s6                     /* arg count                            */
421
422         ble     s6,calljava_argsloaded
423         lda     s6,-1(s6)
424         ldq     a0,offjniitem(t0)
425         ldt     $f16,offjniitem(t0)
426         ble     s6,calljava_argsloaded
427         lda     s6,-1(s6)
428         ldq     a1,offjniitem+sizejniblock*1(t0)
429         ldt     $f17,offjniitem+sizejniblock*1(t0)
430         ble     s6,calljava_argsloaded
431         lda     s6,-1(s6)
432         ldq     a2,offjniitem+sizejniblock*2(t0)
433         ldt     $f18,offjniitem+sizejniblock*2(t0)
434         ble     s6,calljava_argsloaded
435         lda     s6,-1(s6)
436         ldq     a3,offjniitem+sizejniblock*3(t0)
437         ldt     $f19,offjniitem+sizejniblock*3(t0)
438         ble     s6,calljava_argsloaded
439         lda     s6,-1(s6)
440         ldq     a4,offjniitem+sizejniblock*4(t0)
441         ldt     $f20,offjniitem+sizejniblock*4(t0)
442         ble     s6,calljava_argsloaded
443         lda     s6,-1(s6)
444         ldq     a5,offjniitem+sizejniblock*5(t0)
445         ldt     $f21,offjniitem+sizejniblock*5(t0)
446 calljava_argsloaded:
447         mov     sp,t4
448         ble     s6,calljava_nocopy
449         negq    s6,t1
450         s8addq  t1,sp,sp
451         s8addq  t1,t4,t2
452
453 calljava_copyloop:
454         ldq     t3,offjniitem+sizejniblock*6(t0)
455         stq     t3,0(t2)
456         lda     t1,1(t1)
457         lda     t0,sizejniblock(t0)
458         lda     t2,8(t2)
459         bne     t1,calljava_copyloop
460
461 calljava_nocopy:
462         lda     v0,32(t4)                 /* pass pointer to method pointer via v0*/
463
464         lda     $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
465         stq     $28,16(t4)                /* store function address               */
466         lda     $28,8(t4)                 /* set method pointer                   */
467
468         ldq     pv,8($28)                 /* method call as in Java               */
469         jmp     ra,(pv)                   /* call JIT compiler                    */
470 calljava_jit2:
471         lda     pv,-200(ra)               /* asm_calljavafunction-calljava_jit !!!*/
472
473         s8addq  s6,sp,sp
474 calljava_return2:
475         ldq     ra,0(sp)                  /* restore return address               */
476         ldq     gp,8(sp)                  /* restore global pointer               */
477         ldq     s6,24(sp)
478         lda     sp,40(sp)                 /* free stack space                     */
479
480 calljava_ret2:
481         jmp     zero,(ra)
482
483 calljava_xhandler2:
484         s8addq  s6,sp,sp
485         ldq     gp,8(sp)                  /* restore global pointer               */
486         mov     itmp1,a0
487         jsr     ra,builtin_throw_exception
488         ldq     ra,0(sp)                  /* restore return address               */
489         ldq     s6,24(sp)
490         lda     sp,40(sp)                 /* free stack space                     */
491         mov     zero,v0                   /* return NULL                          */
492         jmp     zero,(ra)
493         .end    asm_calljavafunction2
494
495
496 /****************** function asm_call_jit_compiler *****************************
497 *                                                                              *
498 *   invokes the compiler for untranslated JavaVM methods.                      *
499 *                                                                              *
500 *   Register R0 contains a pointer to the method info structure (prepared      *
501 *   by createcompilerstub). Using the return address in R26 and the            *
502 *   offset in the LDA instruction or using the value in methodptr R28 the      *
503 *   patching address for storing the method address can be computed:           *
504 *                                                                              *
505 *   method address was either loaded using                                     *
506 *   M_LDQ (REG_PV, REG_PV, a)        ; invokestatic/special    ($27)           *
507 *   M_LDA (REG_PV, REG_RA, low)                                                *
508 *   M_LDAH(REG_PV, REG_RA, high)     ; optional                                *
509 *   or                                                                         *
510 *   M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28)           *
511 *   in the static case the method pointer can be computed using the            *
512 *   return address and the lda function following the jmp instruction          *
513 *                                                                              *
514 *******************************************************************************/
515
516         .ent    asm_call_jit_compiler
517
518 asm_call_jit_compiler:
519         ldgp    gp,0(pv)
520         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
521         srl     t8,16,t8              /* shift right register number $yy          */
522         and     t8,31,t8              /* isolate register number                  */
523         subl    t8,28,t8              /* test for REG_METHODPTR                   */
524         beq     t8,noregchange       
525         ldl     t8,0(ra)              /* load instruction LDA PV,xxx(RA)          */
526         sll     t8,48,t8
527         sra     t8,48,t8              /* isolate offset                           */
528         addq    t8,ra,$28             /* compute update address                   */
529         ldl     t8,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
530         srl     t8,16,t8              /* isolate instruction code                 */
531         lda     t8,-0x177b(t8)        /* test for LDAH                            */
532         bne     t8,noregchange       
533         ldl     t8,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
534         sll     t8,16,t8              /* compute high offset                      */
535         addl    t8,0,t8               /* sign extend high offset                  */
536         addq    t8,$28,$28            /* compute update address                   */
537 noregchange:
538         lda     sp,-14*8(sp)          /* reserve stack space                      */
539
540         SAVE_ARGUMENT_REGISTERS(0)    /* save 6 int/6 float argument registers    */
541
542         stq     $28,12*8(sp)          /* save method pointer                      */
543         stq     ra,13*8(sp)           /* save return address                      */
544
545         ldq     a0,0(v0)              /* pass 'methodinfo' pointer to             */
546         jsr     ra,jit_compile        /* jit compiler                             */
547         ldgp    gp,0(ra)
548
549         RESTORE_ARGUMENT_REGISTERS(0) /* restore 6 int/6 float argument registers */
550
551         ldq     $28,12*8(sp)          /* load method pointer                      */
552         ldq     ra,13*8(sp)           /* load return address                      */
553         lda     sp,14*8(sp)           /* deallocate stack area                    */
554
555         beq     v0,asm_call_jit_compiler_exception
556
557         ldl     t8,-8(ra)             /* load instruction LDQ PV,xxx($yy)         */
558         sll     t8,48,t8
559         sra     t8,48,t8              /* isolate offset                           */
560
561         addq    t8,$28,t8             /* compute update address via method pointer*/
562         stq     v0,0(t8)              /* save new method address there            */
563
564         call_pal PAL_imb              /* synchronise instruction cache            */
565
566         mov     v0,pv                 /* load method address into pv              */
567         jmp     zero,(pv)             /* and call method. The method returns      */
568                                       /* directly to the caller (ra).             */
569
570 asm_call_jit_compiler_exception:
571 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
572         subq    sp,1*8,sp
573         stq     ra,0*8(sp)
574         jsr     ra,builtin_asm_get_exceptionptrptr
575         ldq     ra,0*8(sp)
576         addq    sp,1*8,sp
577 #else
578         lda     v0,_exceptionptr
579 #endif
580         ldq     xptr,0(v0)            /* get the exception pointer                */
581         stq     zero,0(v0)            /* clear the exception pointer              */
582
583         subq    ra,4,xpc
584         br      asm_handle_nat_exception
585
586         .end    asm_call_jit_compiler
587
588
589 /**************** function asm_refillin_and_handle_exception *******************
590 *                                                                              *
591 *   This function handles an exception. It does not use the usual calling      *
592 *   conventions. The exception is passed in REG_ITMP1 and the                  *
593 *   pc from the exception raising position is passed in REG_ITMP2.             *
594 *   a0 contains the PV of the function causing the problem                     *
595 *                                                                              *
596 *   void asm_handle_arithmetic_exception (exceptionclass, exceptionpc);        *
597 *                                                                              *
598 *******************************************************************************/
599         .ent asm_refillin_and_handle_exception
600 asm_refillin_and_handle_exception:
601         ldgp    gp,0(pv)
602         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
603         sll     t0,48,t0
604         sra     t0,48,t0              /* isolate offset                           */
605         addq    t0,ra,pv              /* compute update address                   */
606         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
607         srl     t0,16,t0              /* isolate instruction code                 */
608         lda     t0,-0x177b(t0)        /* test for LDAH                            */
609         bne     t0, asm_refillin_and_handle_exception_cont
610         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
611         sll     t0,16,t0              /* compute high offset                      */
612         addl    t0,0,t0               /* sign extend high offset                  */
613         addq    t0,pv,pv              /* compute update address                   */
614
615 asm_refillin_and_handle_exception_cont:
616
617         mov     sp,t0
618         lda     sp,-6*8(sp) /* prepare stackframe*/
619         stq     pv,5*8(sp) /* store pv of caller */
620         stq     xptr,4*8(sp) /*exception ptr*/
621         stq     xpc,3*8(sp) /*address of failure*/
622         stq     t0,2*8(sp) /*begin of java stack frame*/
623         stq     pv,1*8(sp) /* store pv of caller */
624         stq     zero,0*8(sp)    /*builtin (invisible) function */
625         jsr     ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
626         ldgp    gp,0(ra)
627
628         ldq     a2,utf_void__java_lang_Throwable
629         ldq     a1,utf_fillInStackTrace
630         ldq     t0,6*8(sp)
631         ldq     t1,offobjvftbl(t0)      
632         ldq     a0,offclass(t1)
633         jsr     ra,class_resolvemethod
634         ldgp    gp,0(ra)
635         /* now we have the method */
636
637         /*refillin */
638         mov     v0,a0
639         ldq     a1,6*8(sp)
640         jsr     ra,asm_calljavafunction
641         ldgp    gp,0(ra)
642
643         /*remove frame*/
644         jsr ra,asm_remove_native_stackinfo
645         ldgp    gp,0(ra)
646
647
648         /*finish*/
649         ldq     xpc,0(sp)       
650         ldq     xptr,1*8(sp)
651         ldq     pv,2*8(sp)
652         lda sp,3*8(sp)
653         br asm_handle_exception
654
655         .end asm_refillin_and_handle_exception
656
657 /****** function asm_throw_and_handle_arrayindexoutofbounds_exception **********
658 *                                                                              *
659 *   This function handles an exception. It does not use the usual calling      *
660 *   conventions. The integer parameter is passed in REG_ITMP1 and the          *
661 *   pc from the exception raising position is passed in REG_ITMP2.             *
662 *                                                                              *
663 *   void asm_handle_arithmetic_exception (exceptionclass, exceptionpc);        *
664 *                                                                              *
665 *******************************************************************************/
666
667         .ent asm_throw_and_handle_arrayindexoutofbounds_exception
668
669 asm_throw_and_handle_arrayindexoutofbounds_exception:
670         ldgp    gp,0(pv)
671
672         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
673         sll     t0,48,t0
674         sra     t0,48,t0              /* isolate offset                           */
675         addq    t0,ra,pv              /* compute update address                   */
676         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
677         srl     t0,16,t0              /* isolate instruction code                 */
678         lda     t0,-0x177b(t0)        /* test for LDAH                            */
679         bne     t0,asm_throw_and_handle_arrayindexoutofbounds_exception_cont
680         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
681         sll     t0,16,t0              /* compute high offset                      */
682         addl    t0,0,t0               /* sign extend high offset                  */
683         addq    t0,pv,pv              /* compute update address                   */
684
685 asm_throw_and_handle_arrayindexoutofbounds_exception_cont:
686         mov     sp,t0
687         lda     sp,-6*8(sp) /*prepare stackframe*/
688         stq     pv,5*8(sp)  /*pv of failure*/
689         stq     itmp1,4*8(sp) /*int parameter  of the exception*/
690         stq     xpc,3*8(sp) /*address of failure */
691         stq     t0,2*8(sp) /*store begin of java stack frame*/
692         stq     pv,1*8(sp) /*store pv of caller in structure*/
693         stq     zero,0*8(sp) /*builtin (invisible function)*/
694
695         jsr     ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
696         ldgp    gp,0(ra)
697
698         ldq     a0,6*8(sp)  /*int  of exception*/
699         jsr     ra,new_arrayindexoutofboundsexception
700         ldgp    gp,0(ra)
701
702         mov     v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
703
704         jsr     ra,asm_remove_native_stackinfo
705         ldgp    gp,0(ra)
706
707         ldq     itmp2,0(sp)     
708         ldq     pv,2*8(sp)
709         lda     sp,3*8(sp)
710         br      asm_handle_exception
711
712         .end asm_throw_and_handle_arrayindexoutofbounds_exception
713
714
715 /* asm_throw_and_handle_arithmetic_exception ***********************************
716
717    DOCUMENT ME!
718
719 *******************************************************************************/
720
721         .ent asm_throw_and_handle_arithmetic_exception
722
723 asm_throw_and_handle_arithmetic_exception:
724         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
725         sll     t0,48,t0
726         sra     t0,48,t0              /* isolate offset                           */
727         addq    t0,ra,pv              /* compute update address                   */
728         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
729         srl     t0,16,t0              /* isolate instruction code                 */
730         lda     t0,-0x177b(t0)        /* test for LDAH                            */
731         bne     t0,asm_throw_and_handle_arithmetic_exception_cont
732         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
733         sll     t0,16,t0              /* compute high offset                      */
734         addl    t0,0,t0               /* sign extend high offset                  */
735         addq    t0,pv,pv              /* compute update address                   */
736
737 asm_throw_and_handle_arithmetic_exception_cont:
738         mov     sp,t0
739         lda     sp,-6*8(sp) /*prepare stackframe*/
740         stq     pv,5*8(sp)  /*pv of failure*/
741         stq     itmp1,4*8(sp) /*exception string of the exception*/
742         stq     xpc,3*8(sp) /*address of failure */
743         stq     t0,2*8(sp) /*store begin of java stack frame*/
744         stq     pv,1*8(sp) /*store pv of caller in structure*/
745         stq     zero,0*8(sp) /*builtin (invisible function)*/
746         jsr     ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
747         ldgp    gp,0(ra)
748
749         jsr     ra,new_arithmeticexception
750         ldgp    gp,0(ra)
751         mov     v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
752
753         jsr ra,asm_remove_native_stackinfo
754         ldgp    gp,0(ra)
755
756         ldq itmp2,0(sp) 
757         ldq    pv,2*8(sp)
758         lda sp,3*8(sp)
759         br asm_handle_exception
760
761         .end asm_throw_and_handle_arithmetic_exception
762
763
764 /* asm_throw_and_handle_exception **********************************************
765
766    DOCUMENT ME!!!
767
768 *******************************************************************************/
769
770         .ent asm_throw_and_handle_nat_exception
771
772 asm_throw_and_handle_nat_exception:
773         ldgp    gp,0(pv)
774         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
775         sll     t0,48,t0
776         sra     t0,48,t0              /* isolate offset                           */
777         addq    t0,ra,pv              /* compute update address                   */
778         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
779         srl     t0,16,t0              /* isolate instruction code                 */
780         lda     t0,-0x177b(t0)        /* test for LDAH                            */
781         bne     t0,asm_throw_and_handle_exception
782         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
783         sll     t0,16,t0              /* compute high offset                      */
784         addl    t0,0,t0               /* sign extend high offset                  */
785         addq    t0,pv,pv              /* compute update address                   */
786
787         .aent asm_throw_and_handle_exception
788
789 asm_throw_and_handle_exception:
790         mov     sp,t0
791         lda     sp,-6*8(sp)           /* prepare stackframe                       */
792         stq     pv,5*8(sp)            /* pv of failure                            */
793         stq     xptr,4*8(sp)          /* classname of the exception               */
794         stq     xpc,3*8(sp)           /* address of failure                       */
795         stq     t0,2*8(sp)            /* store begin of java stack frame          */
796         stq     pv,1*8(sp)            /* store pv of caller in structure          */
797         stq     zero,0*8(sp)          /* builtin (invisible function)             */
798                                       /* puts 2 additional quadwords on stack     */
799
800         br      ra,L_asm_throw_and_handle_exception_load_gp
801 L_asm_throw_and_handle_exception_load_gp:
802         ldgp    gp,0(ra)              /* load gp (it's not set correctly in jit)  */
803
804         jsr     ra,asm_prepare_native_stackinfo
805         ldgp    gp,0(ra)
806
807         ldq     a0,6*8(sp)            /* classname of exception                   */
808         jsr     ra,new_exception
809         ldgp    gp,0(ra)
810
811         mov     v0,xptr               /* xptr (itmp1) is not touched in           */
812                                       /* asm_remove_native_stackinfo              */
813
814         jsr     ra,asm_remove_native_stackinfo
815         ldgp    gp,0(ra)
816
817         ldq     itmp2,0(sp)
818         ldq     pv,2*8(sp)
819         lda     sp,3*8(sp)
820         br      asm_handle_exception
821
822         .end asm_throw_and_handle_nat_exception
823
824
825 /********************* function asm_handle_exception ***************************
826 *                                                                              *
827 *   This function handles an exception. It does not use the usual calling      *
828 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
829 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
830 *   the local exception table for a handler. If no one is found, it unwinds    *
831 *   stacks and continues searching the callers.                                *
832 *                                                                              *
833 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
834 *                                                                              *
835 *******************************************************************************/
836
837         .ent    asm_handle_nat_exception
838
839 asm_handle_nat_exception:
840         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
841         sll     t0,48,t0
842         sra     t0,48,t0              /* isolate offset                           */
843         addq    t0,ra,pv              /* compute update address                   */
844         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
845         srl     t0,16,t0              /* isolate instruction code                 */
846         lda     t0,-0x177b(t0)        /* test for LDAH                            */
847         bne     t0,asm_handle_exception
848         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
849         sll     t0,16,t0              /* compute high offset                      */
850         addl    t0,0,t0               /* sign extend high offset                  */
851         addq    t0,pv,pv              /* compute update address                   */
852
853         .aent    asm_handle_exception
854
855 asm_handle_exception:
856         lda     sp,-18*8(sp)          /* allocate stack                           */
857         stq     t0,0*8(sp)            /* save possible used registers             */
858         stq     t1,1*8(sp)            /* also registers used by trace_exception   */
859         stq     t2,2*8(sp)
860         stq     t3,3*8(sp)
861         stq     t4,4*8(sp)
862         stq     t5,5*8(sp)
863         stq     t6,6*8(sp)
864         stq     t7,7*8(sp)
865         stq     t8,8*8(sp)
866         stq     t9,9*8(sp)
867         stq     t10,10*8(sp)
868         stq     v0,11*8(sp)
869         stq     a0,12*8(sp)
870         stq     a1,13*8(sp)
871         stq     a2,14*8(sp)
872         stq     a3,15*8(sp)
873         stq     a4,16*8(sp)
874         stq     a5,17*8(sp)
875
876         lda     t3,1(zero)            /* set no unwind flag                       */
877 ex_stack_loop:
878         lda     sp,-5*8(sp)           /* allocate stack                           */
879         stq     xptr,0*8(sp)          /* save used register                       */
880         stq     xpc,1*8(sp)
881         stq     pv,2*8(sp)
882         stq     ra,3*8(sp)
883         stq     t3,4*8(sp)
884
885         mov     xptr,a0
886         ldq     a1,MethodPointer(pv)
887         mov     xpc,a2
888 /*      mov     t3,a3 */
889         lda             a3,0(zero)
890         lda             a4,1(zero)
891         br      ra,ex_trace           /* set ra for gp loading                    */
892 ex_trace:
893         ldgp    gp,0(ra)              /* load gp                                  */
894         jsr     ra,builtin_trace_exception /* trace_exception(xptr,methodptr)     */
895         
896         ldq     xptr,0*8(sp)          /* restore used register                    */
897         ldq     xpc,1*8(sp)
898         ldq     pv,2*8(sp)
899         ldq     ra,3*8(sp)
900         ldq     t3,4*8(sp)
901         lda     sp,5*8(sp)            /* deallocate stack                         */
902         
903         ldl     t0,ExTableSize(pv)    /* t0 = exception table size                */
904         beq     t0,empty_table        /* if empty table skip                      */
905
906         lda     t1,ExTableStart(pv)   /* t1 = start of exception table            */
907
908 ex_table_loop:
909         ldq     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
910         cmple   t2,xpc,t2             /* t2 = (startpc <= xpc)                    */
911         beq     t2,ex_table_cont      /* if (false) continue                      */
912         ldq     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
913         cmplt   xpc,t2,t2             /* t2 = (xpc < endpc)                       */
914         beq     t2,ex_table_cont      /* if (false) continue                      */
915         ldq     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
916         beq     a1,ex_handle_it       /* NULL catches everything                  */
917
918         ldl     itmp3,offclassloaded(a1)
919         bne     itmp3,L_class_loaded
920
921         subq    sp,8*8,sp             /* allocate stack                           */
922         stq     t0,0*8(sp)            /* save used register                       */
923         stq     t1,1*8(sp)
924         stq     t3,2*8(sp)
925         stq     xptr,3*8(sp)
926         stq     xpc,4*8(sp)
927         stq     pv,5*8(sp)
928         stq     ra,6*8(sp)
929         stq     a1,7*8(sp)
930
931         mov     a1,a0
932
933         br      ra,L_class_load_ra    /* set ra for gp loading                    */
934 L_class_load_ra:
935         ldgp    gp,0(ra)              /* load gp                                  */
936         jsr     ra,load_class_bootstrap
937
938         ldq     t0,0*8(sp)            /* restore used register                    */
939         ldq     t1,1*8(sp)
940         ldq     t3,2*8(sp)
941         ldq     xptr,3*8(sp)
942         ldq     xpc,4*8(sp)
943         ldq     pv,5*8(sp)
944         ldq     ra,6*8(sp)
945         ldq     a1,7*8(sp)
946         addq    sp,8*8,sp             /* deallocate stack                         */
947
948 L_class_loaded:
949         ldl     itmp3,offclasslinked(a1)
950         subq    sp,8*8,sp             /* allocate stack                           */
951         stq     a1,7*8(sp)
952         bne     itmp3,L_class_linked
953
954         stq     t0,0*8(sp)            /* save used register                       */
955         stq     t1,1*8(sp)
956         stq     t3,2*8(sp)
957         stq     xptr,3*8(sp)
958         stq     xpc,4*8(sp)
959         stq     pv,5*8(sp)
960         stq     ra,6*8(sp)
961
962         mov     a1,a0
963
964         br      ra,L_class_link_ra    /* set ra for gp loading                    */
965 L_class_link_ra:
966         ldgp    gp,0(ra)              /* load gp                                  */
967         jsr     ra,link_class
968
969         ldq     t0,0*8(sp)            /* restore used register                    */
970         ldq     t1,1*8(sp)
971         ldq     t3,2*8(sp)
972         ldq     xptr,3*8(sp)
973         ldq     xpc,4*8(sp)
974         ldq     pv,5*8(sp)
975         ldq     ra,6*8(sp)
976
977 L_class_linked:
978 _crit_restart1:
979         ldq     a1,7*8(sp)
980 _crit_begin1:
981         ldq     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
982         ldq     a1,offclassvftbl(a1)  /* a1 = vftblptr(catchtype) class (not obj) */
983         ldl     a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
984         ldl     v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
985         ldl     a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
986 _crit_end1:
987         subl    a0,v0,a0              /* a0 = baseval(xptr) - baseval(catchtype)  */
988         cmpule  a0,a1,v0              /* v0 = xptr is instanceof catchtype        */
989         addq    sp,8*8,sp             /* deallocate stack                         */
990         beq     v0,ex_table_cont      /* if (false) continue                      */
991
992 ex_handle_it:
993         ldq     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
994
995         beq     t3,ex_jump            /* if (!(no stack unwinding) skip           */
996
997         ldq     t0,0*8(sp)            /* restore possible used registers          */
998         ldq     t1,1*8(sp)            /* also registers used by trace_exception   */
999         ldq     t2,2*8(sp)
1000         ldq     t3,3*8(sp)
1001         ldq     t4,4*8(sp)
1002         ldq     t5,5*8(sp)
1003         ldq     t6,6*8(sp)
1004         ldq     t7,7*8(sp)
1005         ldq     t8,8*8(sp)
1006         ldq     t9,9*8(sp)
1007         ldq     t10,10*8(sp)
1008         ldq     v0,11*8(sp)
1009         ldq     a0,12*8(sp)
1010         ldq     a1,13*8(sp)
1011         ldq     a2,14*8(sp)
1012         ldq     a3,15*8(sp)
1013         ldq     a4,16*8(sp)
1014         ldq     a5,17*8(sp)
1015         lda     sp,18*8(sp)           /* deallocate stack                         */
1016
1017 ex_jump:
1018         jmp     zero,(xpc)            /* jump to the handler                      */
1019
1020 ex_table_cont:
1021         lda     t1,ExEntrySize(t1)    /* next exception table entry               */
1022         subl    t0,1,t0               /* decrement entry counter                  */
1023         bgt     t0,ex_table_loop      /* if (t0 > 0) next entry                   */
1024
1025 empty_table:
1026         beq     t3,ex_already_cleared /* if here the first time, then             */
1027         lda     sp,18*8(sp)           /* deallocate stack and                     */
1028         clr     t3                    /* clear the no unwind flag                 */
1029 ex_already_cleared:
1030         ldl     t0,IsSync(pv)         /* t0 = SyncOffset                          */
1031         beq     t0,no_monitor_exit    /* if zero no monitorexit                   */
1032
1033 #if defined(USE_THREADS)
1034         addq    sp,t0,t0              /* add stackptr to Offset                   */
1035         ldq     a0,-8(t0)             /* load monitorexit pointer                 */
1036
1037         lda     sp,-7*8(sp)           /* allocate stack                           */
1038         stq     t0,0*8(sp)            /* save used register                       */
1039         stq     t1,1*8(sp)
1040         stq     t3,2*8(sp)
1041         stq     xptr,3*8(sp)
1042         stq     xpc,4*8(sp)
1043         stq     pv,5*8(sp)
1044         stq     ra,6*8(sp)
1045
1046         br      ra,ex_mon_load        /* set ra for gp loading                    */
1047 ex_mon_load:
1048         ldgp    gp,0(ra)              /* load gp                                  */
1049         jsr     ra,builtin_monitorexit/* builtin_monitorexit(objectptr)           */
1050         
1051         ldq     t0,0*8(sp)            /* restore used register                    */
1052         ldq     t1,1*8(sp)
1053         ldq     t3,2*8(sp)
1054         ldq     xptr,3*8(sp)
1055         ldq     xpc,4*8(sp)
1056         ldq     pv,5*8(sp)
1057         ldq     ra,6*8(sp)
1058         lda     sp,7*8(sp)            /* deallocate stack                         */
1059 #endif
1060
1061 no_monitor_exit:
1062         ldl     t0,FrameSize(pv)      /* t0 = frame size                          */
1063         addq    sp,t0,sp              /* unwind stack                             */
1064         mov     sp,t0                 /* t0 = pointer to save area                */
1065         ldl     t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
1066         bne     t1,ex_no_restore      /* if (leaf) skip                           */
1067         ldq     ra,-8(t0)             /* restore ra                               */
1068         lda     t0,-8(t0)             /* t0--                                     */
1069 ex_no_restore:
1070         mov     ra,xpc                /* the new xpc is ra                        */
1071         ldl     t1,IntSave(pv)        /* t1 = saved int register count            */
1072         br      t2,ex_int1            /* t2 = current pc                          */
1073 ex_int1:
1074         lda     t2,44(t2)             /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
1075         negl    t1,t1                 /* negate register count                    */
1076         s4addq  t1,t2,t2              /* t2 = ex_int_sav - 4 * register count     */
1077         jmp     zero,(t2)             /* jump to save position                    */
1078         ldq     s0,-56(t0)
1079         ldq     s1,-48(t0)
1080         ldq     s2,-40(t0)
1081         ldq     s3,-32(t0)
1082         ldq     s4,-24(t0)
1083         ldq     s5,-16(t0)
1084         ldq     s6,-8(t0)
1085 ex_int2:
1086         s8addq  t1,t0,t0              /* t0 = t0 - 8 * register count             */
1087
1088         ldl     t1,FltSave(pv)        /* t1 = saved flt register count            */
1089         br      t2,ex_flt1            /* t2 = current pc                          */
1090 ex_flt1:
1091         lda     t2,48(t2)             /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
1092         negl    t1,t1                 /* negate register count                    */
1093         s4addq  t1,t2,t2              /* t2 = ex_flt_sav - 4 * register count     */
1094         jmp     zero,(t2)             /* jump to save position                    */
1095         ldt     fs0,-64(t0)
1096         ldt     fs1,-56(t0)
1097         ldt     fs2,-48(t0)
1098         ldt     fs3,-40(t0)
1099         ldt     fs4,-32(t0)
1100         ldt     fs5,-24(t0)
1101         ldt     fs6,-16(t0)
1102         ldt     fs7,-8(t0)
1103 ex_flt2:
1104         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
1105         sll     t0,48,t0
1106         sra     t0,48,t0              /* isolate offset                           */
1107         addq    t0,ra,pv              /* compute update address                   */
1108         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
1109         srl     t0,16,t0              /* isolate instruction code                 */
1110         lda     t0,-0x177b(t0)        /* test for LDAH                            */
1111         bne     t0,ex_stack_loop       
1112         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(RA)         */
1113         sll     t0,16,t0              /* compute high offset                      */
1114         addl    t0,0,t0               /* sign extend high offset                  */
1115         addq    t0,pv,pv              /* compute update address                   */
1116         br      ex_stack_loop
1117
1118         .end    asm_handle_nat_exception
1119
1120
1121 /* asm_wrapper_patcher *********************************************************
1122
1123    XXX
1124
1125    Stack layout:
1126          24   return address into JIT code (patch position)
1127      16   machine code (which is patched back later)
1128       8   unresolved class/method/field reference
1129       0   patcher function pointer to call
1130
1131    ATTENTION: itmp3 == gp! But we don't need gp do call the patcher function.
1132
1133 *******************************************************************************/
1134                 
1135         .ent    asm_wrapper_patcher
1136
1137 asm_wrapper_patcher:
1138         lda     sp,-(12+27+4)*8(sp)   /* create stack frame                       */
1139
1140         SAVE_ARGUMENT_REGISTERS(0)    /* save 6 int/6 float argument registers    */
1141         SAVE_TEMPORARY_REGISTERS(12)  /* save 11 int/16 float temporary registers */
1142
1143         stq     itmp1,(12+27+0)*8(sp) /* save itmp1                               */
1144         stq     itmp2,(12+27+1)*8(sp) /* save itmp2                               */
1145         stq     ra,(12+27+2)*8(sp)    /* save method return address (for leafs)   */
1146         stq     pv,(12+27+3)*8(sp)    /* save pv of calling java function         */
1147
1148         lda     a0,(1+12+27+4)*8(sp)  /* pass sp, skip patcher function pointer   */
1149         ldq     pv,(0+12+27+4)*8(sp)  /* get function pointer                     */
1150         jmp     ra,(pv)               /* call the patcher function                */
1151         ldgp    gp,0(ra)
1152                 
1153         RESTORE_ARGUMENT_REGISTERS(0) /* restore 6 int/6 float argument registers */
1154         RESTORE_TEMPORARY_REGISTERS(12)/* restore 11 integer temporary registers  */
1155
1156         ldq     itmp1,(12+27+0)*8(sp) /* restore itmp1                            */
1157         ldq     itmp2,(12+27+1)*8(sp) /* restore itmp2                            */
1158         ldq     ra,(12+27+2)*8(sp)    /* restore method return address (for leafs)*/
1159         ldq     pv,(12+27+3)*8(sp)    /* restore pv of calling java function      */
1160
1161         ldq     itmp3,(3+12+27+4)*8(sp)/* get return address (into JIT code)      */
1162         lda     sp,(4+12+27+4)*8(sp)  /* remove stack frame                       */
1163
1164         beq     v0,L_asm_wrapper_patcher_exception
1165
1166         jmp     zero,(itmp3)          /* jump to new patched code                 */
1167
1168 L_asm_wrapper_patcher_exception:
1169         mov     itmp3,xpc             /* return address into JIT code is xpc      */
1170
1171         br      itmp1,L_asm_wrapper_patcher_exception_load_gp
1172 L_asm_wrapper_patcher_exception_load_gp:
1173         ldgp    gp,0(itmp1)           /* itmp3 == gp, load the current gp         */
1174
1175 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1176         subq    sp,3*8,sp
1177         stq     xpc,0*8(sp)           /* save return address (xpc)                */
1178         stq     ra,1*8(sp)
1179         stq     pv,2*8(sp)
1180         jsr     ra,builtin_asm_get_exceptionptrptr
1181         ldq     xpc,0*8(sp)           /* restore return address (xpc)             */
1182         ldq     ra,1*8(sp)
1183         ldq     pv,2*8(sp)
1184         addq    sp,3*8,sp
1185 #else
1186         lda     v0,_exceptionptr
1187 #endif
1188         ldq     xptr,0(v0)            /* get the exception pointer                */
1189         stq     zero,0(v0)            /* clear the exception pointer              */
1190         br      asm_handle_exception  /* we have the pv of the calling java func. */
1191
1192         .end    asm_wrapper_patcher
1193
1194                 
1195 /************************ function asm_builtin_idiv ****************************
1196 *                                                                              *
1197 *   Does null check and calls idiv or throws an exception                      *
1198 *                                                                              *
1199 *******************************************************************************/
1200
1201         .ent    asm_builtin_idiv
1202
1203 asm_builtin_idiv:
1204         ldgp    gp,0(pv)
1205         lda     pv,builtin_idiv
1206         beq     a1,nb_idiv                /* if (null) throw exception            */
1207         jmp     zero,(pv)                 /* else call builtin_idiv               */
1208
1209 nb_idiv:
1210         ldq     xptr,string_java_lang_ArithmeticException_message
1211         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1212         br      asm_throw_and_handle_arithmetic_exception
1213
1214         .end    asm_builtin_idiv
1215
1216
1217 /************************ function asm_builtin_ldiv ****************************
1218 *                                                                              *
1219 *   Does null check and calls ldiv or throws an exception                      *
1220 *                                                                              *
1221 *******************************************************************************/
1222
1223         .ent    asm_builtin_ldiv
1224
1225 asm_builtin_ldiv:
1226         ldgp    gp,0(pv)
1227         lda     pv,builtin_ldiv
1228         beq     a1,nb_ldiv                /* if (null) throw exception            */
1229         jmp     zero,(pv)                 /* else call builtin_ldiv               */
1230
1231 nb_ldiv:
1232         ldq     xptr,string_java_lang_ArithmeticException_message
1233         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1234         br      asm_throw_and_handle_arithmetic_exception
1235
1236         .end    asm_builtin_ldiv
1237
1238
1239 /************************ function asm_builtin_irem ****************************
1240 *                                                                              *
1241 *   Does null check and calls irem or throws an exception                      *
1242 *                                                                              *
1243 *******************************************************************************/
1244
1245         .ent    asm_builtin_irem
1246
1247 asm_builtin_irem:
1248         ldgp    gp,0(pv)
1249         lda     pv,builtin_irem
1250         beq     a1,nb_irem                /* if (null) throw exception            */
1251         jmp     zero,(pv)                 /* else call builtin_irem               */
1252
1253 nb_irem:
1254         ldq     xptr,string_java_lang_ArithmeticException_message
1255         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1256         br      asm_throw_and_handle_arithmetic_exception
1257
1258         .end    asm_builtin_irem
1259
1260
1261 /************************ function asm_builtin_lrem ****************************
1262 *                                                                              *
1263 *   Does null check and calls lrem or throws an exception                      *
1264 *                                                                              *
1265 *******************************************************************************/
1266
1267         .ent    asm_builtin_lrem
1268
1269 asm_builtin_lrem:
1270         ldgp    gp,0(pv)
1271         lda     pv,builtin_lrem
1272         beq     a1,nb_lrem                /* if (null) throw exception            */
1273         jmp     zero,(pv)                 /* else call builtin_lrem               */
1274
1275 nb_lrem:
1276         ldq     xptr,string_java_lang_ArithmeticException_message
1277         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1278         br      asm_throw_and_handle_arithmetic_exception
1279
1280         .end    asm_builtin_lrem
1281
1282
1283 /******************* function asm_builtin_checkarraycast ***********************
1284 *                                                                              *
1285 *   Does the cast check and eventually throws an exception                     *
1286 *                                                                              *
1287 *******************************************************************************/
1288
1289         .ent    asm_builtin_checkarraycast
1290
1291 asm_builtin_checkarraycast:
1292         ldgp    gp,0(pv)
1293         lda     sp,-16(sp)                /* allocate stack space                 */
1294         stq     ra,0(sp)                  /* save return address                  */
1295         stq     a0,8(sp)                  /* save object pointer                  */
1296         jsr     ra,builtin_checkarraycast /* builtin_checkarraycast               */
1297         ldgp    gp,0(ra)
1298         beq     v0,nb_carray_throw        /* if (false) throw exception           */
1299         ldq     ra,0(sp)                  /* restore return address               */
1300         ldq     v0,8(sp)                  /* return object pointer                */
1301         lda     sp,16(sp)                 /* free stack space                     */
1302         jmp     zero,(ra)
1303
1304 nb_carray_throw:
1305         ldq     ra,0(sp)
1306         lda     sp,16(sp)
1307         lda     xpc,-4(ra)
1308         ldq     xptr,string_java_lang_ClassCastException
1309         jmp     zero,asm_throw_and_handle_nat_exception
1310 #if 0
1311         ldq     a0,string_java_lang_ClassCastException
1312     jsr     ra,new_exception
1313     ldgp    gp,0(ra)
1314         mov     v0,xptr
1315
1316         ldq     ra,0(sp)                  /* restore return address               */
1317         lda     sp,16(sp)                 /* free stack space                     */
1318         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1319         br      asm_handle_nat_exception
1320 #endif
1321
1322         .end    asm_builtin_checkarraycast
1323
1324
1325 /******************* function asm_builtin_aastore ******************************
1326 *                                                                              *
1327 *   Does the cast check and eventually throws an exception                     *
1328 *                                                                              *
1329 *******************************************************************************/
1330
1331         .ent    asm_builtin_aastore
1332
1333 asm_builtin_aastore:
1334         ldgp    gp,0(pv)
1335         beq     a0,nb_aastore_null        /* if null pointer throw exception      */
1336         ldl     t0,offarraysize(a0)       /* load size                            */
1337         lda     sp,-24(sp)                /* allocate stack space                 */
1338         stq     ra,0(sp)                  /* save return address                  */
1339         s8addq  a1,a0,t1                  /* add index*8 to arrayref              */
1340         cmpult  a1,t0,t0                  /* do bound check                       */
1341         beq     t0,nb_aastore_bound       /* if out of bounds throw exception     */
1342         mov     a2,a1                     /* object is second argument            */
1343         stq     t1,8(sp)                  /* save store position                  */
1344         stq     a1,16(sp)                 /* save object                          */
1345         jsr     ra,builtin_canstore       /* builtin_canstore(arrayref,object)    */
1346         ldgp    gp,0(ra)
1347         ldq     ra,0(sp)                  /* restore return address               */
1348         ldq     a0,8(sp)                  /* restore store position               */
1349         ldq     a1,16(sp)                 /* restore object                       */
1350         lda     sp,24(sp)                 /* free stack space                     */
1351         beq     v0,nb_aastore_throw       /* if (false) throw exception           */
1352         stq     a1,offobjarrdata(a0)      /* store objectptr in array             */
1353         jmp     zero,(ra)
1354
1355 nb_aastore_null:
1356         ldq     xptr,string_java_lang_NullPointerException
1357         mov     ra,xpc
1358         jmp     zero,asm_throw_and_handle_nat_exception
1359 #if 0   
1360         subq    sp,8,sp                   /* allocate stack space                 */
1361         stq     ra,0(sp)                  /* save return address                  */
1362     jsr     ra,new_nullpointerexception
1363     ldgp    gp,0(ra)
1364         mov     v0,xptr
1365         ldq     ra,0(sp)
1366         addq    sp,8,sp
1367
1368         mov     ra,xpc                    /* faulting address is return adress    */
1369         br      asm_handle_nat_exception
1370 #endif
1371 nb_aastore_bound:
1372         ldq     ra,0(sp)
1373         lda     sp,24(sp)
1374         mov     ra,xpc
1375         mov     a1,xptr
1376         jmp     zero,asm_throw_and_handle_arrayindexoutofbounds_exception
1377 #if 0
1378         ldq     a0,string_java_lang_ArrayIndexOutOfBoundsException
1379     jsr     ra,new_exception_int      /* a1 already contains the index        */
1380     ldgp    gp,0(ra)
1381         mov     v0,xptr
1382
1383         ldq     ra,0(sp)                  /* restore return address               */
1384         lda     sp,24(sp)                 /* free stack space                     */
1385         mov     ra,xpc                    /* faulting address is return adress    */
1386         br      asm_handle_nat_exception
1387 #endif
1388 nb_aastore_throw:
1389         mov     ra,xpc
1390         ldq     xptr,string_java_lang_ArrayStoreException
1391         jmp     zero,asm_throw_and_handle_nat_exception
1392 #if 0
1393         subq    sp,8,sp                   /* allocate stack space                 */
1394         stq     ra,0(sp)                  /* save return address                  */
1395     jsr     ra,new_arraystoreexception
1396     ldgp    gp,0(ra)
1397         mov     v0,xptr
1398         ldq     ra,0(sp)
1399         addq    sp,8,sp
1400
1401         mov     ra,xpc                    /* faulting address is return adress    */
1402         br      asm_handle_nat_exception
1403 #endif
1404         .end    asm_builtin_aastore
1405
1406
1407 /******************* function asm_initialize_thread_stack **********************
1408 *                                                                              *
1409 *   initialized a thread stack                                                 *
1410 *                                                                              *
1411 *******************************************************************************/
1412
1413         .ent    asm_initialize_thread_stack
1414
1415 asm_initialize_thread_stack:
1416         lda     a1,-128(a1)
1417         stq     zero, 0(a1)
1418         stq     zero, 8(a1)
1419         stq     zero, 16(a1)
1420         stq     zero, 24(a1)
1421         stq     zero, 32(a1)
1422         stq     zero, 40(a1)
1423         stq     zero, 48(a1)
1424         stt     fzero, 56(a1)
1425         stt     fzero, 64(a1)
1426         stt     fzero, 72(a1)
1427         stt     fzero, 80(a1)
1428         stt     fzero, 88(a1)
1429         stt     fzero, 96(a1)
1430         stt     fzero, 104(a1)
1431         stt     fzero, 112(a1)
1432         stq     a0, 120(a1)
1433         mov     a1, v0
1434         jmp     zero,(ra)
1435
1436         .end    asm_initialize_thread_stack
1437
1438
1439 /******************* function asm_perform_threadswitch *************************
1440 *                                                                              *
1441 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1442 *                                                                              *
1443 *   performs a threadswitch                                                    *
1444 *                                                                              *
1445 *******************************************************************************/
1446
1447         .ent    asm_perform_threadswitch
1448
1449 asm_perform_threadswitch:
1450         subq    sp,128,sp
1451         stq     s0, 0(sp)
1452         stq     s1, 8(sp)
1453         stq     s2, 16(sp)
1454         stq     s3, 24(sp)
1455         stq     s4, 32(sp)
1456         stq     s5, 40(sp)
1457         stq     s6, 48(sp)
1458         stt     fs0, 56(sp)
1459         stt     fs1, 64(sp)
1460         stt     fs2, 72(sp)
1461         stt     fs3, 80(sp)
1462         stt     fs4, 88(sp)
1463         stt     fs5, 96(sp)
1464         stt     fs6, 104(sp)
1465         stt     fs7, 112(sp)
1466         stq     ra, 120(sp)
1467         stq     sp, 0(a0)
1468         stq     sp, 0(a2)
1469         ldq     sp, 0(a1)
1470         ldq     s0, 0(sp)
1471         ldq     s1, 8(sp)
1472         ldq     s2, 16(sp)
1473         ldq     s3, 24(sp)
1474         ldq     s4, 32(sp)
1475         ldq     s5, 40(sp)
1476         ldq     s6, 48(sp)
1477         ldt     fs0, 56(sp)
1478         ldt     fs1, 64(sp)
1479         ldt     fs2, 72(sp)
1480         ldt     fs3, 80(sp)
1481         ldt     fs4, 88(sp)
1482         ldt     fs5, 96(sp)
1483         ldt     fs6, 104(sp)
1484         ldt     fs7, 112(sp)
1485         ldq     ra, 120(sp)
1486         mov     ra, pv
1487         addq    sp, 128, sp
1488         jmp     zero,(ra)
1489
1490         .end    asm_perform_threadswitch
1491
1492
1493 /********************* function asm_switchstackandcall *************************
1494 *                                                                              *
1495 *  void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1496 *                               void *p);                                      *
1497 *                                                                              *
1498 *   Switches to a new stack, calls a function and switches back.               *
1499 *       a0      new stack pointer                                              *
1500 *       a1      function pointer                                               *
1501 *               a2              pointer to variable where stack top should be stored           *
1502 *               a3      pointer to user data, is passed to the function                *
1503 *                                                                              *
1504 *******************************************************************************/
1505
1506
1507         .ent    asm_switchstackandcall
1508
1509 asm_switchstackandcall:
1510         lda     a0,-2*8(a0)     /* allocate new stack                                 */
1511         stq     ra,0(a0)        /* save return address on new stack                   */
1512         stq     sp,1*8(a0)      /* save old stack pointer on new stack                */
1513         stq sp,0(a2)        /* save old stack pointer to variable                 */
1514         mov     a0,sp           /* switch to new stack                                */
1515         
1516         mov     a1,pv           /* load function pointer                              */
1517         mov a3,a0           /* pass pointer */
1518         jmp     ra,(pv)         /* and call function                                  */
1519
1520         ldq     ra,0(sp)        /* load return address                                */
1521         ldq     sp,1*8(sp)      /* switch to old stack                                */
1522
1523         jmp     zero,(ra)       /* return                                             */
1524
1525         .end    asm_switchstackandcall
1526
1527         .ent    asm_getclassvalues_atomic
1528
1529 asm_getclassvalues_atomic:
1530 _crit_restart2:
1531 _crit_begin2:
1532         ldl     t0,offbaseval(a0)
1533         ldl     t1,offdiffval(a0)
1534         ldl     t2,offbaseval(a1)
1535 _crit_end2:
1536         stl     t0,offcast_super_baseval(a2)
1537         stl     t1,offcast_super_diffval(a2)
1538         stl     t2,offcast_sub_baseval(a2)
1539         jmp      zero,(ra)
1540
1541         .end    asm_getclassvalues_atomic
1542
1543     .data
1544
1545 asm_criticalsections:
1546 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1547     .quad   _crit_begin1
1548     .quad   _crit_end1
1549     .quad   _crit_restart1
1550     .quad   _crit_begin2
1551     .quad   _crit_end2
1552     .quad   _crit_restart2
1553 #endif
1554     .quad   0
1555
1556
1557         .ent asm_prepare_native_stackinfo
1558 asm_prepare_native_stackinfo:
1559         lda sp,-24(sp)
1560         stq ra,0(sp)
1561         jsr ra,builtin_asm_get_stackframeinfo
1562         stq v0,16(sp)
1563         ldq t0,0(v0)
1564         stq t0,8(sp)
1565         ldq ra,0(sp)
1566         lda sp,8(sp)
1567         stq sp,0(v0)
1568         ret
1569         .end asm_prepare_native_stackinfo
1570
1571         .ent asm_remove_native_stackinfo
1572 asm_remove_native_stackinfo:
1573         ldq t0,0(sp)
1574         ldq t1,8(sp)
1575         stq t0,0(t1)
1576         lda sp,40(sp)
1577         ret
1578         .end asm_remove_native_stackinfo
1579
1580 /*
1581  * These are local overrides for various environment variables in Emacs.
1582  * Please do not remove this and leave it at the end of the file, where
1583  * Emacs will automagically detect them.
1584  * ---------------------------------------------------------------------
1585  * Local variables:
1586  * mode: asm
1587  * indent-tabs-mode: t
1588  * c-basic-offset: 4
1589  * tab-width: 4
1590  * End:
1591  */