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