577b428525d59317e85c2ac8fd6f563e5e97a9a7
[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 1695 2004-12-06 12:31:42Z twisti $
34
35 */
36
37
38 #include "config.h"        
39 #include "vm/jit/alpha/offsets.h"
40 #include "vm/jit/alpha/asmoffsets.h"
41
42
43 #define v0      $0
44
45 #define t0      $1
46 #define t1      $2
47 #define t2      $3
48 #define t3      $4
49 #define t4      $5
50 #define t5      $6
51 #define t6      $7
52 #define t7      $8
53
54 #define s0      $9
55 #define s1      $10
56 #define s2      $11
57 #define s3      $12
58 #define s4      $13
59 #define s5      $14
60 #define s6      $15
61
62 #define a0      $16
63 #define a1      $17
64 #define a2      $18
65 #define a3      $19
66 #define a4      $20
67 #define a5      $21
68
69 #define t8      $22
70 #define t9      $23
71 #define t10     $24
72 #define t11     $25
73 #define ra      $26
74 #define t12     $27
75
76 #define pv      t12
77 #define AT      $at
78 #define gp      $29
79 #define sp      $30
80 #define zero    $31
81
82 #define itmp1   $25
83 #define itmp2   $28
84 #define itmp3   $29
85
86 #define xptr    itmp1
87 #define xpc     itmp2
88
89 #define sf0     $f2
90 #define sf1     $f3
91 #define sf2     $f4
92 #define sf3     $f5
93 #define sf4     $f6
94 #define sf5     $f7
95 #define sf6     $f8
96 #define sf7     $f9
97
98 #define fzero   $f31
99
100
101 #define PAL_imb 0x86
102
103         .text
104         .set    noat
105         .set    noreorder
106
107
108 /********************* exported functions and variables ***********************/
109
110         .globl has_no_x_instr_set
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
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         addq    sp,t0,t0              /* add stackptr to Offset                   */
886         ldq     a0,-8(t0)             /* load monitorexit pointer                 */
887
888         lda     sp,-7*8(sp)           /* allocate stack                           */
889         stq     t0,0*8(sp)            /* save used register                       */
890         stq     t1,1*8(sp)
891         stq     t3,2*8(sp)
892         stq     xptr,3*8(sp)
893         stq     xpc,4*8(sp)
894         stq     pv,5*8(sp)
895         stq     ra,6*8(sp)
896
897         br      ra,ex_mon_load        /* set ra for gp loading                    */
898 ex_mon_load:
899         ldgp    gp,0(ra)              /* load gp                                  */
900         jsr     ra,builtin_monitorexit/* builtin_monitorexit(objectptr)           */
901         
902         ldq     t0,0*8(sp)            /* restore used register                    */
903         ldq     t1,1*8(sp)
904         ldq     t3,2*8(sp)
905         ldq     xptr,3*8(sp)
906         ldq     xpc,4*8(sp)
907         ldq     pv,5*8(sp)
908         ldq     ra,6*8(sp)
909         lda     sp,7*8(sp)            /* deallocate stack                         */
910
911 no_monitor_exit:
912         ldl     t0,FrameSize(pv)      /* t0 = frame size                          */
913         addq    sp,t0,sp              /* unwind stack                             */
914         mov     sp,t0                 /* t0 = pointer to save area                */
915         ldl     t1,IsLeaf(pv)         /* t1 = is leaf procedure                   */
916         bne     t1,ex_no_restore      /* if (leaf) skip                           */
917         ldq     ra,-8(t0)             /* restore ra                               */
918         lda     t0,-8(t0)             /* t0--                                     */
919 ex_no_restore:
920         mov     ra,xpc                /* the new xpc is ra                        */
921         ldl     t1,IntSave(pv)        /* t1 = saved int register count            */
922         br      t2,ex_int1            /* t2 = current pc                          */
923 ex_int1:
924         lda     t2,44(t2)             /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
925         negl    t1,t1                 /* negate register count                    */
926         s4addq  t1,t2,t2              /* t2 = ex_int_sav - 4 * register count     */
927         jmp     zero,(t2)             /* jump to save position                    */
928         ldq     s0,-56(t0)
929         ldq     s1,-48(t0)
930         ldq     s2,-40(t0)
931         ldq     s3,-32(t0)
932         ldq     s4,-24(t0)
933         ldq     s5,-16(t0)
934         ldq     s6,-8(t0)
935 ex_int2:
936         s8addq  t1,t0,t0              /* t0 = t0 - 8 * register count             */
937
938         ldl     t1,FltSave(pv)        /* t1 = saved flt register count            */
939         br      t2,ex_flt1            /* t2 = current pc                          */
940 ex_flt1:
941         lda     t2,48(t2)             /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
942         negl    t1,t1                 /* negate register count                    */
943         s4addq  t1,t2,t2              /* t2 = ex_flt_sav - 4 * register count     */
944         jmp     zero,(t2)             /* jump to save position                    */
945         ldt     $f2,-64(t0)
946         ldt     $f3,-56(t0)
947         ldt     $f4,-48(t0)
948         ldt     $f5,-40(t0)
949         ldt     $f6,-32(t0)
950         ldt     $f7,-24(t0)
951         ldt     $f8,-16(t0)
952         ldt     $f9,-8(t0)
953 ex_flt2:
954         ldl     t0,0(ra)              /* load instruction LDA PV,xxx(RA)          */
955         sll     t0,48,t0
956         sra     t0,48,t0              /* isolate offset                           */
957         addq    t0,ra,pv              /* compute update address                   */
958         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(PV)         */
959         srl     t0,16,t0              /* isolate instruction code                 */
960         lda     t0,-0x177b(t0)        /* test for LDAH                            */
961         bne     t0,ex_stack_loop       
962         ldl     t0,4(ra)              /* load instruction LDAH PV,xxx(RA)         */
963         sll     t0,16,t0              /* compute high offset                      */
964         addl    t0,0,t0               /* sign extend high offset                  */
965         addq    t0,pv,pv              /* compute update address                   */
966         br      ex_stack_loop
967
968         .end    asm_handle_nat_exception
969
970
971 /* asm_check_clinit ************************************************************
972
973    DOCUMENT ME!!!
974
975    Arguments:
976
977         itmp1: pointer to class
978
979    Stack layout:
980
981         0   mcode  ; machine code to patch back in
982
983 *******************************************************************************/
984                 
985     .ent    asm_check_clinit
986
987 asm_check_clinit:
988         ldgp    gp,0(itmp2)           /* function is called via `jsr ra,itmp1'    */
989
990         subq    sp,8*8,sp
991
992         stq             ra,0*8(sp)            /* save return address                      */
993         stq     pv,1*8(sp)            /* save pv of calling java function         */
994         stq             a0,2*8(sp)            /* save argument registers for leaf         */
995         stq             a1,3*8(sp)            /* functions and native stub                */
996         stq             a2,4*8(sp)
997         stq             a3,5*8(sp)
998         stq             a4,6*8(sp)
999         stq             a5,7*8(sp)
1000                 
1001         ldl             itmp2,offclassinit(itmp1)
1002         bne             itmp2,L_is_initialized
1003         
1004         mov             itmp1,a0              /* move class pointer to a0                 */
1005         jsr             ra,class_init
1006     ldgp    gp,0(ra)
1007                 
1008         beq     v0,L_initializererror
1009
1010 L_is_initialized:
1011         ldq     ra,0*8(sp)            /* get return address                       */
1012         subq    ra,1*4,ra             /* go back 1 instruction                    */
1013         ldl     itmp1,8*8(sp)         /* load machine code from stack             */
1014         stl     itmp1,0(ra)           /* store the machine code                   */
1015
1016         call_pal PAL_imb              /* synchronise instruction cache            */
1017
1018         ldq             ra,0*8(sp)            /* restore return address                   */
1019         ldq     pv,1*8(sp)            /* restore pv of calling java function      */
1020         ldq             a0,2*8(sp)            /* restore argument registers               */
1021         ldq             a1,3*8(sp)
1022         ldq             a2,4*8(sp)
1023         ldq             a3,5*8(sp)
1024         ldq             a4,6*8(sp)
1025         ldq             a5,7*8(sp)
1026
1027         addq    sp,(8+1)*8,sp         /* remove stack frame (+1 for machine code) */
1028
1029         subq    ra,1*4,ra             /* go back 1 instruction                    */
1030         jmp             zero,(ra)             /* jump to the new code                     */
1031
1032 L_initializererror:
1033 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1034         jsr     ra,builtin_asm_get_exceptionptrptr
1035 #else
1036         lda     v0,_exceptionptr
1037 #endif
1038         ldq     xptr,0(v0)            /* get the exception pointer                */
1039         stq     zero,0(v0)            /* clear the exception pointer              */
1040
1041         ldq             ra,0*8(sp)            /* restore return address                   */
1042         ldq     pv,1*8(sp)            /* restore pv of calling java function      */
1043         ldq             a0,2*8(sp)            /* restore argument registers               */
1044         ldq             a1,3*8(sp)
1045         ldq             a2,4*8(sp)
1046         ldq             a3,5*8(sp)
1047         ldq             a4,6*8(sp)
1048         ldq             a5,7*8(sp)
1049
1050         addq    sp,(8+1)*8,sp         /* remove stack frame (+1 for machine code) */
1051
1052         subq    ra,4,xpc
1053         br      asm_handle_exception  /* we have the pv of the calling java func. */
1054
1055         .end    asm_check_clinit
1056
1057                 
1058 /********************* function asm_builtin_monitorenter ***********************
1059 *                                                                              *
1060 *   Does null check and calls monitorenter or throws an exception              *
1061 *                                                                              *
1062 *******************************************************************************/
1063
1064         .ent    asm_builtin_monitorenter
1065
1066 asm_builtin_monitorenter:
1067         ldgp    gp,0(pv)
1068         lda     pv,builtin_monitorenter
1069         beq     a0,nb_monitorenter        /* if (null) throw exception            */
1070         jmp     zero,(pv)                 /* else call builtin_monitorenter       */
1071
1072 nb_monitorenter:
1073         lda xpc,-4(ra)
1074         ldq xptr,string_java_lang_NullPointerException
1075         jmp zero,asm_throw_and_handle_nat_exception
1076 #if 0
1077         subq    sp,8,sp
1078     stq     ra,0(sp)
1079     jsr     ra,new_nullpointerexception
1080     ldgp    gp,0(ra)
1081         mov     v0,xptr
1082     ldq     ra,0(sp)
1083         addq    sp,8,sp
1084         
1085         lda     xpc,-4(ra)                /* faulting address is return adress - 4*/
1086         br      asm_handle_nat_exception
1087 #endif
1088         .end    asm_builtin_monitorenter
1089
1090
1091 /********************* function asm_builtin_monitorexit ************************
1092 *                                                                              *
1093 *   Does null check and calls monitorexit or throws an exception               *
1094 *                                                                              *
1095 *******************************************************************************/
1096
1097         .ent    asm_builtin_monitorexit
1098
1099 asm_builtin_monitorexit:
1100         ldgp    gp,0(pv)
1101         lda     pv,builtin_monitorexit
1102         beq     a0,nb_monitorexit         /* if (null) throw exception            */
1103         jmp     zero,(pv)                 /* else call builtin_monitorexit        */
1104
1105 nb_monitorexit:
1106         lda     xpc,-4(ra)
1107         ldq     xptr,string_java_lang_NullPointerException
1108         jmp     zero,asm_throw_and_handle_nat_exception
1109 #if 0
1110         subq    sp,8,sp
1111     stq     ra,0(sp)
1112     jsr     ra,new_nullpointerexception
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     jsr     ra,new_nullpointerexception
1292     ldgp    gp,0(ra)
1293         mov     v0,xptr
1294         ldq     ra,0(sp)
1295         addq    sp,8,sp
1296
1297         mov     ra,xpc                    /* faulting address is return adress    */
1298         br      asm_handle_nat_exception
1299 #endif
1300 nb_aastore_bound:
1301         ldq     ra,0(sp)
1302         lda     sp,24(sp)
1303         mov     ra,xpc
1304         mov     a1,xptr
1305         jmp     zero,asm_throw_and_handle_arrayindexoutofbounds_exception
1306 #if 0
1307         ldq     a0,string_java_lang_ArrayIndexOutOfBoundsException
1308     jsr     ra,new_exception_int      /* a1 already contains the index        */
1309     ldgp    gp,0(ra)
1310         mov     v0,xptr
1311
1312         ldq     ra,0(sp)                  /* restore return address               */
1313         lda     sp,24(sp)                 /* free stack space                     */
1314         mov     ra,xpc                    /* faulting address is return adress    */
1315         br      asm_handle_nat_exception
1316 #endif
1317 nb_aastore_throw:
1318         mov     ra,xpc
1319         ldq     xptr,string_java_lang_ArrayStoreException
1320         jmp     zero,asm_throw_and_handle_nat_exception
1321 #if 0
1322         subq    sp,8,sp                   /* allocate stack space                 */
1323         stq     ra,0(sp)                  /* save return address                  */
1324     jsr     ra,new_arraystoreexception
1325     ldgp    gp,0(ra)
1326         mov     v0,xptr
1327         ldq     ra,0(sp)
1328         addq    sp,8,sp
1329
1330         mov     ra,xpc                    /* faulting address is return adress    */
1331         br      asm_handle_nat_exception
1332 #endif
1333         .end    asm_builtin_aastore
1334
1335
1336 /******************* function asm_initialize_thread_stack **********************
1337 *                                                                              *
1338 *   initialized a thread stack                                                 *
1339 *                                                                              *
1340 *******************************************************************************/
1341
1342         .ent    asm_initialize_thread_stack
1343
1344 asm_initialize_thread_stack:
1345         lda     a1,-128(a1)
1346         stq     zero, 0(a1)
1347         stq     zero, 8(a1)
1348         stq     zero, 16(a1)
1349         stq     zero, 24(a1)
1350         stq     zero, 32(a1)
1351         stq     zero, 40(a1)
1352         stq     zero, 48(a1)
1353         stt     fzero, 56(a1)
1354         stt     fzero, 64(a1)
1355         stt     fzero, 72(a1)
1356         stt     fzero, 80(a1)
1357         stt     fzero, 88(a1)
1358         stt     fzero, 96(a1)
1359         stt     fzero, 104(a1)
1360         stt     fzero, 112(a1)
1361         stq     a0, 120(a1)
1362         mov     a1, v0
1363         jmp     zero,(ra)
1364
1365         .end    asm_initialize_thread_stack
1366
1367
1368 /******************* function asm_perform_threadswitch *************************
1369 *                                                                              *
1370 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1371 *                                                                              *
1372 *   performs a threadswitch                                                    *
1373 *                                                                              *
1374 *******************************************************************************/
1375
1376         .ent    asm_perform_threadswitch
1377
1378 asm_perform_threadswitch:
1379         subq    sp,128,sp
1380         stq     s0, 0(sp)
1381         stq     s1, 8(sp)
1382         stq     s2, 16(sp)
1383         stq     s3, 24(sp)
1384         stq     s4, 32(sp)
1385         stq     s5, 40(sp)
1386         stq     s6, 48(sp)
1387         stt     sf0, 56(sp)
1388         stt     sf1, 64(sp)
1389         stt     sf2, 72(sp)
1390         stt     sf3, 80(sp)
1391         stt     sf4, 88(sp)
1392         stt     sf5, 96(sp)
1393         stt     sf6, 104(sp)
1394         stt     sf7, 112(sp)
1395         stq     ra, 120(sp)
1396         stq     sp, 0(a0)
1397         stq     sp, 0(a2)
1398         ldq     sp, 0(a1)
1399         ldq     s0, 0(sp)
1400         ldq     s1, 8(sp)
1401         ldq     s2, 16(sp)
1402         ldq     s3, 24(sp)
1403         ldq     s4, 32(sp)
1404         ldq     s5, 40(sp)
1405         ldq     s6, 48(sp)
1406         ldt     sf0, 56(sp)
1407         ldt     sf1, 64(sp)
1408         ldt     sf2, 72(sp)
1409         ldt     sf3, 80(sp)
1410         ldt     sf4, 88(sp)
1411         ldt     sf5, 96(sp)
1412         ldt     sf6, 104(sp)
1413         ldt     sf7, 112(sp)
1414         ldq     ra, 120(sp)
1415         mov     ra, pv
1416         addq    sp, 128, sp
1417         jmp     zero,(ra)
1418
1419         .end    asm_perform_threadswitch
1420
1421
1422 /********************* function asm_switchstackandcall *************************
1423 *                                                                              *
1424 *  void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1425 *                               void *p);                                      *
1426 *                                                                              *
1427 *   Switches to a new stack, calls a function and switches back.               *
1428 *       a0      new stack pointer                                              *
1429 *       a1      function pointer                                               *
1430 *               a2              pointer to variable where stack top should be stored           *
1431 *               a3      pointer to user data, is passed to the function                *
1432 *                                                                              *
1433 *******************************************************************************/
1434
1435
1436         .ent    asm_switchstackandcall
1437
1438 asm_switchstackandcall:
1439         lda     a0,-2*8(a0)     /* allocate new stack                                 */
1440         stq     ra,0(a0)        /* save return address on new stack                   */
1441         stq     sp,1*8(a0)      /* save old stack pointer on new stack                */
1442         stq sp,0(a2)        /* save old stack pointer to variable                 */
1443         mov     a0,sp           /* switch to new stack                                */
1444         
1445         mov     a1,pv           /* load function pointer                              */
1446         mov a3,a0           /* pass pointer */
1447         jmp     ra,(pv)         /* and call function                                  */
1448
1449         ldq     ra,0(sp)        /* load return address                                */
1450         ldq     sp,1*8(sp)      /* switch to old stack                                */
1451
1452         jmp     zero,(ra)       /* return                                             */
1453
1454         .end    asm_switchstackandcall
1455
1456         .ent    asm_getclassvalues_atomic
1457
1458 asm_getclassvalues_atomic:
1459 _crit_restart2:
1460 _crit_begin2:
1461         ldl     t0,offbaseval(a0)
1462         ldl     t1,offdiffval(a0)
1463         ldl     t2,offbaseval(a1)
1464 _crit_end2:
1465         stl     t0,offcast_super_baseval(a2)
1466         stl     t1,offcast_super_diffval(a2)
1467         stl     t2,offcast_sub_baseval(a2)
1468         jmp      zero,(ra)
1469
1470         .end    asm_getclassvalues_atomic
1471
1472     .data
1473
1474 asm_criticalsections:
1475 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1476     .quad   _crit_begin1
1477     .quad   _crit_end1
1478     .quad   _crit_restart1
1479     .quad   _crit_begin2
1480     .quad   _crit_end2
1481     .quad   _crit_restart2
1482 #endif
1483     .quad   0
1484
1485
1486         .ent asm_prepare_native_stackinfo
1487 asm_prepare_native_stackinfo:
1488         lda sp,-24(sp)
1489         stq ra,0(sp)
1490         jsr ra,builtin_asm_get_stackframeinfo
1491         stq v0,16(sp)
1492         ldq t0,0(v0)
1493         stq t0,8(sp)
1494         ldq ra,0(sp)
1495         lda sp,8(sp)
1496         stq sp,0(v0)
1497         ret
1498         .end asm_prepare_native_stackinfo
1499
1500         .ent asm_remove_native_stackinfo
1501 asm_remove_native_stackinfo:
1502         ldq t0,0(sp)
1503         ldq t1,8(sp)
1504         stq t0,0(t1)
1505         lda sp,40(sp)
1506         ret
1507         .end asm_remove_native_stackinfo
1508
1509 /*
1510  * These are local overrides for various environment variables in Emacs.
1511  * Please do not remove this and leave it at the end of the file, where
1512  * Emacs will automagically detect them.
1513  * ---------------------------------------------------------------------
1514  * Local variables:
1515  * mode: asm
1516  * indent-tabs-mode: t
1517  * c-basic-offset: 4
1518  * tab-width: 4
1519  * End:
1520  */