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