1 /* vm/jit/alpha/asmpart.S - Java-C interface functions for alpha
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
32 $Id: asmpart.S 2142 2005-03-30 12:53:56Z twisti $
38 #include "vm/jit/alpha/offsets.h"
39 #include "vm/jit/alpha/asmoffsets.h"
107 /********************* exported functions and variables ***********************/
109 .globl has_no_x_instr_set
111 .globl asm_calljavafunction
113 .globl asm_calljavafunction2
114 .globl asm_calljavafunction2int
115 .globl asm_calljavafunction2long
116 .globl asm_calljavafunction2float
117 .globl asm_calljavafunction2double
119 .globl asm_call_jit_compiler
120 .globl asm_throw_and_handle_exception
121 .globl asm_throw_and_handle_nat_exception
122 .globl asm_throw_and_handle_arithmetic_exception
123 .globl asm_throw_and_handle_arrayindexoutofbounds_exception
124 .globl asm_handle_exception
125 .globl asm_handle_nat_exception
126 .globl asm_check_clinit
127 .globl asm_builtin_checkarraycast
128 .globl asm_builtin_aastore
130 #if defined(USE_THREADS)
131 .globl asm_builtin_monitorenter
132 .globl asm_builtin_monitorexit
135 .globl asm_builtin_idiv
136 .globl asm_builtin_irem
137 .globl asm_builtin_ldiv
138 .globl asm_builtin_lrem
139 .globl asm_perform_threadswitch
140 .globl asm_initialize_thread_stack
141 .globl asm_switchstackandcall
142 .globl asm_criticalsections
143 .globl asm_getclassvalues_atomic
144 .globl asm_prepare_native_stackinfo
145 .globl asm_remove_native_stackinfo
146 .globl asm_refillin_and_handle_exception
149 /*********************** function has_no_x_instr_set ***************************
151 * determines if the byte support instruction set (21164a and higher) *
154 *******************************************************************************/
156 .ent has_no_x_instr_set
159 .long 0x47e03c20 /* amask 1,v0 */
160 jmp zero,(ra) /* return */
162 .end has_no_x_instr_set
165 /********************* function asm_calljavafunction ***************************
167 * This function calls a Java-method (which possibly needs compilation) *
168 * with up to 4 address parameters. *
170 * This functions calls the JIT-compiler which eventually translates the *
171 * method into machine code. *
174 * javaobject_header *asm_calljavafunction (methodinfo *m, *
175 * void *arg1, void *arg2, void *arg3, void *arg4); *
177 *******************************************************************************/
179 .ent asm_calljavafunction
182 .ascii "calljavafunction\0\0"
185 .quad 0 /* catch type all */
186 .quad calljava_xhandler /* handler pc */
187 .quad calljava_xhandler /* end pc */
188 .quad asm_calljavafunction /* start pc */
189 .long 1 /* extable size */
190 .long 0 /* PADDING */
191 .quad 0 /* line number table start */
192 .quad 0 /* line number table size */
193 .long 0 /* PADDING */
194 .long 0 /* fltsave */
195 .long 0 /* intsave */
198 .long 32 /* frame size */
199 .quad 0 /* method pointer (pointer to name) */
201 asm_calljavafunction:
203 lda sp,-32(sp) /* allocate stack space */
204 stq gp,24(sp) /* save global pointer */
205 stq ra,0(sp) /* save return address */
207 stq a0,16(sp) /* save method pointer for compiler */
208 lda v0,16(sp) /* pass pointer to method pointer via v0*/
210 mov a1,a0 /* pass the remaining parameters */
215 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
216 stq $28,8(sp) /* store function address */
217 mov sp,$28 /* set method pointer */
219 ldq pv,8($28) /* method call as in Java */
220 jmp ra,(pv) /* call JIT compiler */
222 lda pv,-64(ra) /* asm_calljavafunction-calljava_jit !!!!!*/
225 ldq ra,0(sp) /* restore return address */
226 ldq gp,24(sp) /* restore global pointer */
227 lda sp,32(sp) /* free stack space */
233 ldq gp,24(sp) /* restore global pointer */
235 jsr ra,builtin_throw_exception
236 ldq ra,0(sp) /* restore return address */
237 lda sp,32(sp) /* free stack space */
239 .end asm_calljavafunction
244 .ent asm_calljavafunction2
249 .quad 0 /* catch type all */
250 .quad calljava_xhandler2 /* handler pc */
251 .quad calljava_xhandler2 /* end pc */
252 .quad asm_calljavafunction2 /* start pc */
253 .long 1 /* extable size */
254 .long 0 /* PADDING */
255 .quad 0 /* line number table start */
256 .quad 0 /* line number table size */
257 .long 0 /* PADDING */
258 .long 0 /* fltsave */
259 .long 1 /* intsave */
262 .long 40 /* frame size */
263 .quad 0 /* method pointer (pointer to name) */
265 asm_calljavafunction2:
266 asm_calljavafunction2int:
267 asm_calljavafunction2long:
268 asm_calljavafunction2float:
269 asm_calljavafunction2double:
271 lda sp,-40(sp) /* allocate stack space */
272 stq ra,0(sp) /* save return address */
274 stq gp,8(sp) /* save global pointer */
276 stq a0,32(sp) /* save method pointer for compiler */
277 mov a3,t0 /* pointer to arg block */
278 mov a1,s6 /* arg count */
280 ble s6,calljava_argsloaded
282 ldq a0,offjniitem(t0)
283 ldt $f16,offjniitem(t0)
284 ble s6,calljava_argsloaded
286 ldq a1,offjniitem+sizejniblock*1(t0)
287 ldt $f17,offjniitem+sizejniblock*1(t0)
288 ble s6,calljava_argsloaded
290 ldq a2,offjniitem+sizejniblock*2(t0)
291 ldt $f18,offjniitem+sizejniblock*2(t0)
292 ble s6,calljava_argsloaded
294 ldq a3,offjniitem+sizejniblock*3(t0)
295 ldt $f19,offjniitem+sizejniblock*3(t0)
296 ble s6,calljava_argsloaded
298 ldq a4,offjniitem+sizejniblock*4(t0)
299 ldt $f20,offjniitem+sizejniblock*4(t0)
300 ble s6,calljava_argsloaded
302 ldq a5,offjniitem+sizejniblock*5(t0)
303 ldt $f21,offjniitem+sizejniblock*5(t0)
306 ble s6,calljava_nocopy
312 ldq t3,offjniitem+sizejniblock*6(t0)
315 lda t0,sizejniblock(t0)
317 bne t1,calljava_copyloop
320 lda v0,32(t4) /* pass pointer to method pointer via v0*/
322 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
323 stq $28,16(t4) /* store function address */
324 lda $28,8(t4) /* set method pointer */
326 ldq pv,8($28) /* method call as in Java */
327 jmp ra,(pv) /* call JIT compiler */
329 lda pv,-200(ra) /* asm_calljavafunction-calljava_jit !!!*/
333 ldq ra,0(sp) /* restore return address */
334 ldq gp,8(sp) /* restore global pointer */
336 lda sp,40(sp) /* free stack space */
343 ldq gp,8(sp) /* restore global pointer */
345 jsr ra,builtin_throw_exception
346 ldq ra,0(sp) /* restore return address */
348 lda sp,40(sp) /* free stack space */
350 .end asm_calljavafunction2
353 /****************** function asm_call_jit_compiler *****************************
355 * invokes the compiler for untranslated JavaVM methods. *
357 * Register R0 contains a pointer to the method info structure (prepared *
358 * by createcompilerstub). Using the return address in R26 and the *
359 * offset in the LDA instruction or using the value in methodptr R28 the *
360 * patching address for storing the method address can be computed: *
362 * method address was either loaded using *
363 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
364 * M_LDA (REG_PV, REG_RA, low) *
365 * M_LDAH(REG_PV, REG_RA, high) ; optional *
367 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
368 * in the static case the method pointer can be computed using the *
369 * return address and the lda function following the jmp instruction *
371 *******************************************************************************/
373 .ent asm_call_jit_compiler
375 asm_call_jit_compiler:
377 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
378 srl t8,16,t8 /* shift right register number $yy */
379 and t8,31,t8 /* isolate register number */
380 subl t8,28,t8 /* test for REG_METHODPTR */
382 ldl t8,0(ra) /* load instruction LDA PV,xxx(RA) */
384 sra t8,48,t8 /* isolate offset */
385 addq t8,ra,$28 /* compute update address */
386 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
387 srl t8,16,t8 /* isolate instruction code */
388 lda t8,-0x177b(t8) /* test for LDAH */
390 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
391 sll t8,16,t8 /* compute high offset */
392 addl t8,0,t8 /* sign extend high offset */
393 addq t8,$28,$28 /* compute update address */
395 lda sp,-14*8(sp) /* reserve stack space */
396 stq a0,0*8(sp) /* save all argument registers */
397 stq a1,1*8(sp) /* they could be used by method */
408 stq $28,12*8(sp) /* save method pointer */
409 stq ra,13*8(sp) /* save return address */
411 ldq a0,0(v0) /* pass 'methodinfo' pointer to */
412 jsr ra,jit_compile /* jit compiler */
415 ldq a0,0*8(sp) /* load argument registers */
427 ldq $28,12*8(sp) /* load method pointer */
428 ldq ra,13*8(sp) /* load return address */
429 lda sp,14*8(sp) /* deallocate stack area */
431 beq v0,asm_call_jit_compiler_exception
433 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
435 sra t8,48,t8 /* isolate offset */
437 addq t8,$28,t8 /* compute update address via method pointer*/
438 stq v0,0(t8) /* save new method address there */
440 call_pal PAL_imb /* synchronise instruction cache */
442 mov v0,pv /* load method address into pv */
443 jmp zero,(pv) /* and call method. The method returns */
444 /* directly to the caller (ra). */
446 asm_call_jit_compiler_exception:
447 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
450 jsr ra,builtin_asm_get_exceptionptrptr
456 ldq xptr,0(v0) /* get the exception pointer */
457 stq zero,0(v0) /* clear the exception pointer */
460 br asm_handle_nat_exception
462 .end asm_call_jit_compiler
465 /**************** function asm_refillin_and_handle_exception *******************
467 * This function handles an exception. It does not use the usual calling *
468 * conventions. The exception is passed in REG_ITMP1 and the *
469 * pc from the exception raising position is passed in REG_ITMP2. *
470 * a0 contains the PV of the function causing the problem *
472 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
474 *******************************************************************************/
475 .ent asm_refillin_and_handle_exception
476 asm_refillin_and_handle_exception:
478 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
480 sra t0,48,t0 /* isolate offset */
481 addq t0,ra,pv /* compute update address */
482 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
483 srl t0,16,t0 /* isolate instruction code */
484 lda t0,-0x177b(t0) /* test for LDAH */
485 bne t0, asm_refillin_and_handle_exception_cont
486 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
487 sll t0,16,t0 /* compute high offset */
488 addl t0,0,t0 /* sign extend high offset */
489 addq t0,pv,pv /* compute update address */
491 asm_refillin_and_handle_exception_cont:
494 lda sp,-6*8(sp) /* prepare stackframe*/
495 stq pv,5*8(sp) /* store pv of caller */
496 stq xptr,4*8(sp) /*exception ptr*/
497 stq xpc,3*8(sp) /*address of failure*/
498 stq t0,2*8(sp) /*begin of java stack frame*/
499 stq pv,1*8(sp) /* store pv of caller */
500 stq zero,0*8(sp) /*builtin (invisible) function */
501 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
504 ldq a2,utf_void__java_lang_Throwable
505 ldq a1,utf_fillInStackTrace
507 ldq t1,offobjvftbl(t0)
509 jsr ra,class_resolvemethod
511 /* now we have the method */
516 jsr ra,asm_calljavafunction
520 jsr ra,asm_remove_native_stackinfo
529 br asm_handle_exception
531 .end asm_refillin_and_handle_exception
533 /****** function asm_throw_and_handle_arrayindexoutofbounds_exception **********
535 * This function handles an exception. It does not use the usual calling *
536 * conventions. The integer parameter is passed in REG_ITMP1 and the *
537 * pc from the exception raising position is passed in REG_ITMP2. *
539 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
541 *******************************************************************************/
543 .ent asm_throw_and_handle_arrayindexoutofbounds_exception
545 asm_throw_and_handle_arrayindexoutofbounds_exception:
548 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
550 sra t0,48,t0 /* isolate offset */
551 addq t0,ra,pv /* compute update address */
552 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
553 srl t0,16,t0 /* isolate instruction code */
554 lda t0,-0x177b(t0) /* test for LDAH */
555 bne t0,asm_throw_and_handle_arrayindexoutofbounds_exception_cont
556 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
557 sll t0,16,t0 /* compute high offset */
558 addl t0,0,t0 /* sign extend high offset */
559 addq t0,pv,pv /* compute update address */
561 asm_throw_and_handle_arrayindexoutofbounds_exception_cont:
563 lda sp,-6*8(sp) /*prepare stackframe*/
564 stq pv,5*8(sp) /*pv of failure*/
565 stq itmp1,4*8(sp) /*int parameter of the exception*/
566 stq xpc,3*8(sp) /*address of failure */
567 stq t0,2*8(sp) /*store begin of java stack frame*/
568 stq pv,1*8(sp) /*store pv of caller in structure*/
569 stq zero,0*8(sp) /*builtin (invisible function)*/
571 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
574 ldq a0,6*8(sp) /*int of exception*/
575 jsr ra,new_arrayindexoutofboundsexception
578 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
580 jsr ra,asm_remove_native_stackinfo
586 br asm_handle_exception
588 .end asm_throw_and_handle_arrayindexoutofbounds_exception
591 /* asm_throw_and_handle_arithmetic_exception ***********************************
595 *******************************************************************************/
597 .ent asm_throw_and_handle_arithmetic_exception
599 asm_throw_and_handle_arithmetic_exception:
600 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
602 sra t0,48,t0 /* isolate offset */
603 addq t0,ra,pv /* compute update address */
604 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
605 srl t0,16,t0 /* isolate instruction code */
606 lda t0,-0x177b(t0) /* test for LDAH */
607 bne t0,asm_throw_and_handle_arithmetic_exception_cont
608 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
609 sll t0,16,t0 /* compute high offset */
610 addl t0,0,t0 /* sign extend high offset */
611 addq t0,pv,pv /* compute update address */
613 asm_throw_and_handle_arithmetic_exception_cont:
615 lda sp,-6*8(sp) /*prepare stackframe*/
616 stq pv,5*8(sp) /*pv of failure*/
617 stq itmp1,4*8(sp) /*exception string of the exception*/
618 stq xpc,3*8(sp) /*address of failure */
619 stq t0,2*8(sp) /*store begin of java stack frame*/
620 stq pv,1*8(sp) /*store pv of caller in structure*/
621 stq zero,0*8(sp) /*builtin (invisible function)*/
622 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
625 jsr ra,new_arithmeticexception
627 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
629 jsr ra,asm_remove_native_stackinfo
635 br asm_handle_exception
637 .end asm_throw_and_handle_arithmetic_exception
640 /* asm_throw_and_handle_exception **********************************************
644 *******************************************************************************/
646 .ent asm_throw_and_handle_nat_exception
648 asm_throw_and_handle_nat_exception:
650 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
652 sra t0,48,t0 /* isolate offset */
653 addq t0,ra,pv /* compute update address */
654 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
655 srl t0,16,t0 /* isolate instruction code */
656 lda t0,-0x177b(t0) /* test for LDAH */
657 bne t0,asm_throw_and_handle_exception
658 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
659 sll t0,16,t0 /* compute high offset */
660 addl t0,0,t0 /* sign extend high offset */
661 addq t0,pv,pv /* compute update address */
663 .aent asm_throw_and_handle_exception
665 asm_throw_and_handle_exception:
667 lda sp,-6*8(sp) /* prepare stackframe */
668 stq pv,5*8(sp) /* pv of failure */
669 stq xptr,4*8(sp) /* classname of the exception */
670 stq xpc,3*8(sp) /* address of failure */
671 stq t0,2*8(sp) /* store begin of java stack frame */
672 stq pv,1*8(sp) /* store pv of caller in structure */
673 stq zero,0*8(sp) /* builtin (invisible function) */
674 /* puts 2 additional quadwords on stack */
675 jsr ra,asm_prepare_native_stackinfo
678 ldq a0,6*8(sp) /* classname of exception */
682 mov v0,xptr /* xptr (itmp1) is not touched in */
683 /* asm_remove_native_stackinfo */
685 jsr ra,asm_remove_native_stackinfo
691 br asm_handle_exception
693 .end asm_throw_and_handle_nat_exception
696 /********************* function asm_handle_exception ***************************
698 * This function handles an exception. It does not use the usual calling *
699 * conventions. The exception pointer is passed in REG_ITMP1 and the *
700 * pc from the exception raising position is passed in REG_ITMP2. It searches *
701 * the local exception table for a handler. If no one is found, it unwinds *
702 * stacks and continues searching the callers. *
704 * void asm_handle_exception (exceptionptr, exceptionpc); *
706 *******************************************************************************/
708 .ent asm_handle_nat_exception
710 asm_handle_nat_exception:
711 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
713 sra t0,48,t0 /* isolate offset */
714 addq t0,ra,pv /* compute update address */
715 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
716 srl t0,16,t0 /* isolate instruction code */
717 lda t0,-0x177b(t0) /* test for LDAH */
718 bne t0,asm_handle_exception
719 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
720 sll t0,16,t0 /* compute high offset */
721 addl t0,0,t0 /* sign extend high offset */
722 addq t0,pv,pv /* compute update address */
724 .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 */
904 #if defined(USE_THREADS)
905 addq sp,t0,t0 /* add stackptr to Offset */
906 ldq a0,-8(t0) /* load monitorexit pointer */
908 lda sp,-7*8(sp) /* allocate stack */
909 stq t0,0*8(sp) /* save used register */
917 br ra,ex_mon_load /* set ra for gp loading */
919 ldgp gp,0(ra) /* load gp */
920 jsr ra,builtin_monitorexit/* builtin_monitorexit(objectptr) */
922 ldq t0,0*8(sp) /* restore used register */
929 lda sp,7*8(sp) /* deallocate stack */
933 ldl t0,FrameSize(pv) /* t0 = frame size */
934 addq sp,t0,sp /* unwind stack */
935 mov sp,t0 /* t0 = pointer to save area */
936 ldl t1,IsLeaf(pv) /* t1 = is leaf procedure */
937 bne t1,ex_no_restore /* if (leaf) skip */
938 ldq ra,-8(t0) /* restore ra */
939 lda t0,-8(t0) /* t0-- */
941 mov ra,xpc /* the new xpc is ra */
942 ldl t1,IntSave(pv) /* t1 = saved int register count */
943 br t2,ex_int1 /* t2 = current pc */
945 lda t2,44(t2) /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
946 negl t1,t1 /* negate register count */
947 s4addq t1,t2,t2 /* t2 = ex_int_sav - 4 * register count */
948 jmp zero,(t2) /* jump to save position */
957 s8addq t1,t0,t0 /* t0 = t0 - 8 * register count */
959 ldl t1,FltSave(pv) /* t1 = saved flt register count */
960 br t2,ex_flt1 /* t2 = current pc */
962 lda t2,48(t2) /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
963 negl t1,t1 /* negate register count */
964 s4addq t1,t2,t2 /* t2 = ex_flt_sav - 4 * register count */
965 jmp zero,(t2) /* jump to save position */
975 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
977 sra t0,48,t0 /* isolate offset */
978 addq t0,ra,pv /* compute update address */
979 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
980 srl t0,16,t0 /* isolate instruction code */
981 lda t0,-0x177b(t0) /* test for LDAH */
983 ldl t0,4(ra) /* load instruction LDAH PV,xxx(RA) */
984 sll t0,16,t0 /* compute high offset */
985 addl t0,0,t0 /* sign extend high offset */
986 addq t0,pv,pv /* compute update address */
989 .end asm_handle_nat_exception
992 /* asm_check_clinit ************************************************************
998 itmp1: pointer to class
1002 0 mcode ; machine code to patch back in
1004 *******************************************************************************/
1006 .ent asm_check_clinit
1009 ldgp gp,0(itmp2) /* function is called via `jsr ra,itmp1' */
1013 stq ra,0*8(sp) /* save return address */
1014 stq pv,1*8(sp) /* save pv of calling java function */
1015 stq a0,2*8(sp) /* save argument registers for leaf */
1016 stq a1,3*8(sp) /* functions and native stub */
1022 ldl itmp2,offclassinit(itmp1)
1023 bne itmp2,L_is_initialized
1025 mov itmp1,a0 /* move class pointer to a0 */
1029 beq v0,L_initializererror
1032 ldq ra,0*8(sp) /* get return address */
1033 subq ra,1*4,ra /* go back 1 instruction */
1034 ldl itmp1,8*8(sp) /* load machine code from stack */
1035 stl itmp1,0(ra) /* store the machine code */
1037 call_pal PAL_imb /* synchronise instruction cache */
1039 ldq ra,0*8(sp) /* restore return address */
1040 ldq pv,1*8(sp) /* restore pv of calling java function */
1041 ldq a0,2*8(sp) /* restore argument registers */
1048 addq sp,(8+1)*8,sp /* remove stack frame (+1 for machine code) */
1050 subq ra,1*4,ra /* go back 1 instruction */
1051 jmp zero,(ra) /* jump to the new code */
1054 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1055 jsr ra,builtin_asm_get_exceptionptrptr
1057 lda v0,_exceptionptr
1059 ldq xptr,0(v0) /* get the exception pointer */
1060 stq zero,0(v0) /* clear the exception pointer */
1062 ldq ra,0*8(sp) /* restore return address */
1063 ldq pv,1*8(sp) /* restore pv of calling java function */
1064 ldq a0,2*8(sp) /* restore argument registers */
1071 addq sp,(8+1)*8,sp /* remove stack frame (+1 for machine code) */
1074 br asm_handle_exception /* we have the pv of the calling java func. */
1076 .end asm_check_clinit
1079 /********************* function asm_builtin_monitorenter ***********************
1081 * Does null check and calls monitorenter or throws an exception *
1083 *******************************************************************************/
1085 #if defined(USE_THREADS)
1086 .ent asm_builtin_monitorenter
1088 asm_builtin_monitorenter:
1090 lda pv,builtin_monitorenter
1091 beq a0,nb_monitorenter /* if (null) throw exception */
1092 jmp zero,(pv) /* else call builtin_monitorenter */
1096 ldq xptr,string_java_lang_NullPointerException
1097 jmp zero,asm_throw_and_handle_nat_exception
1101 jsr ra,new_nullpointerexception
1107 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1108 br asm_handle_nat_exception
1111 .end asm_builtin_monitorenter
1115 /********************* function asm_builtin_monitorexit ************************
1117 * Does null check and calls monitorexit or throws an exception *
1119 *******************************************************************************/
1121 #if defined(USE_THREADS)
1122 .ent asm_builtin_monitorexit
1124 asm_builtin_monitorexit:
1126 lda pv,builtin_monitorexit
1127 beq a0,nb_monitorexit /* if (null) throw exception */
1128 jmp zero,(pv) /* else call builtin_monitorexit */
1132 ldq xptr,string_java_lang_NullPointerException
1133 jmp zero,asm_throw_and_handle_nat_exception
1137 jsr ra,new_nullpointerexception
1143 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1144 br asm_handle_nat_exception
1147 .end asm_builtin_monitorexit
1151 /************************ function asm_builtin_idiv ****************************
1153 * Does null check and calls idiv or throws an exception *
1155 *******************************************************************************/
1157 .ent asm_builtin_idiv
1162 beq a1,nb_idiv /* if (null) throw exception */
1163 jmp zero,(pv) /* else call builtin_idiv */
1166 ldq xptr,string_java_lang_ArithmeticException_message
1167 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1168 br asm_throw_and_handle_arithmetic_exception
1170 .end asm_builtin_idiv
1173 /************************ function asm_builtin_ldiv ****************************
1175 * Does null check and calls ldiv or throws an exception *
1177 *******************************************************************************/
1179 .ent asm_builtin_ldiv
1184 beq a1,nb_ldiv /* if (null) throw exception */
1185 jmp zero,(pv) /* else call builtin_ldiv */
1188 ldq xptr,string_java_lang_ArithmeticException_message
1189 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1190 br asm_throw_and_handle_arithmetic_exception
1192 .end asm_builtin_ldiv
1195 /************************ function asm_builtin_irem ****************************
1197 * Does null check and calls irem or throws an exception *
1199 *******************************************************************************/
1201 .ent asm_builtin_irem
1206 beq a1,nb_irem /* if (null) throw exception */
1207 jmp zero,(pv) /* else call builtin_irem */
1210 ldq xptr,string_java_lang_ArithmeticException_message
1211 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1212 br asm_throw_and_handle_arithmetic_exception
1214 .end asm_builtin_irem
1217 /************************ function asm_builtin_lrem ****************************
1219 * Does null check and calls lrem or throws an exception *
1221 *******************************************************************************/
1223 .ent asm_builtin_lrem
1228 beq a1,nb_lrem /* if (null) throw exception */
1229 jmp zero,(pv) /* else call builtin_lrem */
1232 ldq xptr,string_java_lang_ArithmeticException_message
1233 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1234 br asm_throw_and_handle_arithmetic_exception
1236 .end asm_builtin_lrem
1239 /******************* function asm_builtin_checkarraycast ***********************
1241 * Does the cast check and eventually throws an exception *
1243 *******************************************************************************/
1245 .ent asm_builtin_checkarraycast
1247 asm_builtin_checkarraycast:
1249 lda sp,-16(sp) /* allocate stack space */
1250 stq ra,0(sp) /* save return address */
1251 stq a0,8(sp) /* save object pointer */
1252 jsr ra,builtin_checkarraycast /* builtin_checkarraycast */
1254 beq v0,nb_carray_throw /* if (false) throw exception */
1255 ldq ra,0(sp) /* restore return address */
1256 ldq v0,8(sp) /* return object pointer */
1257 lda sp,16(sp) /* free stack space */
1264 ldq xptr,string_java_lang_ClassCastException
1265 jmp zero,asm_throw_and_handle_nat_exception
1267 ldq a0,string_java_lang_ClassCastException
1268 jsr ra,new_exception
1272 ldq ra,0(sp) /* restore return address */
1273 lda sp,16(sp) /* free stack space */
1274 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1275 br asm_handle_nat_exception
1278 .end asm_builtin_checkarraycast
1281 /******************* function asm_builtin_aastore ******************************
1283 * Does the cast check and eventually throws an exception *
1285 *******************************************************************************/
1287 .ent asm_builtin_aastore
1289 asm_builtin_aastore:
1291 beq a0,nb_aastore_null /* if null pointer throw exception */
1292 ldl t0,offarraysize(a0) /* load size */
1293 lda sp,-24(sp) /* allocate stack space */
1294 stq ra,0(sp) /* save return address */
1295 s8addq a1,a0,t1 /* add index*8 to arrayref */
1296 cmpult a1,t0,t0 /* do bound check */
1297 beq t0,nb_aastore_bound /* if out of bounds throw exception */
1298 mov a2,a1 /* object is second argument */
1299 stq t1,8(sp) /* save store position */
1300 stq a1,16(sp) /* save object */
1301 jsr ra,builtin_canstore /* builtin_canstore(arrayref,object) */
1303 ldq ra,0(sp) /* restore return address */
1304 ldq a0,8(sp) /* restore store position */
1305 ldq a1,16(sp) /* restore object */
1306 lda sp,24(sp) /* free stack space */
1307 beq v0,nb_aastore_throw /* if (false) throw exception */
1308 stq a1,offobjarrdata(a0) /* store objectptr in array */
1312 ldq xptr,string_java_lang_NullPointerException
1314 jmp zero,asm_throw_and_handle_nat_exception
1316 subq sp,8,sp /* allocate stack space */
1317 stq ra,0(sp) /* save return address */
1318 jsr ra,new_nullpointerexception
1324 mov ra,xpc /* faulting address is return adress */
1325 br asm_handle_nat_exception
1332 jmp zero,asm_throw_and_handle_arrayindexoutofbounds_exception
1334 ldq a0,string_java_lang_ArrayIndexOutOfBoundsException
1335 jsr ra,new_exception_int /* a1 already contains the index */
1339 ldq ra,0(sp) /* restore return address */
1340 lda sp,24(sp) /* free stack space */
1341 mov ra,xpc /* faulting address is return adress */
1342 br asm_handle_nat_exception
1346 ldq xptr,string_java_lang_ArrayStoreException
1347 jmp zero,asm_throw_and_handle_nat_exception
1349 subq sp,8,sp /* allocate stack space */
1350 stq ra,0(sp) /* save return address */
1351 jsr ra,new_arraystoreexception
1357 mov ra,xpc /* faulting address is return adress */
1358 br asm_handle_nat_exception
1360 .end asm_builtin_aastore
1363 /******************* function asm_initialize_thread_stack **********************
1365 * initialized a thread stack *
1367 *******************************************************************************/
1369 .ent asm_initialize_thread_stack
1371 asm_initialize_thread_stack:
1392 .end asm_initialize_thread_stack
1395 /******************* function asm_perform_threadswitch *************************
1397 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1399 * performs a threadswitch *
1401 *******************************************************************************/
1403 .ent asm_perform_threadswitch
1405 asm_perform_threadswitch:
1446 .end asm_perform_threadswitch
1449 /********************* function asm_switchstackandcall *************************
1451 * void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1454 * Switches to a new stack, calls a function and switches back. *
1455 * a0 new stack pointer *
1456 * a1 function pointer *
1457 * a2 pointer to variable where stack top should be stored *
1458 * a3 pointer to user data, is passed to the function *
1460 *******************************************************************************/
1463 .ent asm_switchstackandcall
1465 asm_switchstackandcall:
1466 lda a0,-2*8(a0) /* allocate new stack */
1467 stq ra,0(a0) /* save return address on new stack */
1468 stq sp,1*8(a0) /* save old stack pointer on new stack */
1469 stq sp,0(a2) /* save old stack pointer to variable */
1470 mov a0,sp /* switch to new stack */
1472 mov a1,pv /* load function pointer */
1473 mov a3,a0 /* pass pointer */
1474 jmp ra,(pv) /* and call function */
1476 ldq ra,0(sp) /* load return address */
1477 ldq sp,1*8(sp) /* switch to old stack */
1479 jmp zero,(ra) /* return */
1481 .end asm_switchstackandcall
1483 .ent asm_getclassvalues_atomic
1485 asm_getclassvalues_atomic:
1488 ldl t0,offbaseval(a0)
1489 ldl t1,offdiffval(a0)
1490 ldl t2,offbaseval(a1)
1492 stl t0,offcast_super_baseval(a2)
1493 stl t1,offcast_super_diffval(a2)
1494 stl t2,offcast_sub_baseval(a2)
1497 .end asm_getclassvalues_atomic
1501 asm_criticalsections:
1502 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1505 .quad _crit_restart1
1508 .quad _crit_restart2
1513 .ent asm_prepare_native_stackinfo
1514 asm_prepare_native_stackinfo:
1517 jsr ra,builtin_asm_get_stackframeinfo
1525 .end asm_prepare_native_stackinfo
1527 .ent asm_remove_native_stackinfo
1528 asm_remove_native_stackinfo:
1534 .end asm_remove_native_stackinfo
1537 * These are local overrides for various environment variables in Emacs.
1538 * Please do not remove this and leave it at the end of the file, where
1539 * Emacs will automagically detect them.
1540 * ---------------------------------------------------------------------
1543 * indent-tabs-mode: t