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