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