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