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