Use monitorenter/exit only with threads.
[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-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
32    $Id: asmpart.S 1811 2004-12-22 12:21:38Z twisti $
33
34 */
35
36
37 #include "config.h"        
38 #include "vm/jit/alpha/offsets.h"
39 #include "vm/jit/alpha/asmoffsets.h"
40
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
111         .globl asm_calljavafunction
112
113         .globl asm_calljavafunction2
114         .globl asm_calljavafunction2int
115         .globl asm_calljavafunction2long
116         .globl asm_calljavafunction2float
117         .globl asm_calljavafunction2double
118
119         .globl asm_call_jit_compiler
120         .globl asm_throw_and_handle_exception
121         .globl asm_throw_and_handle_nat_exception
122         .globl asm_throw_and_handle_arithmetic_exception
123         .globl asm_throw_and_handle_arrayindexoutofbounds_exception
124         .globl asm_handle_exception
125         .globl asm_handle_nat_exception
126         .globl asm_check_clinit
127         .globl asm_builtin_checkcast    
128         .globl asm_builtin_checkarraycast
129         .globl asm_builtin_aastore
130
131 #if defined(USE_THREADS)
132         .globl asm_builtin_monitorenter
133         .globl asm_builtin_monitorexit
134 #endif
135
136         .globl asm_builtin_idiv
137         .globl asm_builtin_irem
138         .globl asm_builtin_ldiv
139         .globl asm_builtin_lrem
140         .globl asm_perform_threadswitch
141         .globl asm_initialize_thread_stack
142         .globl asm_switchstackandcall
143         .globl asm_builtin_trace
144         .globl asm_builtin_exittrace
145         .globl asm_criticalsections
146         .globl asm_getclassvalues_atomic
147         .globl asm_prepare_native_stackinfo
148         .globl asm_remove_native_stackinfo
149         .globl asm_refillin_and_handle_exception
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
531 asm_throw_and_handle_arrayindexoutofbounds_exception:
532         ldgp    gp,0(pv)
533
534         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
535         sll     t0,48,t0
536         sra     t0,48,t0              /* isolate offset                           */
537         addq    t0,ra,pv              /* compute update address                   */
538         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
539         srl     t0,16,t0              /* isolate instruction code                 */
540         lda     t0,-0x177b(t0)        /* test for LDAH                            */
541         bne     t0,asm_throw_and_handle_arrayindexoutofbounds_exception_cont
542         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
543         sll     t0,16,t0              /* compute high offset                      */
544         addl    t0,0,t0               /* sign extend high offset                  */
545         addq    t0,pv,pv              /* compute update address                   */
546
547 asm_throw_and_handle_arrayindexoutofbounds_exception_cont:
548         mov     sp,t0
549         lda     sp,-6*8(sp) /*prepare stackframe*/
550         stq     pv,5*8(sp)  /*pv of failure*/
551         stq     itmp1,4*8(sp) /*int parameter  of the exception*/
552         stq     xpc,3*8(sp) /*address of failure */
553         stq     t0,2*8(sp) /*store begin of java stack frame*/
554         stq     pv,1*8(sp) /*store pv of caller in structure*/
555         stq     zero,0*8(sp) /*builtin (invisible function)*/
556
557         jsr     ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
558         ldgp    gp,0(ra)
559
560         ldq     a0,6*8(sp)  /*int  of exception*/
561         jsr     ra,new_arrayindexoutofboundsexception
562         ldgp    gp,0(ra)
563
564         mov     v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
565
566         jsr     ra,asm_remove_native_stackinfo
567         ldgp    gp,0(ra)
568
569         ldq     itmp2,0(sp)     
570         ldq     pv,2*8(sp)
571         lda     sp,3*8(sp)
572         br      asm_handle_exception
573
574         .end asm_throw_and_handle_arrayindexoutofbounds_exception
575
576
577 /* asm_throw_and_handle_arithmetic_exception ***********************************
578
579    DOCUMENT ME!
580
581 *******************************************************************************/
582
583         .ent asm_throw_and_handle_arithmetic_exception
584
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         jsr     ra,new_arithmeticexception
612         ldgp    gp,0(ra)
613         mov     v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
614
615         jsr ra,asm_remove_native_stackinfo
616         ldgp    gp,0(ra)
617
618         ldq itmp2,0(sp) 
619         ldq    pv,2*8(sp)
620         lda sp,3*8(sp)
621         br asm_handle_exception
622
623         .end asm_throw_and_handle_arithmetic_exception
624
625
626 /**************** function asm_throw_and_handle_exception **********************
627 *                                                                              *
628 *   This function handles an exception. It does not use the usual calling      *
629 *   conventions. The exception class name is passed in REG_ITMP1 and the       *
630 *   pc from the exception raising position is passed in REG_ITMP2.             *
631 *                                                                              *
632 *   void asm_handle_exception (exceptionclass, exceptionpc);                   *
633 *                                                                              *
634 *******************************************************************************/
635         .ent asm_throw_and_handle_nat_exception
636 asm_throw_and_handle_nat_exception:
637         ldgp    gp,0(pv)
638         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
639         sll     t0,48,t0
640         sra     t0,48,t0              /* isolate offset                           */
641         addq    t0,ra,pv              /* compute update address                   */
642         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
643         srl     t0,16,t0              /* isolate instruction code                 */
644         lda     t0,-0x177b(t0)        /* test for LDAH                            */
645         bne     t0,asm_throw_and_handle_exception
646         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
647         sll     t0,16,t0              /* compute high offset                      */
648         addl    t0,0,t0               /* sign extend high offset                  */
649         addq    t0,pv,pv              /* compute update address                   */
650
651         .aent asm_throw_and_handle_exception
652 asm_throw_and_handle_exception:
653         mov     sp,t0
654         lda     sp,-6*8(sp) /*prepare stackframe*/
655         stq     pv,5*8(sp)  /*pv of failure*/
656         stq     itmp1,4*8(sp) /*classname of the exception*/
657         stq     xpc,3*8(sp) /*address of failure */
658         stq     t0,2*8(sp) /*store begin of java stack frame*/
659         stq     pv,1*8(sp) /*store pv of caller in structure*/
660         stq     zero,0*8(sp) /*builtin (invisible function)*/
661         jsr     ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
662         ldgp    gp,0(ra)
663
664         ldq a0,6*8(sp)  /*classname of exception*/
665         jsr ra,new_exception
666         ldgp    gp,0(ra)
667
668         mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
669
670         jsr ra,asm_remove_native_stackinfo
671         ldgp    gp,0(ra)
672
673         ldq itmp2,0(sp) 
674         ldq    pv,2*8(sp)
675         lda sp,3*8(sp)
676         br asm_handle_exception
677         .end asm_throw_and_handle_nat_exception
678
679
680 /********************* function asm_handle_exception ***************************
681 *                                                                              *
682 *   This function handles an exception. It does not use the usual calling      *
683 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
684 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
685 *   the local exception table for a handler. If no one is found, it unwinds    *
686 *   stacks and continues searching the callers.                                *
687 *                                                                              *
688 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
689 *                                                                              *
690 *******************************************************************************/
691
692         .ent    asm_handle_nat_exception
693 asm_handle_nat_exception:
694         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
695         sll     t0,48,t0
696         sra     t0,48,t0              /* isolate offset                           */
697         addq    t0,ra,pv              /* compute update address                   */
698         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
699         srl     t0,16,t0              /* isolate instruction code                 */
700         lda     t0,-0x177b(t0)        /* test for LDAH                            */
701         bne     t0,asm_handle_exception
702         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
703         sll     t0,16,t0              /* compute high offset                      */
704         addl    t0,0,t0               /* sign extend high offset                  */
705         addq    t0,pv,pv              /* compute update address                   */
706
707         .aent    asm_handle_exception
708 asm_handle_exception:
709         lda     sp,-18*8(sp)          /* allocate stack                           */
710         stq     t0,0*8(sp)            /* save possible used registers             */
711         stq     t1,1*8(sp)            /* also registers used by trace_exception   */
712         stq     t2,2*8(sp)
713         stq     t3,3*8(sp)
714         stq     t4,4*8(sp)
715         stq     t5,5*8(sp)
716         stq     t6,6*8(sp)
717         stq     t7,7*8(sp)
718         stq     t8,8*8(sp)
719         stq     t9,9*8(sp)
720         stq     t10,10*8(sp)
721         stq     v0,11*8(sp)
722         stq     a0,12*8(sp)
723         stq     a1,13*8(sp)
724         stq     a2,14*8(sp)
725         stq     a3,15*8(sp)
726         stq     a4,16*8(sp)
727         stq     a5,17*8(sp)
728
729         lda     t3,1(zero)            /* set no unwind flag                       */
730 ex_stack_loop:
731         lda     sp,-5*8(sp)           /* allocate stack                           */
732         stq     xptr,0*8(sp)          /* save used register                       */
733         stq     xpc,1*8(sp)
734         stq     pv,2*8(sp)
735         stq     ra,3*8(sp)
736         stq     t3,4*8(sp)
737
738         mov     xptr,a0
739         ldq     a1,MethodPointer(pv)
740         mov     xpc,a2
741 /*      mov     t3,a3 */
742         lda             a3,0(zero)
743         lda             a4,1(zero)
744         br      ra,ex_trace           /* set ra for gp loading                    */
745 ex_trace:
746         ldgp    gp,0(ra)              /* load gp                                  */
747         jsr     ra,builtin_trace_exception /* trace_exception(xptr,methodptr)     */
748         
749         ldq     xptr,0*8(sp)          /* restore used register                    */
750         ldq     xpc,1*8(sp)
751         ldq     pv,2*8(sp)
752         ldq     ra,3*8(sp)
753         ldq     t3,4*8(sp)
754         lda     sp,5*8(sp)            /* deallocate stack                         */
755         
756         ldl     t0,ExTableSize(pv)    /* t0 = exception table size                */
757         beq     t0,empty_table        /* if empty table skip                      */
758
759         lda     t1,ExTableStart(pv)   /* t1 = start of exception table            */
760
761 ex_table_loop:
762         ldq     t2,ExStartPC(t1)      /* t2 = exception start pc                  */
763         cmple   t2,xpc,t2             /* t2 = (startpc <= xpc)                    */
764         beq     t2,ex_table_cont      /* if (false) continue                      */
765         ldq     t2,ExEndPC(t1)        /* t2 = exception end pc                    */
766         cmplt   xpc,t2,t2             /* t2 = (xpc < endpc)                       */
767         beq     t2,ex_table_cont      /* if (false) continue                      */
768         ldq     a1,ExCatchType(t1)    /* arg1 = exception catch type              */
769         beq     a1,ex_handle_it       /* NULL catches everything                  */
770
771         ldl     itmp3,offclassloaded(a1)
772         bne     itmp3,L_class_loaded
773
774         subq    sp,8*8,sp             /* allocate stack                           */
775         stq     t0,0*8(sp)            /* save used register                       */
776         stq     t1,1*8(sp)
777         stq     t3,2*8(sp)
778         stq     xptr,3*8(sp)
779         stq     xpc,4*8(sp)
780         stq     pv,5*8(sp)
781         stq     ra,6*8(sp)
782         stq     a1,7*8(sp)
783
784         mov     a1,a0
785
786         br      ra,L_class_load_ra    /* set ra for gp loading                    */
787 L_class_load_ra:
788         ldgp    gp,0(ra)              /* load gp                                  */
789         jsr     ra,class_load         /* class_load(exceptionclass)               */
790
791         ldq     t0,0*8(sp)            /* restore used register                    */
792         ldq     t1,1*8(sp)
793         ldq     t3,2*8(sp)
794         ldq     xptr,3*8(sp)
795         ldq     xpc,4*8(sp)
796         ldq     pv,5*8(sp)
797         ldq     ra,6*8(sp)
798         ldq     a1,7*8(sp)
799         addq    sp,8*8,sp             /* deallocate stack                         */
800
801 L_class_loaded:
802         ldl     itmp3,offclasslinked(a1)
803         subq    sp,8*8,sp             /* allocate stack                           */
804         stq     a1,7*8(sp)
805         bne     itmp3,L_class_linked
806
807         stq     t0,0*8(sp)            /* save used register                       */
808         stq     t1,1*8(sp)
809         stq     t3,2*8(sp)
810         stq     xptr,3*8(sp)
811         stq     xpc,4*8(sp)
812         stq     pv,5*8(sp)
813         stq     ra,6*8(sp)
814
815         mov     a1,a0
816
817         br      ra,L_class_link_ra    /* set ra for gp loading                    */
818 L_class_link_ra:
819         ldgp    gp,0(ra)              /* load gp                                  */
820         jsr     ra,class_link         /* class_load(exceptionclass)               */
821
822         ldq     t0,0*8(sp)            /* restore used register                    */
823         ldq     t1,1*8(sp)
824         ldq     t3,2*8(sp)
825         ldq     xptr,3*8(sp)
826         ldq     xpc,4*8(sp)
827         ldq     pv,5*8(sp)
828         ldq     ra,6*8(sp)
829
830 L_class_linked:
831 _crit_restart1:
832         ldq     a1,7*8(sp)
833 _crit_begin1:
834         ldq     a0,offobjvftbl(xptr)  /* a0 = vftblptr(xptr)                      */
835         ldq     a1,offclassvftbl(a1)  /* a1 = vftblptr(catchtype) class (not obj) */
836         ldl     a0,offbaseval(a0)     /* a0 = baseval(xptr)                       */
837         ldl     v0,offbaseval(a1)     /* a2 = baseval(catchtype)                  */
838         ldl     a1,offdiffval(a1)     /* a1 = diffval(catchtype)                  */
839 _crit_end1:
840         subl    a0,v0,a0              /* a0 = baseval(xptr) - baseval(catchtype)  */
841         cmpule  a0,a1,v0              /* v0 = xptr is instanceof catchtype        */
842         addq    sp,8*8,sp             /* deallocate stack                         */
843         beq     v0,ex_table_cont      /* if (false) continue                      */
844
845 ex_handle_it:
846         ldq     xpc,ExHandlerPC(t1)   /* xpc = exception handler pc               */
847
848         beq     t3,ex_jump            /* if (!(no stack unwinding) skip           */
849
850         ldq     t0,0*8(sp)            /* restore possible used registers          */
851         ldq     t1,1*8(sp)            /* also registers used by trace_exception   */
852         ldq     t2,2*8(sp)
853         ldq     t3,3*8(sp)
854         ldq     t4,4*8(sp)
855         ldq     t5,5*8(sp)
856         ldq     t6,6*8(sp)
857         ldq     t7,7*8(sp)
858         ldq     t8,8*8(sp)
859         ldq     t9,9*8(sp)
860         ldq     t10,10*8(sp)
861         ldq     v0,11*8(sp)
862         ldq     a0,12*8(sp)
863         ldq     a1,13*8(sp)
864         ldq     a2,14*8(sp)
865         ldq     a3,15*8(sp)
866         ldq     a4,16*8(sp)
867         ldq     a5,17*8(sp)
868         lda     sp,18*8(sp)           /* deallocate stack                         */
869
870 ex_jump:
871         jmp     zero,(xpc)            /* jump to the handler                      */
872
873 ex_table_cont:
874         lda     t1,ExEntrySize(t1)    /* next exception table entry               */
875         subl    t0,1,t0               /* decrement entry counter                  */
876         bgt     t0,ex_table_loop      /* if (t0 > 0) next entry                   */
877
878 empty_table:
879         beq     t3,ex_already_cleared /* if here the first time, then             */
880         lda     sp,18*8(sp)           /* deallocate stack and                     */
881         clr     t3                    /* clear the no unwind flag                 */
882 ex_already_cleared:
883         ldl     t0,IsSync(pv)         /* t0 = SyncOffset                          */
884         beq     t0,no_monitor_exit    /* if zero no monitorexit                   */
885
886 #if defined(USE_THREADS)
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 #endif
913
914 no_monitor_exit:
915         ldl     t0,FrameSize(pv)      /* t0 = frame size                          */
916         addq    sp,t0,sp              /* unwind stack                             */
917         mov     sp,t0                 /* t0 = pointer to save area                */
918         ldl     t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
919         bne     t1,ex_no_restore      /* if (leaf) skip                           */
920         ldq     ra,-8(t0)             /* restore ra                               */
921         lda     t0,-8(t0)             /* t0--                                     */
922 ex_no_restore:
923         mov     ra,xpc                /* the new xpc is ra                        */
924         ldl     t1,IntSave(pv)        /* t1 = saved int register count            */
925         br      t2,ex_int1            /* t2 = current pc                          */
926 ex_int1:
927         lda     t2,44(t2)             /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
928         negl    t1,t1                 /* negate register count                    */
929         s4addq  t1,t2,t2              /* t2 = ex_int_sav - 4 * register count     */
930         jmp     zero,(t2)             /* jump to save position                    */
931         ldq     s0,-56(t0)
932         ldq     s1,-48(t0)
933         ldq     s2,-40(t0)
934         ldq     s3,-32(t0)
935         ldq     s4,-24(t0)
936         ldq     s5,-16(t0)
937         ldq     s6,-8(t0)
938 ex_int2:
939         s8addq  t1,t0,t0              /* t0 = t0 - 8 * register count             */
940
941         ldl     t1,FltSave(pv)        /* t1 = saved flt register count            */
942         br      t2,ex_flt1            /* t2 = current pc                          */
943 ex_flt1:
944         lda     t2,48(t2)             /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
945         negl    t1,t1                 /* negate register count                    */
946         s4addq  t1,t2,t2              /* t2 = ex_flt_sav - 4 * register count     */
947         jmp     zero,(t2)             /* jump to save position                    */
948         ldt     $f2,-64(t0)
949         ldt     $f3,-56(t0)
950         ldt     $f4,-48(t0)
951         ldt     $f5,-40(t0)
952         ldt     $f6,-32(t0)
953         ldt     $f7,-24(t0)
954         ldt     $f8,-16(t0)
955         ldt     $f9,-8(t0)
956 ex_flt2:
957         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
958         sll     t0,48,t0
959         sra     t0,48,t0              /* isolate offset                           */
960         addq    t0,ra,pv              /* compute update address                   */
961         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
962         srl     t0,16,t0              /* isolate instruction code                 */
963         lda     t0,-0x177b(t0)        /* test for LDAH                            */
964         bne     t0,ex_stack_loop       
965         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(RA)         */
966         sll     t0,16,t0              /* compute high offset                      */
967         addl    t0,0,t0               /* sign extend high offset                  */
968         addq    t0,pv,pv              /* compute update address                   */
969         br      ex_stack_loop
970
971         .end    asm_handle_nat_exception
972
973
974 /* asm_check_clinit ************************************************************
975
976    DOCUMENT ME!!!
977
978    Arguments:
979
980         itmp1: pointer to class
981
982    Stack layout:
983
984         0   mcode  ; machine code to patch back in
985
986 *******************************************************************************/
987                 
988     .ent    asm_check_clinit
989
990 asm_check_clinit:
991         ldgp    gp,0(itmp2)           /* function is called via `jsr ra,itmp1'    */
992
993         subq    sp,8*8,sp
994
995         stq             ra,0*8(sp)            /* save return address                      */
996         stq     pv,1*8(sp)            /* save pv of calling java function         */
997         stq             a0,2*8(sp)            /* save argument registers for leaf         */
998         stq             a1,3*8(sp)            /* functions and native stub                */
999         stq             a2,4*8(sp)
1000         stq             a3,5*8(sp)
1001         stq             a4,6*8(sp)
1002         stq             a5,7*8(sp)
1003                 
1004         ldl             itmp2,offclassinit(itmp1)
1005         bne             itmp2,L_is_initialized
1006         
1007         mov             itmp1,a0              /* move class pointer to a0                 */
1008         jsr             ra,class_init
1009     ldgp    gp,0(ra)
1010                 
1011         beq     v0,L_initializererror
1012
1013 L_is_initialized:
1014         ldq     ra,0*8(sp)            /* get return address                       */
1015         subq    ra,1*4,ra             /* go back 1 instruction                    */
1016         ldl     itmp1,8*8(sp)         /* load machine code from stack             */
1017         stl     itmp1,0(ra)           /* store the machine code                   */
1018
1019         call_pal PAL_imb              /* synchronise instruction cache            */
1020
1021         ldq             ra,0*8(sp)            /* restore return address                   */
1022         ldq     pv,1*8(sp)            /* restore pv of calling java function      */
1023         ldq             a0,2*8(sp)            /* restore argument registers               */
1024         ldq             a1,3*8(sp)
1025         ldq             a2,4*8(sp)
1026         ldq             a3,5*8(sp)
1027         ldq             a4,6*8(sp)
1028         ldq             a5,7*8(sp)
1029
1030         addq    sp,(8+1)*8,sp         /* remove stack frame (+1 for machine code) */
1031
1032         subq    ra,1*4,ra             /* go back 1 instruction                    */
1033         jmp             zero,(ra)             /* jump to the new code                     */
1034
1035 L_initializererror:
1036 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1037         jsr     ra,builtin_asm_get_exceptionptrptr
1038 #else
1039         lda     v0,_exceptionptr
1040 #endif
1041         ldq     xptr,0(v0)            /* get the exception pointer                */
1042         stq     zero,0(v0)            /* clear the exception pointer              */
1043
1044         ldq             ra,0*8(sp)            /* restore return address                   */
1045         ldq     pv,1*8(sp)            /* restore pv of calling java function      */
1046         ldq             a0,2*8(sp)            /* restore argument registers               */
1047         ldq             a1,3*8(sp)
1048         ldq             a2,4*8(sp)
1049         ldq             a3,5*8(sp)
1050         ldq             a4,6*8(sp)
1051         ldq             a5,7*8(sp)
1052
1053         addq    sp,(8+1)*8,sp         /* remove stack frame (+1 for machine code) */
1054
1055         subq    ra,4,xpc
1056         br      asm_handle_exception  /* we have the pv of the calling java func. */
1057
1058         .end    asm_check_clinit
1059
1060                 
1061 /********************* function asm_builtin_monitorenter ***********************
1062 *                                                                              *
1063 *   Does null check and calls monitorenter or throws an exception              *
1064 *                                                                              *
1065 *******************************************************************************/
1066
1067 #if defined(USE_THREADS)
1068         .ent    asm_builtin_monitorenter
1069
1070 asm_builtin_monitorenter:
1071         ldgp    gp,0(pv)
1072         lda     pv,builtin_monitorenter
1073         beq     a0,nb_monitorenter        /* if (null) throw exception            */
1074         jmp     zero,(pv)                 /* else call builtin_monitorenter       */
1075
1076 nb_monitorenter:
1077         lda xpc,-4(ra)
1078         ldq xptr,string_java_lang_NullPointerException
1079         jmp zero,asm_throw_and_handle_nat_exception
1080 #if 0
1081         subq    sp,8,sp
1082     stq     ra,0(sp)
1083     jsr     ra,new_nullpointerexception
1084     ldgp    gp,0(ra)
1085         mov     v0,xptr
1086     ldq     ra,0(sp)
1087         addq    sp,8,sp
1088         
1089         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1090         br      asm_handle_nat_exception
1091 #endif
1092
1093         .end    asm_builtin_monitorenter
1094 #endif
1095
1096
1097 /********************* function asm_builtin_monitorexit ************************
1098 *                                                                              *
1099 *   Does null check and calls monitorexit or throws an exception               *
1100 *                                                                              *
1101 *******************************************************************************/
1102
1103 #if defined(USE_THREADS)
1104         .ent    asm_builtin_monitorexit
1105
1106 asm_builtin_monitorexit:
1107         ldgp    gp,0(pv)
1108         lda     pv,builtin_monitorexit
1109         beq     a0,nb_monitorexit         /* if (null) throw exception            */
1110         jmp     zero,(pv)                 /* else call builtin_monitorexit        */
1111
1112 nb_monitorexit:
1113         lda     xpc,-4(ra)
1114         ldq     xptr,string_java_lang_NullPointerException
1115         jmp     zero,asm_throw_and_handle_nat_exception
1116 #if 0
1117         subq    sp,8,sp
1118     stq     ra,0(sp)
1119     jsr     ra,new_nullpointerexception
1120     ldgp    gp,0(ra)
1121         mov     v0,xptr
1122     ldq     ra,0(sp)
1123         addq    sp,8,sp
1124         
1125         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1126         br      asm_handle_nat_exception
1127 #endif
1128
1129         .end    asm_builtin_monitorexit
1130 #endif
1131
1132
1133 /************************ function asm_builtin_idiv ****************************
1134 *                                                                              *
1135 *   Does null check and calls idiv or throws an exception                      *
1136 *                                                                              *
1137 *******************************************************************************/
1138
1139         .ent    asm_builtin_idiv
1140
1141 asm_builtin_idiv:
1142         ldgp    gp,0(pv)
1143         lda     pv,builtin_idiv
1144         beq     a1,nb_idiv                /* if (null) throw exception            */
1145         jmp     zero,(pv)                 /* else call builtin_idiv               */
1146
1147 nb_idiv:
1148         ldq     xptr,string_java_lang_ArithmeticException_message
1149         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1150         br      asm_throw_and_handle_arithmetic_exception
1151
1152         .end    asm_builtin_idiv
1153
1154
1155 /************************ function asm_builtin_ldiv ****************************
1156 *                                                                              *
1157 *   Does null check and calls ldiv or throws an exception                      *
1158 *                                                                              *
1159 *******************************************************************************/
1160
1161         .ent    asm_builtin_ldiv
1162
1163 asm_builtin_ldiv:
1164         ldgp    gp,0(pv)
1165         lda     pv,builtin_ldiv
1166         beq     a1,nb_ldiv                /* if (null) throw exception            */
1167         jmp     zero,(pv)                 /* else call builtin_ldiv               */
1168
1169 nb_ldiv:
1170         ldq     xptr,string_java_lang_ArithmeticException_message
1171         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1172         br      asm_throw_and_handle_arithmetic_exception
1173
1174         .end    asm_builtin_ldiv
1175
1176
1177 /************************ function asm_builtin_irem ****************************
1178 *                                                                              *
1179 *   Does null check and calls irem or throws an exception                      *
1180 *                                                                              *
1181 *******************************************************************************/
1182
1183         .ent    asm_builtin_irem
1184
1185 asm_builtin_irem:
1186         ldgp    gp,0(pv)
1187         lda     pv,builtin_irem
1188         beq     a1,nb_irem                /* if (null) throw exception            */
1189         jmp     zero,(pv)                 /* else call builtin_irem               */
1190
1191 nb_irem:
1192         ldq     xptr,string_java_lang_ArithmeticException_message
1193         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1194         br      asm_throw_and_handle_arithmetic_exception
1195
1196         .end    asm_builtin_irem
1197
1198
1199 /************************ function asm_builtin_lrem ****************************
1200 *                                                                              *
1201 *   Does null check and calls lrem or throws an exception                      *
1202 *                                                                              *
1203 *******************************************************************************/
1204
1205         .ent    asm_builtin_lrem
1206
1207 asm_builtin_lrem:
1208         ldgp    gp,0(pv)
1209         lda     pv,builtin_lrem
1210         beq     a1,nb_lrem                /* if (null) throw exception            */
1211         jmp     zero,(pv)                 /* else call builtin_lrem               */
1212
1213 nb_lrem:
1214         ldq     xptr,string_java_lang_ArithmeticException_message
1215         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1216         br      asm_throw_and_handle_arithmetic_exception
1217
1218         .end    asm_builtin_lrem
1219
1220
1221 /******************* function asm_builtin_checkarraycast ***********************
1222 *                                                                              *
1223 *   Does the cast check and eventually throws an exception                     *
1224 *                                                                              *
1225 *******************************************************************************/
1226
1227         .ent    asm_builtin_checkarraycast
1228
1229 asm_builtin_checkarraycast:
1230         ldgp    gp,0(pv)
1231         lda     sp,-16(sp)                /* allocate stack space                 */
1232         stq     ra,0(sp)                  /* save return address                  */
1233         stq     a0,8(sp)                  /* save object pointer                  */
1234         jsr     ra,builtin_checkarraycast /* builtin_checkarraycast               */
1235         ldgp    gp,0(ra)
1236         beq     v0,nb_carray_throw        /* if (false) throw exception           */
1237         ldq     ra,0(sp)                  /* restore return address               */
1238         ldq     v0,8(sp)                  /* return object pointer                */
1239         lda     sp,16(sp)                 /* free stack space                     */
1240         jmp     zero,(ra)
1241
1242 nb_carray_throw:
1243         ldq     ra,0(sp)
1244         lda     sp,16(sp)
1245         lda     xpc,-4(ra)
1246         ldq     xptr,string_java_lang_ClassCastException
1247         jmp     zero,asm_throw_and_handle_nat_exception
1248 #if 0
1249         ldq     a0,string_java_lang_ClassCastException
1250     jsr     ra,new_exception
1251     ldgp    gp,0(ra)
1252         mov     v0,xptr
1253
1254         ldq     ra,0(sp)                  /* restore return address               */
1255         lda     sp,16(sp)                 /* free stack space                     */
1256         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1257         br      asm_handle_nat_exception
1258 #endif
1259
1260         .end    asm_builtin_checkarraycast
1261
1262
1263 /******************* function asm_builtin_aastore ******************************
1264 *                                                                              *
1265 *   Does the cast check and eventually throws an exception                     *
1266 *                                                                              *
1267 *******************************************************************************/
1268
1269         .ent    asm_builtin_aastore
1270
1271 asm_builtin_aastore:
1272         ldgp    gp,0(pv)
1273         beq     a0,nb_aastore_null        /* if null pointer throw exception      */
1274         ldl     t0,offarraysize(a0)       /* load size                            */
1275         lda     sp,-24(sp)                /* allocate stack space                 */
1276         stq     ra,0(sp)                  /* save return address                  */
1277         s8addq  a1,a0,t1                  /* add index*8 to arrayref              */
1278         cmpult  a1,t0,t0                  /* do bound check                       */
1279         beq     t0,nb_aastore_bound       /* if out of bounds throw exception     */
1280         mov     a2,a1                     /* object is second argument            */
1281         stq     t1,8(sp)                  /* save store position                  */
1282         stq     a1,16(sp)                 /* save object                          */
1283         jsr     ra,builtin_canstore       /* builtin_canstore(arrayref,object)    */
1284         ldgp    gp,0(ra)
1285         ldq     ra,0(sp)                  /* restore return address               */
1286         ldq     a0,8(sp)                  /* restore store position               */
1287         ldq     a1,16(sp)                 /* restore object                       */
1288         lda     sp,24(sp)                 /* free stack space                     */
1289         beq     v0,nb_aastore_throw       /* if (false) throw exception           */
1290         stq     a1,offobjarrdata(a0)      /* store objectptr in array             */
1291         jmp     zero,(ra)
1292
1293 nb_aastore_null:
1294         ldq     xptr,string_java_lang_NullPointerException
1295         mov     ra,xpc
1296         jmp     zero,asm_throw_and_handle_nat_exception
1297 #if 0   
1298         subq    sp,8,sp                   /* allocate stack space                 */
1299         stq     ra,0(sp)                  /* save return address                  */
1300     jsr     ra,new_nullpointerexception
1301     ldgp    gp,0(ra)
1302         mov     v0,xptr
1303         ldq     ra,0(sp)
1304         addq    sp,8,sp
1305
1306         mov     ra,xpc                    /* faulting address is return adress    */
1307         br      asm_handle_nat_exception
1308 #endif
1309 nb_aastore_bound:
1310         ldq     ra,0(sp)
1311         lda     sp,24(sp)
1312         mov     ra,xpc
1313         mov     a1,xptr
1314         jmp     zero,asm_throw_and_handle_arrayindexoutofbounds_exception
1315 #if 0
1316         ldq     a0,string_java_lang_ArrayIndexOutOfBoundsException
1317     jsr     ra,new_exception_int      /* a1 already contains the index        */
1318     ldgp    gp,0(ra)
1319         mov     v0,xptr
1320
1321         ldq     ra,0(sp)                  /* restore return address               */
1322         lda     sp,24(sp)                 /* free stack space                     */
1323         mov     ra,xpc                    /* faulting address is return adress    */
1324         br      asm_handle_nat_exception
1325 #endif
1326 nb_aastore_throw:
1327         mov     ra,xpc
1328         ldq     xptr,string_java_lang_ArrayStoreException
1329         jmp     zero,asm_throw_and_handle_nat_exception
1330 #if 0
1331         subq    sp,8,sp                   /* allocate stack space                 */
1332         stq     ra,0(sp)                  /* save return address                  */
1333     jsr     ra,new_arraystoreexception
1334     ldgp    gp,0(ra)
1335         mov     v0,xptr
1336         ldq     ra,0(sp)
1337         addq    sp,8,sp
1338
1339         mov     ra,xpc                    /* faulting address is return adress    */
1340         br      asm_handle_nat_exception
1341 #endif
1342         .end    asm_builtin_aastore
1343
1344
1345 /******************* function asm_initialize_thread_stack **********************
1346 *                                                                              *
1347 *   initialized a thread stack                                                 *
1348 *                                                                              *
1349 *******************************************************************************/
1350
1351         .ent    asm_initialize_thread_stack
1352
1353 asm_initialize_thread_stack:
1354         lda     a1,-128(a1)
1355         stq     zero, 0(a1)
1356         stq     zero, 8(a1)
1357         stq     zero, 16(a1)
1358         stq     zero, 24(a1)
1359         stq     zero, 32(a1)
1360         stq     zero, 40(a1)
1361         stq     zero, 48(a1)
1362         stt     fzero, 56(a1)
1363         stt     fzero, 64(a1)
1364         stt     fzero, 72(a1)
1365         stt     fzero, 80(a1)
1366         stt     fzero, 88(a1)
1367         stt     fzero, 96(a1)
1368         stt     fzero, 104(a1)
1369         stt     fzero, 112(a1)
1370         stq     a0, 120(a1)
1371         mov     a1, v0
1372         jmp     zero,(ra)
1373
1374         .end    asm_initialize_thread_stack
1375
1376
1377 /******************* function asm_perform_threadswitch *************************
1378 *                                                                              *
1379 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1380 *                                                                              *
1381 *   performs a threadswitch                                                    *
1382 *                                                                              *
1383 *******************************************************************************/
1384
1385         .ent    asm_perform_threadswitch
1386
1387 asm_perform_threadswitch:
1388         subq    sp,128,sp
1389         stq     s0, 0(sp)
1390         stq     s1, 8(sp)
1391         stq     s2, 16(sp)
1392         stq     s3, 24(sp)
1393         stq     s4, 32(sp)
1394         stq     s5, 40(sp)
1395         stq     s6, 48(sp)
1396         stt     sf0, 56(sp)
1397         stt     sf1, 64(sp)
1398         stt     sf2, 72(sp)
1399         stt     sf3, 80(sp)
1400         stt     sf4, 88(sp)
1401         stt     sf5, 96(sp)
1402         stt     sf6, 104(sp)
1403         stt     sf7, 112(sp)
1404         stq     ra, 120(sp)
1405         stq     sp, 0(a0)
1406         stq     sp, 0(a2)
1407         ldq     sp, 0(a1)
1408         ldq     s0, 0(sp)
1409         ldq     s1, 8(sp)
1410         ldq     s2, 16(sp)
1411         ldq     s3, 24(sp)
1412         ldq     s4, 32(sp)
1413         ldq     s5, 40(sp)
1414         ldq     s6, 48(sp)
1415         ldt     sf0, 56(sp)
1416         ldt     sf1, 64(sp)
1417         ldt     sf2, 72(sp)
1418         ldt     sf3, 80(sp)
1419         ldt     sf4, 88(sp)
1420         ldt     sf5, 96(sp)
1421         ldt     sf6, 104(sp)
1422         ldt     sf7, 112(sp)
1423         ldq     ra, 120(sp)
1424         mov     ra, pv
1425         addq    sp, 128, sp
1426         jmp     zero,(ra)
1427
1428         .end    asm_perform_threadswitch
1429
1430
1431 /********************* function asm_switchstackandcall *************************
1432 *                                                                              *
1433 *  void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1434 *                               void *p);                                      *
1435 *                                                                              *
1436 *   Switches to a new stack, calls a function and switches back.               *
1437 *       a0      new stack pointer                                              *
1438 *       a1      function pointer                                               *
1439 *               a2              pointer to variable where stack top should be stored           *
1440 *               a3      pointer to user data, is passed to the function                *
1441 *                                                                              *
1442 *******************************************************************************/
1443
1444
1445         .ent    asm_switchstackandcall
1446
1447 asm_switchstackandcall:
1448         lda     a0,-2*8(a0)     /* allocate new stack                                 */
1449         stq     ra,0(a0)        /* save return address on new stack                   */
1450         stq     sp,1*8(a0)      /* save old stack pointer on new stack                */
1451         stq sp,0(a2)        /* save old stack pointer to variable                 */
1452         mov     a0,sp           /* switch to new stack                                */
1453         
1454         mov     a1,pv           /* load function pointer                              */
1455         mov a3,a0           /* pass pointer */
1456         jmp     ra,(pv)         /* and call function                                  */
1457
1458         ldq     ra,0(sp)        /* load return address                                */
1459         ldq     sp,1*8(sp)      /* switch to old stack                                */
1460
1461         jmp     zero,(ra)       /* return                                             */
1462
1463         .end    asm_switchstackandcall
1464
1465         .ent    asm_getclassvalues_atomic
1466
1467 asm_getclassvalues_atomic:
1468 _crit_restart2:
1469 _crit_begin2:
1470         ldl     t0,offbaseval(a0)
1471         ldl     t1,offdiffval(a0)
1472         ldl     t2,offbaseval(a1)
1473 _crit_end2:
1474         stl     t0,offcast_super_baseval(a2)
1475         stl     t1,offcast_super_diffval(a2)
1476         stl     t2,offcast_sub_baseval(a2)
1477         jmp      zero,(ra)
1478
1479         .end    asm_getclassvalues_atomic
1480
1481     .data
1482
1483 asm_criticalsections:
1484 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1485     .quad   _crit_begin1
1486     .quad   _crit_end1
1487     .quad   _crit_restart1
1488     .quad   _crit_begin2
1489     .quad   _crit_end2
1490     .quad   _crit_restart2
1491 #endif
1492     .quad   0
1493
1494
1495         .ent asm_prepare_native_stackinfo
1496 asm_prepare_native_stackinfo:
1497         lda sp,-24(sp)
1498         stq ra,0(sp)
1499         jsr ra,builtin_asm_get_stackframeinfo
1500         stq v0,16(sp)
1501         ldq t0,0(v0)
1502         stq t0,8(sp)
1503         ldq ra,0(sp)
1504         lda sp,8(sp)
1505         stq sp,0(v0)
1506         ret
1507         .end asm_prepare_native_stackinfo
1508
1509         .ent asm_remove_native_stackinfo
1510 asm_remove_native_stackinfo:
1511         ldq t0,0(sp)
1512         ldq t1,8(sp)
1513         stq t0,0(t1)
1514         lda sp,40(sp)
1515         ret
1516         .end asm_remove_native_stackinfo
1517
1518 /*
1519  * These are local overrides for various environment variables in Emacs.
1520  * Please do not remove this and leave it at the end of the file, where
1521  * Emacs will automagically detect them.
1522  * ---------------------------------------------------------------------
1523  * Local variables:
1524  * mode: asm
1525  * indent-tabs-mode: t
1526  * c-basic-offset: 4
1527  * tab-width: 4
1528  * End:
1529  */