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