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