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