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