1 /* vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
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,
9 This file is part of CACAO.
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.
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.
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
26 Contact: cacao@complang.tuwien.ac.at
28 Authors: Andreas Krall
31 Changes: Joseph Wenninger
33 $Id: asmpart.S 1690 2004-12-06 08:48:07Z twisti $
39 #include "vm/jit/alpha/offsets.h"
40 #include "vm/jit/alpha/asmoffsets.h"
43 #define MethodPointer -8
49 /* DEFINE LINE NUMBER STUFF HERE */
50 #define ExTableSize -56
51 #define ExTableStart -56
53 #define ExEntrySize -32
56 #define ExHandlerPC -24
57 #define ExCatchType -32
125 /********************* exported functions and variables ***********************/
127 .globl has_no_x_instr_set
128 .globl synchronize_caches
129 .globl asm_calljavafunction
130 .globl asm_calljavafunction2
131 .globl asm_calljavafunction2double
132 .globl asm_calljavafunction2long
133 .globl asm_call_jit_compiler
134 .globl asm_throw_and_handle_exception
135 .globl asm_throw_and_handle_nat_exception
136 .globl asm_throw_and_handle_arithmetic_exception
137 .globl asm_throw_and_handle_arrayindexoutofbounds_exception
138 .globl asm_handle_exception
139 .globl asm_handle_nat_exception
140 .globl asm_check_clinit
141 .globl asm_builtin_checkcast
142 .globl asm_builtin_checkarraycast
143 .globl asm_builtin_aastore
144 .globl asm_builtin_monitorenter
145 .globl asm_builtin_monitorexit
146 .globl asm_builtin_idiv
147 .globl asm_builtin_irem
148 .globl asm_builtin_ldiv
149 .globl asm_builtin_lrem
150 .globl asm_perform_threadswitch
151 .globl asm_initialize_thread_stack
152 .globl asm_switchstackandcall
153 .globl asm_builtin_trace
154 .globl asm_builtin_exittrace
155 .globl asm_criticalsections
156 .globl asm_getclassvalues_atomic
157 .globl asm_prepare_native_stackinfo
158 .globl asm_remove_native_stackinfo
159 .globl asm_refillin_and_handle_exception
161 /*************************** imported functions *******************************/
164 .globl builtin_monitorexit
165 .globl builtin_throw_exception
166 .globl builtin_trace_exception
167 .globl class_java_lang_Object
170 /*********************** function has_no_x_instr_set ***************************
172 * determines if the byte support instruction set (21164a and higher) *
175 *******************************************************************************/
177 .ent has_no_x_instr_set
180 .long 0x47e03c20 /* amask 1,v0 */
181 jmp zero,(ra) /* return */
183 .end has_no_x_instr_set
186 /********************* function asm_calljavafunction ***************************
188 * This function calls a Java-method (which possibly needs compilation) *
189 * with up to 4 address parameters. *
191 * This functions calls the JIT-compiler which eventually translates the *
192 * method into machine code. *
195 * javaobject_header *asm_calljavafunction (methodinfo *m, *
196 * void *arg1, void *arg2, void *arg3, void *arg4); *
198 *******************************************************************************/
200 .ent asm_calljavafunction
203 .ascii "calljavafunction\0\0"
206 .quad 0 /* catch type all */
207 .quad calljava_xhandler /* handler pc */
208 .quad calljava_xhandler /* end pc */
209 .quad asm_calljavafunction /* start pc */
210 .long 1 /* extable size */
211 .long 0 /* PADDING */
212 .quad 0 /* line number table start */
213 .quad 0 /* line number table size */
214 .long 0 /* PADDING */
215 .long 0 /* fltsave */
216 .long 0 /* intsave */
219 .long 32 /* frame size */
220 .quad 0 /* method pointer (pointer to name) */
222 asm_calljavafunction:
224 lda sp,-32(sp) /* allocate stack space */
225 stq gp,24(sp) /* save global pointer */
226 stq ra,0(sp) /* save return address */
228 stq a0,16(sp) /* save method pointer for compiler */
229 lda v0,16(sp) /* pass pointer to method pointer via v0*/
231 mov a1,a0 /* pass the remaining parameters */
236 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
237 stq $28,8(sp) /* store function address */
238 mov sp,$28 /* set method pointer */
240 ldq pv,8($28) /* method call as in Java */
241 jmp ra,(pv) /* call JIT compiler */
243 lda pv,-64(ra) /* asm_calljavafunction-calljava_jit !!!!!*/
246 ldq ra,0(sp) /* restore return address */
247 ldq gp,24(sp) /* restore global pointer */
248 lda sp,32(sp) /* free stack space */
254 ldq gp,24(sp) /* restore global pointer */
256 jsr ra,builtin_throw_exception
257 ldq ra,0(sp) /* restore return address */
258 lda sp,32(sp) /* free stack space */
260 .end asm_calljavafunction
265 .ent asm_calljavafunction2
268 .ascii "calljavafunction2\0\0"
271 .quad 0 /* catch type all */
272 .quad calljava_xhandler2 /* handler pc */
273 .quad calljava_xhandler2 /* end pc */
274 .quad asm_calljavafunction2 /* start pc */
275 .long 1 /* extable size */
276 .long 0 /* PADDING */
277 .quad 0 /* line number table start */
278 .quad 0 /* line number table size */
279 .long 0 /* PADDING */
280 .long 0 /* fltsave */
281 .long 1 /* intsave */
284 .long 40 /* frame size */
285 .quad 0 /* method pointer (pointer to name) */
287 asm_calljavafunction2:
288 asm_calljavafunction2double:
289 asm_calljavafunction2long:
291 lda sp,-40(sp) /* allocate stack space */
292 stq ra,0(sp) /* save return address */
294 stq gp,8(sp) /* save global pointer */
296 stq a0,32(sp) /* save method pointer for compiler */
297 mov a3,t0 /* pointer to arg block */
298 mov a1,s6 /* arg count */
300 ble s6,calljava_argsloaded
302 ldq a0,offjniitem(t0)
303 ldt $f16,offjniitem(t0)
304 ble s6,calljava_argsloaded
306 ldq a1,offjniitem+sizejniblock*1(t0)
307 ldt $f17,offjniitem+sizejniblock*1(t0)
308 ble s6,calljava_argsloaded
310 ldq a2,offjniitem+sizejniblock*2(t0)
311 ldt $f18,offjniitem+sizejniblock*2(t0)
312 ble s6,calljava_argsloaded
314 ldq a3,offjniitem+sizejniblock*3(t0)
315 ldt $f19,offjniitem+sizejniblock*3(t0)
316 ble s6,calljava_argsloaded
318 ldq a4,offjniitem+sizejniblock*4(t0)
319 ldt $f20,offjniitem+sizejniblock*4(t0)
320 ble s6,calljava_argsloaded
322 ldq a5,offjniitem+sizejniblock*5(t0)
323 ldt $f21,offjniitem+sizejniblock*5(t0)
326 ble s6,calljava_nocopy
332 ldq t3,offjniitem+sizejniblock*6(t0)
335 lda t0,sizejniblock(t0)
337 bne t1,calljava_copyloop
340 lda v0,32(t4) /* pass pointer to method pointer via v0*/
342 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
343 stq $28,16(t4) /* store function address */
344 lda $28,8(t4) /* set method pointer */
346 ldq pv,8($28) /* method call as in Java */
347 jmp ra,(pv) /* call JIT compiler */
349 lda pv,-200(ra) /* asm_calljavafunction-calljava_jit !!!*/
353 ldq ra,0(sp) /* restore return address */
354 ldq gp,8(sp) /* restore global pointer */
356 lda sp,40(sp) /* free stack space */
363 ldq gp,8(sp) /* restore global pointer */
365 jsr ra,builtin_throw_exception
366 ldq ra,0(sp) /* restore return address */
368 lda sp,40(sp) /* free stack space */
370 .end asm_calljavafunction2
373 /****************** function asm_call_jit_compiler *****************************
375 * invokes the compiler for untranslated JavaVM methods. *
377 * Register R0 contains a pointer to the method info structure (prepared *
378 * by createcompilerstub). Using the return address in R26 and the *
379 * offset in the LDA instruction or using the value in methodptr R28 the *
380 * patching address for storing the method address can be computed: *
382 * method address was either loaded using *
383 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
384 * M_LDA (REG_PV, REG_RA, low) *
385 * M_LDAH(REG_PV, REG_RA, high) ; optional *
387 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
388 * in the static case the method pointer can be computed using the *
389 * return address and the lda function following the jmp instruction *
391 *******************************************************************************/
394 .ent asm_call_jit_compiler
395 asm_call_jit_compiler:
398 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
399 srl t8,16,t8 /* shift right register number $yy */
400 and t8,31,t8 /* isolate register number */
401 subl t8,28,t8 /* test for REG_METHODPTR */
403 ldl t8,0(ra) /* load instruction LDA PV,xxx(RA) */
405 sra t8,48,t8 /* isolate offset */
406 addq t8,ra,$28 /* compute update address */
407 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
408 srl t8,16,t8 /* isolate instruction code */
409 lda t8,-0x177b(t8) /* test for LDAH */
411 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
412 sll t8,16,t8 /* compute high offset */
413 addl t8,0,t8 /* sign extend high offset */
414 addq t8,$28,$28 /* compute update address */
416 lda sp,-14*8(sp) /* reserve stack space */
417 stq a0,0*8(sp) /* save all argument registers */
418 stq a1,1*8(sp) /* they could be used by method */
429 stq $28,12*8(sp) /* save method pointer */
430 stq ra,13*8(sp) /* save return address */
432 ldq a0,0(v0) /* pass 'methodinfo' pointer to */
433 jsr ra,jit_compile /* jit compiler */
436 ldq a0,0*8(sp) /* load argument registers */
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 */
452 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
454 sra t8,48,t8 /* isolate offset */
456 addq t8,$28,t8 /* compute update address via method pointer*/
457 stq v0,0(t8) /* save new method address there */
459 call_pal PAL_imb /* synchronise instruction cache */
461 mov v0,pv /* load method address into pv */
463 jmp zero,(pv) /* and call method. The method returns */
464 /* directly to the caller (ra). */
466 .end asm_call_jit_compiler
469 /**************** function asm_refillin_and_handle_exception *******************
471 * This function handles an exception. It does not use the usual calling *
472 * conventions. The exception is passed in REG_ITMP1 and the *
473 * pc from the exception raising position is passed in REG_ITMP2. *
474 * a0 contains the PV of the function causing the problem *
476 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
478 *******************************************************************************/
479 .ent asm_refillin_and_handle_exception
480 asm_refillin_and_handle_exception:
482 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
484 sra t0,48,t0 /* isolate offset */
485 addq t0,ra,pv /* compute update address */
486 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
487 srl t0,16,t0 /* isolate instruction code */
488 lda t0,-0x177b(t0) /* test for LDAH */
489 bne t0, asm_refillin_and_handle_exception_cont
490 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
491 sll t0,16,t0 /* compute high offset */
492 addl t0,0,t0 /* sign extend high offset */
493 addq t0,pv,pv /* compute update address */
495 asm_refillin_and_handle_exception_cont:
498 lda sp,-6*8(sp) /* prepare stackframe*/
499 stq pv,5*8(sp) /* store pv of caller */
500 stq xptr,4*8(sp) /*exception ptr*/
501 stq xpc,3*8(sp) /*address of failure*/
502 stq t0,2*8(sp) /*begin of java stack frame*/
503 stq pv,1*8(sp) /* store pv of caller */
504 stq zero,0*8(sp) /*builtin (invisible) function */
505 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
508 ldq a2,utf_fillInStackTrace_desc
509 ldq a1,utf_fillInStackTrace_name
511 ldq t1,offobjvftbl(t0)
513 jsr ra,class_resolvemethod
515 /* now we have the method */
520 jsr ra,asm_calljavafunction
524 jsr ra,asm_remove_native_stackinfo
533 br asm_handle_exception
535 .end asm_refillin_and_handle_exception
537 /****** function asm_throw_and_handle_arrayindexoutofbounds_exception **********
539 * This function handles an exception. It does not use the usual calling *
540 * conventions. The integer parameter is passed in REG_ITMP1 and the *
541 * pc from the exception raising position is passed in REG_ITMP2. *
543 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
545 *******************************************************************************/
547 .ent asm_throw_and_handle_arrayindexoutofbounds_exception
549 asm_throw_and_handle_arrayindexoutofbounds_exception:
552 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
554 sra t0,48,t0 /* isolate offset */
555 addq t0,ra,pv /* compute update address */
556 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
557 srl t0,16,t0 /* isolate instruction code */
558 lda t0,-0x177b(t0) /* test for LDAH */
559 bne t0,asm_throw_and_handle_arrayindexoutofbounds_exception_cont
560 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
561 sll t0,16,t0 /* compute high offset */
562 addl t0,0,t0 /* sign extend high offset */
563 addq t0,pv,pv /* compute update address */
565 asm_throw_and_handle_arrayindexoutofbounds_exception_cont:
567 lda sp,-6*8(sp) /*prepare stackframe*/
568 stq pv,5*8(sp) /*pv of failure*/
569 stq itmp1,4*8(sp) /*int parameter of the exception*/
570 stq xpc,3*8(sp) /*address of failure */
571 stq t0,2*8(sp) /*store begin of java stack frame*/
572 stq pv,1*8(sp) /*store pv of caller in structure*/
573 stq zero,0*8(sp) /*builtin (invisible function)*/
575 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
578 ldq a0,6*8(sp) /*int of exception*/
579 jsr ra,new_arrayindexoutofboundsexception
582 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
584 jsr ra,asm_remove_native_stackinfo
590 br asm_handle_exception
592 .end asm_throw_and_handle_arrayindexoutofbounds_exception
595 /* asm_throw_and_handle_arithmetic_exception ***********************************
599 *******************************************************************************/
601 .ent asm_throw_and_handle_arithmetic_exception
603 asm_throw_and_handle_arithmetic_exception:
604 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
606 sra t0,48,t0 /* isolate offset */
607 addq t0,ra,pv /* compute update address */
608 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
609 srl t0,16,t0 /* isolate instruction code */
610 lda t0,-0x177b(t0) /* test for LDAH */
611 bne t0,asm_throw_and_handle_arithmetic_exception_cont
612 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
613 sll t0,16,t0 /* compute high offset */
614 addl t0,0,t0 /* sign extend high offset */
615 addq t0,pv,pv /* compute update address */
617 asm_throw_and_handle_arithmetic_exception_cont:
619 lda sp,-6*8(sp) /*prepare stackframe*/
620 stq pv,5*8(sp) /*pv of failure*/
621 stq itmp1,4*8(sp) /*exception string of the exception*/
622 stq xpc,3*8(sp) /*address of failure */
623 stq t0,2*8(sp) /*store begin of java stack frame*/
624 stq pv,1*8(sp) /*store pv of caller in structure*/
625 stq zero,0*8(sp) /*builtin (invisible function)*/
626 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
629 jsr ra,new_arithmeticexception
631 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
633 jsr ra,asm_remove_native_stackinfo
639 br asm_handle_exception
641 .end asm_throw_and_handle_arithmetic_exception
644 /**************** function asm_throw_and_handle_exception **********************
646 * This function handles an exception. It does not use the usual calling *
647 * conventions. The exception class name is passed in REG_ITMP1 and the *
648 * pc from the exception raising position is passed in REG_ITMP2. *
650 * void asm_handle_exception (exceptionclass, exceptionpc); *
652 *******************************************************************************/
653 .ent asm_throw_and_handle_nat_exception
654 asm_throw_and_handle_nat_exception:
656 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
658 sra t0,48,t0 /* isolate offset */
659 addq t0,ra,pv /* compute update address */
660 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
661 srl t0,16,t0 /* isolate instruction code */
662 lda t0,-0x177b(t0) /* test for LDAH */
663 bne t0,asm_throw_and_handle_exception
664 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
665 sll t0,16,t0 /* compute high offset */
666 addl t0,0,t0 /* sign extend high offset */
667 addq t0,pv,pv /* compute update address */
669 .aent asm_throw_and_handle_exception
670 asm_throw_and_handle_exception:
672 lda sp,-6*8(sp) /*prepare stackframe*/
673 stq pv,5*8(sp) /*pv of failure*/
674 stq itmp1,4*8(sp) /*classname of the exception*/
675 stq xpc,3*8(sp) /*address of failure */
676 stq t0,2*8(sp) /*store begin of java stack frame*/
677 stq pv,1*8(sp) /*store pv of caller in structure*/
678 stq zero,0*8(sp) /*builtin (invisible function)*/
679 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
682 ldq a0,6*8(sp) /*classname of exception*/
686 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
688 jsr ra,asm_remove_native_stackinfo
694 br asm_handle_exception
695 .end asm_throw_and_handle_nat_exception
698 /********************* function asm_handle_exception ***************************
700 * This function handles an exception. It does not use the usual calling *
701 * conventions. The exception pointer is passed in REG_ITMP1 and the *
702 * pc from the exception raising position is passed in REG_ITMP2. It searches *
703 * the local exception table for a handler. If no one is found, it unwinds *
704 * stacks and continues searching the callers. *
706 * void asm_handle_exception (exceptionptr, exceptionpc); *
708 *******************************************************************************/
710 .ent asm_handle_nat_exception
711 asm_handle_nat_exception:
712 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
714 sra t0,48,t0 /* isolate offset */
715 addq t0,ra,pv /* compute update address */
716 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
717 srl t0,16,t0 /* isolate instruction code */
718 lda t0,-0x177b(t0) /* test for LDAH */
719 bne t0,asm_handle_exception
720 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
721 sll t0,16,t0 /* compute high offset */
722 addl t0,0,t0 /* sign extend high offset */
723 addq t0,pv,pv /* compute update address */
725 .aent asm_handle_exception
726 asm_handle_exception:
727 lda sp,-18*8(sp) /* allocate stack */
728 stq t0,0*8(sp) /* save possible used registers */
729 stq t1,1*8(sp) /* also registers used by trace_exception */
747 lda t3,1(zero) /* set no unwind flag */
749 lda sp,-5*8(sp) /* allocate stack */
750 stq xptr,0*8(sp) /* save used register */
757 ldq a1,MethodPointer(pv)
762 br ra,ex_trace /* set ra for gp loading */
764 ldgp gp,0(ra) /* load gp */
765 jsr ra,builtin_trace_exception /* trace_exception(xptr,methodptr) */
767 ldq xptr,0*8(sp) /* restore used register */
772 lda sp,5*8(sp) /* deallocate stack */
774 ldl t0,ExTableSize(pv) /* t0 = exception table size */
775 beq t0,empty_table /* if empty table skip */
777 lda t1,ExTableStart(pv) /* t1 = start of exception table */
780 ldq t2,ExStartPC(t1) /* t2 = exception start pc */
781 cmple t2,xpc,t2 /* t2 = (startpc <= xpc) */
782 beq t2,ex_table_cont /* if (false) continue */
783 ldq t2,ExEndPC(t1) /* t2 = exception end pc */
784 cmplt xpc,t2,t2 /* t2 = (xpc < endpc) */
785 beq t2,ex_table_cont /* if (false) continue */
786 ldq a1,ExCatchType(t1) /* arg1 = exception catch type */
787 beq a1,ex_handle_it /* NULL catches everything */
789 ldl itmp3,offclassloaded(a1)
790 bne itmp3,L_class_loaded
792 subq sp,8*8,sp /* allocate stack */
793 stq t0,0*8(sp) /* save used register */
804 br ra,L_class_load_ra /* set ra for gp loading */
806 ldgp gp,0(ra) /* load gp */
807 jsr ra,class_load /* class_load(exceptionclass) */
809 ldq t0,0*8(sp) /* restore used register */
817 addq sp,8*8,sp /* deallocate stack */
820 ldl itmp3,offclasslinked(a1)
821 subq sp,8*8,sp /* allocate stack */
823 bne itmp3,L_class_linked
825 stq t0,0*8(sp) /* save used register */
835 br ra,L_class_link_ra /* set ra for gp loading */
837 ldgp gp,0(ra) /* load gp */
838 jsr ra,class_link /* class_load(exceptionclass) */
840 ldq t0,0*8(sp) /* restore used register */
852 ldq a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
853 ldq a1,offclassvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
854 ldl a0,offbaseval(a0) /* a0 = baseval(xptr) */
855 ldl v0,offbaseval(a1) /* a2 = baseval(catchtype) */
856 ldl a1,offdiffval(a1) /* a1 = diffval(catchtype) */
858 subl a0,v0,a0 /* a0 = baseval(xptr) - baseval(catchtype) */
859 cmpule a0,a1,v0 /* v0 = xptr is instanceof catchtype */
860 addq sp,8*8,sp /* deallocate stack */
861 beq v0,ex_table_cont /* if (false) continue */
864 ldq xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
866 beq t3,ex_jump /* if (!(no stack unwinding) skip */
868 ldq t0,0*8(sp) /* restore possible used registers */
869 ldq t1,1*8(sp) /* also registers used by trace_exception */
886 lda sp,18*8(sp) /* deallocate stack */
889 jmp zero,(xpc) /* jump to the handler */
892 lda t1,ExEntrySize(t1) /* next exception table entry */
893 subl t0,1,t0 /* decrement entry counter */
894 bgt t0,ex_table_loop /* if (t0 > 0) next entry */
897 beq t3,ex_already_cleared /* if here the first time, then */
898 lda sp,18*8(sp) /* deallocate stack and */
899 clr t3 /* clear the no unwind flag */
901 ldl t0,IsSync(pv) /* t0 = SyncOffset */
902 beq t0,no_monitor_exit /* if zero no monitorexit */
903 addq sp,t0,t0 /* add stackptr to Offset */
904 ldq a0,-8(t0) /* load monitorexit pointer */
906 lda sp,-7*8(sp) /* allocate stack */
907 stq t0,0*8(sp) /* save used register */
915 br ra,ex_mon_load /* set ra for gp loading */
917 ldgp gp,0(ra) /* load gp */
918 jsr ra,builtin_monitorexit/* builtin_monitorexit(objectptr) */
920 ldq t0,0*8(sp) /* restore used register */
927 lda sp,7*8(sp) /* deallocate stack */
930 ldl t0,FrameSize(pv) /* t0 = frame size */
931 addq sp,t0,sp /* unwind stack */
932 mov sp,t0 /* t0 = pointer to save area */
933 ldl t1,IsLeaf(pv) /* t1 = is leaf procedure */
934 bne t1,ex_no_restore /* if (leaf) skip */
935 ldq ra,-8(t0) /* restore ra */
936 lda t0,-8(t0) /* t0-- */
938 mov ra,xpc /* the new xpc is ra */
939 ldl t1,IntSave(pv) /* t1 = saved int register count */
940 br t2,ex_int1 /* t2 = current pc */
942 lda t2,44(t2) /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
943 negl t1,t1 /* negate register count */
944 s4addq t1,t2,t2 /* t2 = ex_int_sav - 4 * register count */
945 jmp zero,(t2) /* jump to save position */
954 s8addq t1,t0,t0 /* t0 = t0 - 8 * register count */
956 ldl t1,FltSave(pv) /* t1 = saved flt register count */
957 br t2,ex_flt1 /* t2 = current pc */
959 lda t2,48(t2) /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
960 negl t1,t1 /* negate register count */
961 s4addq t1,t2,t2 /* t2 = ex_flt_sav - 4 * register count */
962 jmp zero,(t2) /* jump to save position */
972 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
974 sra t0,48,t0 /* isolate offset */
975 addq t0,ra,pv /* compute update address */
976 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
977 srl t0,16,t0 /* isolate instruction code */
978 lda t0,-0x177b(t0) /* test for LDAH */
980 ldl t0,4(ra) /* load instruction LDAH PV,xxx(RA) */
981 sll t0,16,t0 /* compute high offset */
982 addl t0,0,t0 /* sign extend high offset */
983 addq t0,pv,pv /* compute update address */
986 .end asm_handle_nat_exception
989 /* asm_check_clinit ************************************************************
995 itmp1: pointer to class
999 0 mcode ; machine code to patch back in
1001 *******************************************************************************/
1003 .ent asm_check_clinit
1006 ldgp gp,0(itmp2) /* function is called via `jsr ra,itmp1' */
1010 stq ra,0*8(sp) /* save return address */
1011 stq pv,1*8(sp) /* save pv of calling java function */
1012 stq a0,2*8(sp) /* save argument registers for leaf */
1013 stq a1,3*8(sp) /* functions and native stub */
1019 ldl itmp2,offclassinit(itmp1)
1020 bne itmp2,L_is_initialized
1022 mov itmp1,a0 /* move class pointer to a0 */
1026 beq v0,L_initializererror
1029 ldq ra,0*8(sp) /* get return address */
1030 subq ra,1*4,ra /* go back 1 instruction */
1031 ldl itmp1,8*8(sp) /* load machine code from stack */
1032 stl itmp1,0(ra) /* store the machine code */
1034 call_pal PAL_imb /* synchronise instruction cache */
1036 ldq ra,0*8(sp) /* restore return address */
1037 ldq pv,1*8(sp) /* restore pv of calling java function */
1038 ldq a0,2*8(sp) /* restore argument registers */
1045 addq sp,(8+1)*8,sp /* remove stack frame (+1 for machine code) */
1047 subq ra,1*4,ra /* go back 1 instruction */
1048 jmp zero,(ra) /* jump to the new code */
1051 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1052 jsr ra,builtin_asm_get_exceptionptrptr
1054 lda v0,_exceptionptr
1056 ldq xptr,0(v0) /* get the exception pointer */
1057 stq zero,0(v0) /* clear the exception pointer */
1059 ldq ra,0*8(sp) /* restore return address */
1060 ldq pv,1*8(sp) /* restore pv of calling java function */
1061 ldq a0,2*8(sp) /* restore argument registers */
1068 addq sp,(8+1)*8,sp /* remove stack frame (+1 for machine code) */
1071 br asm_handle_exception /* we have the pv of the calling java func. */
1073 .end asm_check_clinit
1076 /********************* function asm_builtin_monitorenter ***********************
1078 * Does null check and calls monitorenter or throws an exception *
1080 *******************************************************************************/
1082 .ent asm_builtin_monitorenter
1084 asm_builtin_monitorenter:
1086 lda pv,builtin_monitorenter
1087 beq a0,nb_monitorenter /* if (null) throw exception */
1088 jmp zero,(pv) /* else call builtin_monitorenter */
1092 ldq xptr,string_java_lang_NullPointerException
1093 jmp zero,asm_throw_and_handle_nat_exception
1097 jsr ra,new_nullpointerexception
1103 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1104 br asm_handle_nat_exception
1106 .end asm_builtin_monitorenter
1109 /********************* function asm_builtin_monitorexit ************************
1111 * Does null check and calls monitorexit or throws an exception *
1113 *******************************************************************************/
1115 .ent asm_builtin_monitorexit
1117 asm_builtin_monitorexit:
1119 lda pv,builtin_monitorexit
1120 beq a0,nb_monitorexit /* if (null) throw exception */
1121 jmp zero,(pv) /* else call builtin_monitorexit */
1125 ldq xptr,string_java_lang_NullPointerException
1126 jmp zero,asm_throw_and_handle_nat_exception
1130 jsr ra,new_nullpointerexception
1136 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1137 br asm_handle_nat_exception
1139 .end asm_builtin_monitorexit
1142 /************************ function asm_builtin_idiv ****************************
1144 * Does null check and calls idiv or throws an exception *
1146 *******************************************************************************/
1148 .ent asm_builtin_idiv
1153 beq a1,nb_idiv /* if (null) throw exception */
1154 jmp zero,(pv) /* else call builtin_idiv */
1157 ldq xptr,string_java_lang_ArithmeticException_message
1158 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1159 br asm_throw_and_handle_arithmetic_exception
1161 .end asm_builtin_idiv
1164 /************************ function asm_builtin_ldiv ****************************
1166 * Does null check and calls ldiv or throws an exception *
1168 *******************************************************************************/
1170 .ent asm_builtin_ldiv
1175 beq a1,nb_ldiv /* if (null) throw exception */
1176 jmp zero,(pv) /* else call builtin_ldiv */
1179 ldq xptr,string_java_lang_ArithmeticException_message
1180 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1181 br asm_throw_and_handle_arithmetic_exception
1183 .end asm_builtin_ldiv
1186 /************************ function asm_builtin_irem ****************************
1188 * Does null check and calls irem or throws an exception *
1190 *******************************************************************************/
1192 .ent asm_builtin_irem
1197 beq a1,nb_irem /* if (null) throw exception */
1198 jmp zero,(pv) /* else call builtin_irem */
1201 ldq xptr,string_java_lang_ArithmeticException_message
1202 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1203 br asm_throw_and_handle_arithmetic_exception
1205 .end asm_builtin_irem
1208 /************************ function asm_builtin_lrem ****************************
1210 * Does null check and calls lrem or throws an exception *
1212 *******************************************************************************/
1214 .ent asm_builtin_lrem
1219 beq a1,nb_lrem /* if (null) throw exception */
1220 jmp zero,(pv) /* else call builtin_lrem */
1223 ldq xptr,string_java_lang_ArithmeticException_message
1224 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1225 br asm_throw_and_handle_arithmetic_exception
1227 .end asm_builtin_lrem
1230 /******************* function asm_builtin_checkarraycast ***********************
1232 * Does the cast check and eventually throws an exception *
1234 *******************************************************************************/
1236 .ent asm_builtin_checkarraycast
1238 asm_builtin_checkarraycast:
1240 lda sp,-16(sp) /* allocate stack space */
1241 stq ra,0(sp) /* save return address */
1242 stq a0,8(sp) /* save object pointer */
1243 jsr ra,builtin_checkarraycast /* builtin_checkarraycast */
1245 beq v0,nb_carray_throw /* if (false) throw exception */
1246 ldq ra,0(sp) /* restore return address */
1247 ldq v0,8(sp) /* return object pointer */
1248 lda sp,16(sp) /* free stack space */
1255 ldq xptr,string_java_lang_ClassCastException
1256 jmp zero,asm_throw_and_handle_nat_exception
1258 ldq a0,string_java_lang_ClassCastException
1259 jsr ra,new_exception
1263 ldq ra,0(sp) /* restore return address */
1264 lda sp,16(sp) /* free stack space */
1265 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1266 br asm_handle_nat_exception
1269 .end asm_builtin_checkarraycast
1272 /******************* function asm_builtin_aastore ******************************
1274 * Does the cast check and eventually throws an exception *
1276 *******************************************************************************/
1278 .ent asm_builtin_aastore
1280 asm_builtin_aastore:
1282 beq a0,nb_aastore_null /* if null pointer throw exception */
1283 ldl t0,offarraysize(a0) /* load size */
1284 lda sp,-24(sp) /* allocate stack space */
1285 stq ra,0(sp) /* save return address */
1286 s8addq a1,a0,t1 /* add index*8 to arrayref */
1287 cmpult a1,t0,t0 /* do bound check */
1288 beq t0,nb_aastore_bound /* if out of bounds throw exception */
1289 mov a2,a1 /* object is second argument */
1290 stq t1,8(sp) /* save store position */
1291 stq a1,16(sp) /* save object */
1292 jsr ra,builtin_canstore /* builtin_canstore(arrayref,object) */
1294 ldq ra,0(sp) /* restore return address */
1295 ldq a0,8(sp) /* restore store position */
1296 ldq a1,16(sp) /* restore object */
1297 lda sp,24(sp) /* free stack space */
1298 beq v0,nb_aastore_throw /* if (false) throw exception */
1299 stq a1,offobjarrdata(a0) /* store objectptr in array */
1303 ldq xptr,string_java_lang_NullPointerException
1305 jmp zero,asm_throw_and_handle_nat_exception
1307 subq sp,8,sp /* allocate stack space */
1308 stq ra,0(sp) /* save return address */
1309 jsr ra,new_nullpointerexception
1315 mov ra,xpc /* faulting address is return adress */
1316 br asm_handle_nat_exception
1323 jmp zero,asm_throw_and_handle_arrayindexoutofbounds_exception
1325 ldq a0,string_java_lang_ArrayIndexOutOfBoundsException
1326 jsr ra,new_exception_int /* a1 already contains the index */
1330 ldq ra,0(sp) /* restore return address */
1331 lda sp,24(sp) /* free stack space */
1332 mov ra,xpc /* faulting address is return adress */
1333 br asm_handle_nat_exception
1337 ldq xptr,string_java_lang_ArrayStoreException
1338 jmp zero,asm_throw_and_handle_nat_exception
1340 subq sp,8,sp /* allocate stack space */
1341 stq ra,0(sp) /* save return address */
1342 jsr ra,new_arraystoreexception
1348 mov ra,xpc /* faulting address is return adress */
1349 br asm_handle_nat_exception
1351 .end asm_builtin_aastore
1354 /******************* function asm_initialize_thread_stack **********************
1356 * initialized a thread stack *
1358 *******************************************************************************/
1360 .ent asm_initialize_thread_stack
1362 asm_initialize_thread_stack:
1383 .end asm_initialize_thread_stack
1386 /******************* function asm_perform_threadswitch *************************
1388 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1390 * performs a threadswitch *
1392 *******************************************************************************/
1394 .ent asm_perform_threadswitch
1396 asm_perform_threadswitch:
1437 .end asm_perform_threadswitch
1440 /********************* function asm_switchstackandcall *************************
1442 * void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1445 * Switches to a new stack, calls a function and switches back. *
1446 * a0 new stack pointer *
1447 * a1 function pointer *
1448 * a2 pointer to variable where stack top should be stored *
1449 * a3 pointer to user data, is passed to the function *
1451 *******************************************************************************/
1454 .ent asm_switchstackandcall
1456 asm_switchstackandcall:
1457 lda a0,-2*8(a0) /* allocate new stack */
1458 stq ra,0(a0) /* save return address on new stack */
1459 stq sp,1*8(a0) /* save old stack pointer on new stack */
1460 stq sp,0(a2) /* save old stack pointer to variable */
1461 mov a0,sp /* switch to new stack */
1463 mov a1,pv /* load function pointer */
1464 mov a3,a0 /* pass pointer */
1465 jmp ra,(pv) /* and call function */
1467 ldq ra,0(sp) /* load return address */
1468 ldq sp,1*8(sp) /* switch to old stack */
1470 jmp zero,(ra) /* return */
1472 .end asm_switchstackandcall
1474 .ent asm_getclassvalues_atomic
1476 asm_getclassvalues_atomic:
1479 ldl t0,offbaseval(a0)
1480 ldl t1,offdiffval(a0)
1481 ldl t2,offbaseval(a1)
1483 stl t0,offcast_super_baseval(a2)
1484 stl t1,offcast_super_diffval(a2)
1485 stl t2,offcast_sub_baseval(a2)
1488 .end asm_getclassvalues_atomic
1492 asm_criticalsections:
1493 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1496 .quad _crit_restart1
1499 .quad _crit_restart2
1504 .ent asm_prepare_native_stackinfo
1505 asm_prepare_native_stackinfo:
1508 jsr ra,builtin_asm_get_stackframeinfo
1516 .end asm_prepare_native_stackinfo
1518 .end asm_remove_native_stackinfo
1519 asm_remove_native_stackinfo:
1525 .end asm_prepare_native_stackinfo
1528 * These are local overrides for various environment variables in Emacs.
1529 * Please do not remove this and leave it at the end of the file, where
1530 * Emacs will automagically detect them.
1531 * ---------------------------------------------------------------------
1534 * indent-tabs-mode: t