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