1 /* src/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
33 $Id: asmpart.S 2389 2005-04-26 16:16:05Z twisti $
39 #include "vm/jit/alpha/offsets.h"
40 #include "vm/jit/alpha/asmoffsets.h"
104 /* save and restore macros ****************************************************/
106 #define SAVE_ARGUMENT_REGISTERS(off) \
107 stq a0,(0+(off))*8(sp) ; \
108 stq a1,(1+(off))*8(sp) ; \
109 stq a2,(2+(off))*8(sp) ; \
110 stq a3,(3+(off))*8(sp) ; \
111 stq a4,(4+(off))*8(sp) ; \
112 stq a5,(5+(off))*8(sp) ;
115 #define RESTORE_ARGUMENT_REGISTERS(off) \
116 ldq a0,(0+(off))*8(sp) ; \
117 ldq a1,(1+(off))*8(sp) ; \
118 ldq a2,(2+(off))*8(sp) ; \
119 ldq a3,(3+(off))*8(sp) ; \
120 ldq a4,(4+(off))*8(sp) ; \
121 ldq a5,(5+(off))*8(sp) ;
124 #define SAVE_TEMPORARY_REGISTERS(off) \
125 stq t0,(0+(off))*8(sp) ; \
126 stq t1,(1+(off))*8(sp) ; \
127 stq t2,(2+(off))*8(sp) ; \
128 stq t3,(3+(off))*8(sp) ; \
129 stq t4,(4+(off))*8(sp) ; \
130 stq t5,(5+(off))*8(sp) ; \
131 stq t6,(6+(off))*8(sp) ; \
132 stq t7,(7+(off))*8(sp) ; \
133 stq t8,(8+(off))*8(sp) ; \
134 stq t9,(9+(off))*8(sp) ; \
135 stq t10,(10+(off))*8(sp) ;
138 #define RESTORE_TEMPORARY_REGISTERS(off) \
139 ldq t0,(0+(off))*8(sp) ; \
140 ldq t1,(1+(off))*8(sp) ; \
141 ldq t2,(2+(off))*8(sp) ; \
142 ldq t3,(3+(off))*8(sp) ; \
143 ldq t4,(4+(off))*8(sp) ; \
144 ldq t5,(5+(off))*8(sp) ; \
145 ldq t6,(6+(off))*8(sp) ; \
146 ldq t7,(7+(off))*8(sp) ; \
147 ldq t8,(8+(off))*8(sp) ; \
148 ldq t9,(9+(off))*8(sp) ; \
149 ldq t10,(10+(off))*8(sp) ;
157 /********************* exported functions and variables ***********************/
159 .globl asm_sync_instruction_cache
160 .globl has_no_x_instr_set
162 .globl asm_calljavafunction
163 .globl asm_calljavafunction_int
165 .globl asm_calljavafunction2
166 .globl asm_calljavafunction2int
167 .globl asm_calljavafunction2long
168 .globl asm_calljavafunction2float
169 .globl asm_calljavafunction2double
171 .globl asm_call_jit_compiler
172 .globl asm_throw_and_handle_exception
173 .globl asm_throw_and_handle_nat_exception
174 .globl asm_throw_and_handle_arithmetic_exception
175 .globl asm_throw_and_handle_arrayindexoutofbounds_exception
176 .globl asm_handle_exception
177 .globl asm_handle_nat_exception
179 .globl asm_wrapper_patcher
181 .globl asm_builtin_checkarraycast
182 .globl asm_builtin_aastore
184 .globl asm_builtin_idiv
185 .globl asm_builtin_irem
186 .globl asm_builtin_ldiv
187 .globl asm_builtin_lrem
189 .globl asm_perform_threadswitch
190 .globl asm_initialize_thread_stack
191 .globl asm_switchstackandcall
192 .globl asm_criticalsections
193 .globl asm_getclassvalues_atomic
194 .globl asm_prepare_native_stackinfo
195 .globl asm_remove_native_stackinfo
196 .globl asm_refillin_and_handle_exception
199 /* asm_sync_instruction_cache **************************************************
203 *******************************************************************************/
205 .ent asm_sync_instruction_cache
207 asm_sync_instruction_cache:
208 call_pal PAL_imb /* synchronize instruction cache */
211 .end asm_sync_instruction_cache
213 /*********************** function has_no_x_instr_set ***************************
215 * determines if the byte support instruction set (21164a and higher) *
218 *******************************************************************************/
220 .ent has_no_x_instr_set
223 .long 0x47e03c20 /* amask 1,v0 */
224 jmp zero,(ra) /* return */
226 .end has_no_x_instr_set
229 /********************* function asm_calljavafunction ***************************
231 * This function calls a Java-method (which possibly needs compilation) *
232 * with up to 4 address parameters. *
234 * This functions calls the JIT-compiler which eventually translates the *
235 * method into machine code. *
238 * javaobject_header *asm_calljavafunction (methodinfo *m, *
239 * void *arg1, void *arg2, void *arg3, void *arg4); *
241 *******************************************************************************/
243 .ent asm_calljavafunction
246 .ascii "calljavafunction\0\0"
249 .quad 0 /* catch type all */
250 .quad calljava_xhandler /* handler pc */
251 .quad calljava_xhandler /* end pc */
252 .quad asm_calljavafunction /* 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 0 /* intsave */
262 .long 32 /* frame size */
263 .quad 0 /* method pointer (pointer to name) */
265 asm_calljavafunction:
266 asm_calljavafunction_int:
268 lda sp,-32(sp) /* allocate stack space */
269 stq gp,24(sp) /* save global pointer */
270 stq ra,0(sp) /* save return address */
272 stq a0,16(sp) /* save method pointer for compiler */
273 lda v0,16(sp) /* pass pointer to method pointer via v0*/
275 mov a1,a0 /* pass the remaining parameters */
280 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
281 stq $28,8(sp) /* store function address */
282 mov sp,$28 /* set method pointer */
284 ldq pv,8($28) /* method call as in Java */
285 jmp ra,(pv) /* call JIT compiler */
287 lda pv,-64(ra) /* asm_calljavafunction-calljava_jit !!!!!*/
290 ldq ra,0(sp) /* restore return address */
291 ldq gp,24(sp) /* restore global pointer */
292 lda sp,32(sp) /* free stack space */
298 ldq gp,24(sp) /* restore global pointer */
300 jsr ra,builtin_throw_exception
301 ldq ra,0(sp) /* restore return address */
302 lda sp,32(sp) /* free stack space */
303 mov zero,v0 /* return NULL */
305 .end asm_calljavafunction
310 .ent asm_calljavafunction2
315 .quad 0 /* catch type all */
316 .quad calljava_xhandler2 /* handler pc */
317 .quad calljava_xhandler2 /* end pc */
318 .quad asm_calljavafunction2 /* start pc */
319 .long 1 /* extable size */
320 .long 0 /* PADDING */
321 .quad 0 /* line number table start */
322 .quad 0 /* line number table size */
323 .long 0 /* PADDING */
324 .long 0 /* fltsave */
325 .long 1 /* intsave */
328 .long 40 /* frame size */
329 .quad 0 /* method pointer (pointer to name) */
331 asm_calljavafunction2:
332 asm_calljavafunction2int:
333 asm_calljavafunction2long:
334 asm_calljavafunction2float:
335 asm_calljavafunction2double:
337 lda sp,-40(sp) /* allocate stack space */
338 stq ra,0(sp) /* save return address */
340 stq gp,8(sp) /* save global pointer */
342 stq a0,32(sp) /* save method pointer for compiler */
343 mov a3,t0 /* pointer to arg block */
344 mov a1,s6 /* arg count */
346 ble s6,calljava_argsloaded
348 ldq a0,offjniitem(t0)
349 ldt $f16,offjniitem(t0)
350 ble s6,calljava_argsloaded
352 ldq a1,offjniitem+sizejniblock*1(t0)
353 ldt $f17,offjniitem+sizejniblock*1(t0)
354 ble s6,calljava_argsloaded
356 ldq a2,offjniitem+sizejniblock*2(t0)
357 ldt $f18,offjniitem+sizejniblock*2(t0)
358 ble s6,calljava_argsloaded
360 ldq a3,offjniitem+sizejniblock*3(t0)
361 ldt $f19,offjniitem+sizejniblock*3(t0)
362 ble s6,calljava_argsloaded
364 ldq a4,offjniitem+sizejniblock*4(t0)
365 ldt $f20,offjniitem+sizejniblock*4(t0)
366 ble s6,calljava_argsloaded
368 ldq a5,offjniitem+sizejniblock*5(t0)
369 ldt $f21,offjniitem+sizejniblock*5(t0)
372 ble s6,calljava_nocopy
378 ldq t3,offjniitem+sizejniblock*6(t0)
381 lda t0,sizejniblock(t0)
383 bne t1,calljava_copyloop
386 lda v0,32(t4) /* pass pointer to method pointer via v0*/
388 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
389 stq $28,16(t4) /* store function address */
390 lda $28,8(t4) /* set method pointer */
392 ldq pv,8($28) /* method call as in Java */
393 jmp ra,(pv) /* call JIT compiler */
395 lda pv,-200(ra) /* asm_calljavafunction-calljava_jit !!!*/
399 ldq ra,0(sp) /* restore return address */
400 ldq gp,8(sp) /* restore global pointer */
402 lda sp,40(sp) /* free stack space */
409 ldq gp,8(sp) /* restore global pointer */
411 jsr ra,builtin_throw_exception
412 ldq ra,0(sp) /* restore return address */
414 lda sp,40(sp) /* free stack space */
416 .end asm_calljavafunction2
419 /****************** function asm_call_jit_compiler *****************************
421 * invokes the compiler for untranslated JavaVM methods. *
423 * Register R0 contains a pointer to the method info structure (prepared *
424 * by createcompilerstub). Using the return address in R26 and the *
425 * offset in the LDA instruction or using the value in methodptr R28 the *
426 * patching address for storing the method address can be computed: *
428 * method address was either loaded using *
429 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
430 * M_LDA (REG_PV, REG_RA, low) *
431 * M_LDAH(REG_PV, REG_RA, high) ; optional *
433 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
434 * in the static case the method pointer can be computed using the *
435 * return address and the lda function following the jmp instruction *
437 *******************************************************************************/
439 .ent asm_call_jit_compiler
441 asm_call_jit_compiler:
443 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
444 srl t8,16,t8 /* shift right register number $yy */
445 and t8,31,t8 /* isolate register number */
446 subl t8,28,t8 /* test for REG_METHODPTR */
448 ldl t8,0(ra) /* load instruction LDA PV,xxx(RA) */
450 sra t8,48,t8 /* isolate offset */
451 addq t8,ra,$28 /* compute update address */
452 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
453 srl t8,16,t8 /* isolate instruction code */
454 lda t8,-0x177b(t8) /* test for LDAH */
456 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
457 sll t8,16,t8 /* compute high offset */
458 addl t8,0,t8 /* sign extend high offset */
459 addq t8,$28,$28 /* compute update address */
461 lda sp,-14*8(sp) /* reserve stack space */
462 stq a0,0*8(sp) /* save all argument registers */
463 stq a1,1*8(sp) /* they could be used by method */
474 stq $28,12*8(sp) /* save method pointer */
475 stq ra,13*8(sp) /* save return address */
477 ldq a0,0(v0) /* pass 'methodinfo' pointer to */
478 jsr ra,jit_compile /* jit compiler */
481 ldq a0,0*8(sp) /* load argument registers */
493 ldq $28,12*8(sp) /* load method pointer */
494 ldq ra,13*8(sp) /* load return address */
495 lda sp,14*8(sp) /* deallocate stack area */
497 beq v0,asm_call_jit_compiler_exception
499 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
501 sra t8,48,t8 /* isolate offset */
503 addq t8,$28,t8 /* compute update address via method pointer*/
504 stq v0,0(t8) /* save new method address there */
506 call_pal PAL_imb /* synchronise instruction cache */
508 mov v0,pv /* load method address into pv */
509 jmp zero,(pv) /* and call method. The method returns */
510 /* directly to the caller (ra). */
512 asm_call_jit_compiler_exception:
513 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
516 jsr ra,builtin_asm_get_exceptionptrptr
522 ldq xptr,0(v0) /* get the exception pointer */
523 stq zero,0(v0) /* clear the exception pointer */
526 br asm_handle_nat_exception
528 .end asm_call_jit_compiler
531 /**************** function asm_refillin_and_handle_exception *******************
533 * This function handles an exception. It does not use the usual calling *
534 * conventions. The exception is passed in REG_ITMP1 and the *
535 * pc from the exception raising position is passed in REG_ITMP2. *
536 * a0 contains the PV of the function causing the problem *
538 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
540 *******************************************************************************/
541 .ent asm_refillin_and_handle_exception
542 asm_refillin_and_handle_exception:
544 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
546 sra t0,48,t0 /* isolate offset */
547 addq t0,ra,pv /* compute update address */
548 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
549 srl t0,16,t0 /* isolate instruction code */
550 lda t0,-0x177b(t0) /* test for LDAH */
551 bne t0, asm_refillin_and_handle_exception_cont
552 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
553 sll t0,16,t0 /* compute high offset */
554 addl t0,0,t0 /* sign extend high offset */
555 addq t0,pv,pv /* compute update address */
557 asm_refillin_and_handle_exception_cont:
560 lda sp,-6*8(sp) /* prepare stackframe*/
561 stq pv,5*8(sp) /* store pv of caller */
562 stq xptr,4*8(sp) /*exception ptr*/
563 stq xpc,3*8(sp) /*address of failure*/
564 stq t0,2*8(sp) /*begin of java stack frame*/
565 stq pv,1*8(sp) /* store pv of caller */
566 stq zero,0*8(sp) /*builtin (invisible) function */
567 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
570 ldq a2,utf_void__java_lang_Throwable
571 ldq a1,utf_fillInStackTrace
573 ldq t1,offobjvftbl(t0)
575 jsr ra,class_resolvemethod
577 /* now we have the method */
582 jsr ra,asm_calljavafunction
586 jsr ra,asm_remove_native_stackinfo
595 br asm_handle_exception
597 .end asm_refillin_and_handle_exception
599 /****** function asm_throw_and_handle_arrayindexoutofbounds_exception **********
601 * This function handles an exception. It does not use the usual calling *
602 * conventions. The integer parameter is passed in REG_ITMP1 and the *
603 * pc from the exception raising position is passed in REG_ITMP2. *
605 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
607 *******************************************************************************/
609 .ent asm_throw_and_handle_arrayindexoutofbounds_exception
611 asm_throw_and_handle_arrayindexoutofbounds_exception:
614 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
616 sra t0,48,t0 /* isolate offset */
617 addq t0,ra,pv /* compute update address */
618 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
619 srl t0,16,t0 /* isolate instruction code */
620 lda t0,-0x177b(t0) /* test for LDAH */
621 bne t0,asm_throw_and_handle_arrayindexoutofbounds_exception_cont
622 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
623 sll t0,16,t0 /* compute high offset */
624 addl t0,0,t0 /* sign extend high offset */
625 addq t0,pv,pv /* compute update address */
627 asm_throw_and_handle_arrayindexoutofbounds_exception_cont:
629 lda sp,-6*8(sp) /*prepare stackframe*/
630 stq pv,5*8(sp) /*pv of failure*/
631 stq itmp1,4*8(sp) /*int parameter of the exception*/
632 stq xpc,3*8(sp) /*address of failure */
633 stq t0,2*8(sp) /*store begin of java stack frame*/
634 stq pv,1*8(sp) /*store pv of caller in structure*/
635 stq zero,0*8(sp) /*builtin (invisible function)*/
637 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
640 ldq a0,6*8(sp) /*int of exception*/
641 jsr ra,new_arrayindexoutofboundsexception
644 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
646 jsr ra,asm_remove_native_stackinfo
652 br asm_handle_exception
654 .end asm_throw_and_handle_arrayindexoutofbounds_exception
657 /* asm_throw_and_handle_arithmetic_exception ***********************************
661 *******************************************************************************/
663 .ent asm_throw_and_handle_arithmetic_exception
665 asm_throw_and_handle_arithmetic_exception:
666 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
668 sra t0,48,t0 /* isolate offset */
669 addq t0,ra,pv /* compute update address */
670 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
671 srl t0,16,t0 /* isolate instruction code */
672 lda t0,-0x177b(t0) /* test for LDAH */
673 bne t0,asm_throw_and_handle_arithmetic_exception_cont
674 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
675 sll t0,16,t0 /* compute high offset */
676 addl t0,0,t0 /* sign extend high offset */
677 addq t0,pv,pv /* compute update address */
679 asm_throw_and_handle_arithmetic_exception_cont:
681 lda sp,-6*8(sp) /*prepare stackframe*/
682 stq pv,5*8(sp) /*pv of failure*/
683 stq itmp1,4*8(sp) /*exception string of the exception*/
684 stq xpc,3*8(sp) /*address of failure */
685 stq t0,2*8(sp) /*store begin of java stack frame*/
686 stq pv,1*8(sp) /*store pv of caller in structure*/
687 stq zero,0*8(sp) /*builtin (invisible function)*/
688 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
691 jsr ra,new_arithmeticexception
693 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
695 jsr ra,asm_remove_native_stackinfo
701 br asm_handle_exception
703 .end asm_throw_and_handle_arithmetic_exception
706 /* asm_throw_and_handle_exception **********************************************
710 *******************************************************************************/
712 .ent asm_throw_and_handle_nat_exception
714 asm_throw_and_handle_nat_exception:
716 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
718 sra t0,48,t0 /* isolate offset */
719 addq t0,ra,pv /* compute update address */
720 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
721 srl t0,16,t0 /* isolate instruction code */
722 lda t0,-0x177b(t0) /* test for LDAH */
723 bne t0,asm_throw_and_handle_exception
724 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
725 sll t0,16,t0 /* compute high offset */
726 addl t0,0,t0 /* sign extend high offset */
727 addq t0,pv,pv /* compute update address */
729 .aent asm_throw_and_handle_exception
731 asm_throw_and_handle_exception:
733 lda sp,-6*8(sp) /* prepare stackframe */
734 stq pv,5*8(sp) /* pv of failure */
735 stq xptr,4*8(sp) /* classname of the exception */
736 stq xpc,3*8(sp) /* address of failure */
737 stq t0,2*8(sp) /* store begin of java stack frame */
738 stq pv,1*8(sp) /* store pv of caller in structure */
739 stq zero,0*8(sp) /* builtin (invisible function) */
740 /* puts 2 additional quadwords on stack */
741 jsr ra,asm_prepare_native_stackinfo
744 ldq a0,6*8(sp) /* classname of exception */
748 mov v0,xptr /* xptr (itmp1) is not touched in */
749 /* asm_remove_native_stackinfo */
751 jsr ra,asm_remove_native_stackinfo
757 br asm_handle_exception
759 .end asm_throw_and_handle_nat_exception
762 /********************* function asm_handle_exception ***************************
764 * This function handles an exception. It does not use the usual calling *
765 * conventions. The exception pointer is passed in REG_ITMP1 and the *
766 * pc from the exception raising position is passed in REG_ITMP2. It searches *
767 * the local exception table for a handler. If no one is found, it unwinds *
768 * stacks and continues searching the callers. *
770 * void asm_handle_exception (exceptionptr, exceptionpc); *
772 *******************************************************************************/
774 .ent asm_handle_nat_exception
776 asm_handle_nat_exception:
777 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
779 sra t0,48,t0 /* isolate offset */
780 addq t0,ra,pv /* compute update address */
781 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
782 srl t0,16,t0 /* isolate instruction code */
783 lda t0,-0x177b(t0) /* test for LDAH */
784 bne t0,asm_handle_exception
785 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
786 sll t0,16,t0 /* compute high offset */
787 addl t0,0,t0 /* sign extend high offset */
788 addq t0,pv,pv /* compute update address */
790 .aent asm_handle_exception
792 asm_handle_exception:
793 lda sp,-18*8(sp) /* allocate stack */
794 stq t0,0*8(sp) /* save possible used registers */
795 stq t1,1*8(sp) /* also registers used by trace_exception */
813 lda t3,1(zero) /* set no unwind flag */
815 lda sp,-5*8(sp) /* allocate stack */
816 stq xptr,0*8(sp) /* save used register */
823 ldq a1,MethodPointer(pv)
828 br ra,ex_trace /* set ra for gp loading */
830 ldgp gp,0(ra) /* load gp */
831 jsr ra,builtin_trace_exception /* trace_exception(xptr,methodptr) */
833 ldq xptr,0*8(sp) /* restore used register */
838 lda sp,5*8(sp) /* deallocate stack */
840 ldl t0,ExTableSize(pv) /* t0 = exception table size */
841 beq t0,empty_table /* if empty table skip */
843 lda t1,ExTableStart(pv) /* t1 = start of exception table */
846 ldq t2,ExStartPC(t1) /* t2 = exception start pc */
847 cmple t2,xpc,t2 /* t2 = (startpc <= xpc) */
848 beq t2,ex_table_cont /* if (false) continue */
849 ldq t2,ExEndPC(t1) /* t2 = exception end pc */
850 cmplt xpc,t2,t2 /* t2 = (xpc < endpc) */
851 beq t2,ex_table_cont /* if (false) continue */
852 ldq a1,ExCatchType(t1) /* arg1 = exception catch type */
853 beq a1,ex_handle_it /* NULL catches everything */
855 ldl itmp3,offclassloaded(a1)
856 bne itmp3,L_class_loaded
858 subq sp,8*8,sp /* allocate stack */
859 stq t0,0*8(sp) /* save used register */
870 br ra,L_class_load_ra /* set ra for gp loading */
872 ldgp gp,0(ra) /* load gp */
873 jsr ra,load_class_bootstrap
875 ldq t0,0*8(sp) /* restore used register */
883 addq sp,8*8,sp /* deallocate stack */
886 ldl itmp3,offclasslinked(a1)
887 subq sp,8*8,sp /* allocate stack */
889 bne itmp3,L_class_linked
891 stq t0,0*8(sp) /* save used register */
901 br ra,L_class_link_ra /* set ra for gp loading */
903 ldgp gp,0(ra) /* load gp */
906 ldq t0,0*8(sp) /* restore used register */
918 ldq a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
919 ldq a1,offclassvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
920 ldl a0,offbaseval(a0) /* a0 = baseval(xptr) */
921 ldl v0,offbaseval(a1) /* a2 = baseval(catchtype) */
922 ldl a1,offdiffval(a1) /* a1 = diffval(catchtype) */
924 subl a0,v0,a0 /* a0 = baseval(xptr) - baseval(catchtype) */
925 cmpule a0,a1,v0 /* v0 = xptr is instanceof catchtype */
926 addq sp,8*8,sp /* deallocate stack */
927 beq v0,ex_table_cont /* if (false) continue */
930 ldq xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
932 beq t3,ex_jump /* if (!(no stack unwinding) skip */
934 ldq t0,0*8(sp) /* restore possible used registers */
935 ldq t1,1*8(sp) /* also registers used by trace_exception */
952 lda sp,18*8(sp) /* deallocate stack */
955 jmp zero,(xpc) /* jump to the handler */
958 lda t1,ExEntrySize(t1) /* next exception table entry */
959 subl t0,1,t0 /* decrement entry counter */
960 bgt t0,ex_table_loop /* if (t0 > 0) next entry */
963 beq t3,ex_already_cleared /* if here the first time, then */
964 lda sp,18*8(sp) /* deallocate stack and */
965 clr t3 /* clear the no unwind flag */
967 ldl t0,IsSync(pv) /* t0 = SyncOffset */
968 beq t0,no_monitor_exit /* if zero no monitorexit */
970 #if defined(USE_THREADS)
971 addq sp,t0,t0 /* add stackptr to Offset */
972 ldq a0,-8(t0) /* load monitorexit pointer */
974 lda sp,-7*8(sp) /* allocate stack */
975 stq t0,0*8(sp) /* save used register */
983 br ra,ex_mon_load /* set ra for gp loading */
985 ldgp gp,0(ra) /* load gp */
986 jsr ra,builtin_monitorexit/* builtin_monitorexit(objectptr) */
988 ldq t0,0*8(sp) /* restore used register */
995 lda sp,7*8(sp) /* deallocate stack */
999 ldl t0,FrameSize(pv) /* t0 = frame size */
1000 addq sp,t0,sp /* unwind stack */
1001 mov sp,t0 /* t0 = pointer to save area */
1002 ldl t1,IsLeaf(pv) /* t1 = is leaf procedure */
1003 bne t1,ex_no_restore /* if (leaf) skip */
1004 ldq ra,-8(t0) /* restore ra */
1005 lda t0,-8(t0) /* t0-- */
1007 mov ra,xpc /* the new xpc is ra */
1008 ldl t1,IntSave(pv) /* t1 = saved int register count */
1009 br t2,ex_int1 /* t2 = current pc */
1011 lda t2,44(t2) /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
1012 negl t1,t1 /* negate register count */
1013 s4addq t1,t2,t2 /* t2 = ex_int_sav - 4 * register count */
1014 jmp zero,(t2) /* jump to save position */
1023 s8addq t1,t0,t0 /* t0 = t0 - 8 * register count */
1025 ldl t1,FltSave(pv) /* t1 = saved flt register count */
1026 br t2,ex_flt1 /* t2 = current pc */
1028 lda t2,48(t2) /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
1029 negl t1,t1 /* negate register count */
1030 s4addq t1,t2,t2 /* t2 = ex_flt_sav - 4 * register count */
1031 jmp zero,(t2) /* jump to save position */
1041 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
1043 sra t0,48,t0 /* isolate offset */
1044 addq t0,ra,pv /* compute update address */
1045 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
1046 srl t0,16,t0 /* isolate instruction code */
1047 lda t0,-0x177b(t0) /* test for LDAH */
1048 bne t0,ex_stack_loop
1049 ldl t0,4(ra) /* load instruction LDAH PV,xxx(RA) */
1050 sll t0,16,t0 /* compute high offset */
1051 addl t0,0,t0 /* sign extend high offset */
1052 addq t0,pv,pv /* compute update address */
1055 .end asm_handle_nat_exception
1058 /* asm_wrapper_patcher *********************************************************
1063 16 machine code (which is patched back later)
1064 8 unresolved class/method/field reference
1065 0 patcher function pointer to call
1067 -8 return address (saved below in the wrapper)
1069 ATTENTION: itmp3 == gp! But we don't need gp do call the patcher function.
1071 *******************************************************************************/
1073 .ent asm_wrapper_patcher
1075 asm_wrapper_patcher:
1076 subq sp,(6+11+4)*8,sp /* create stack frame */
1078 SAVE_ARGUMENT_REGISTERS(0) /* save 6 integer argument registers */
1079 SAVE_TEMPORARY_REGISTERS(6) /* save 11 integer temporary registers */
1081 stq itmp1,(6+11+0)*8(sp) /* save itmp1 */
1082 stq itmp2,(6+11+1)*8(sp) /* save itmp2 */
1083 stq pv,(6+11+2)*8(sp) /* save pv of calling java function */
1084 stq ra,(6+11+3)*8(sp) /* save return address */
1086 mov sp,a0 /* pass stack pointer */
1087 addq a0,(1+6+11+4)*8,a0 /* skip patcher function pointer */
1088 ldq pv,(0+6+11+4)*8(sp) /* get function pointer */
1089 jmp ra,(pv) /* call the patcher function */
1092 RESTORE_ARGUMENT_REGISTERS(0) /* restore 6 integer argument registers */
1093 RESTORE_TEMPORARY_REGISTERS(6)/* restore 11 integer temporary registers */
1095 ldq itmp1,(6+11+0)*8(sp) /* restore itmp1 */
1096 ldq itmp2,(6+11+1)*8(sp) /* restore itmp2 */
1097 ldq pv,(6+11+2)*8(sp) /* restore pv of calling java function */
1098 ldq ra,(6+11+3)*8(sp) /* restore return address */
1100 addq sp,(3+6+11+4)*8,sp /* remove stack frame */
1102 beq v0,L_asm_wrapper_patcher_exception
1103 jmp zero,(ra) /* jump to new patched code */
1105 L_asm_wrapper_patcher_exception:
1106 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1110 jsr ra,builtin_asm_get_exceptionptrptr
1115 lda v0,_exceptionptr
1117 ldq xptr,0(v0) /* get the exception pointer */
1118 stq zero,0(v0) /* clear the exception pointer */
1120 mov ra,xpc /* get exception pc */
1121 br asm_handle_exception /* we have the pv of the calling java func. */
1123 .end asm_wrapper_patcher
1126 /************************ function asm_builtin_idiv ****************************
1128 * Does null check and calls idiv or throws an exception *
1130 *******************************************************************************/
1132 .ent asm_builtin_idiv
1137 beq a1,nb_idiv /* if (null) throw exception */
1138 jmp zero,(pv) /* else call builtin_idiv */
1141 ldq xptr,string_java_lang_ArithmeticException_message
1142 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1143 br asm_throw_and_handle_arithmetic_exception
1145 .end asm_builtin_idiv
1148 /************************ function asm_builtin_ldiv ****************************
1150 * Does null check and calls ldiv or throws an exception *
1152 *******************************************************************************/
1154 .ent asm_builtin_ldiv
1159 beq a1,nb_ldiv /* if (null) throw exception */
1160 jmp zero,(pv) /* else call builtin_ldiv */
1163 ldq xptr,string_java_lang_ArithmeticException_message
1164 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1165 br asm_throw_and_handle_arithmetic_exception
1167 .end asm_builtin_ldiv
1170 /************************ function asm_builtin_irem ****************************
1172 * Does null check and calls irem or throws an exception *
1174 *******************************************************************************/
1176 .ent asm_builtin_irem
1181 beq a1,nb_irem /* if (null) throw exception */
1182 jmp zero,(pv) /* else call builtin_irem */
1185 ldq xptr,string_java_lang_ArithmeticException_message
1186 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1187 br asm_throw_and_handle_arithmetic_exception
1189 .end asm_builtin_irem
1192 /************************ function asm_builtin_lrem ****************************
1194 * Does null check and calls lrem or throws an exception *
1196 *******************************************************************************/
1198 .ent asm_builtin_lrem
1203 beq a1,nb_lrem /* if (null) throw exception */
1204 jmp zero,(pv) /* else call builtin_lrem */
1207 ldq xptr,string_java_lang_ArithmeticException_message
1208 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1209 br asm_throw_and_handle_arithmetic_exception
1211 .end asm_builtin_lrem
1214 /******************* function asm_builtin_checkarraycast ***********************
1216 * Does the cast check and eventually throws an exception *
1218 *******************************************************************************/
1220 .ent asm_builtin_checkarraycast
1222 asm_builtin_checkarraycast:
1224 lda sp,-16(sp) /* allocate stack space */
1225 stq ra,0(sp) /* save return address */
1226 stq a0,8(sp) /* save object pointer */
1227 jsr ra,builtin_checkarraycast /* builtin_checkarraycast */
1229 beq v0,nb_carray_throw /* if (false) throw exception */
1230 ldq ra,0(sp) /* restore return address */
1231 ldq v0,8(sp) /* return object pointer */
1232 lda sp,16(sp) /* free stack space */
1239 ldq xptr,string_java_lang_ClassCastException
1240 jmp zero,asm_throw_and_handle_nat_exception
1242 ldq a0,string_java_lang_ClassCastException
1243 jsr ra,new_exception
1247 ldq ra,0(sp) /* restore return address */
1248 lda sp,16(sp) /* free stack space */
1249 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1250 br asm_handle_nat_exception
1253 .end asm_builtin_checkarraycast
1256 /******************* function asm_builtin_aastore ******************************
1258 * Does the cast check and eventually throws an exception *
1260 *******************************************************************************/
1262 .ent asm_builtin_aastore
1264 asm_builtin_aastore:
1266 beq a0,nb_aastore_null /* if null pointer throw exception */
1267 ldl t0,offarraysize(a0) /* load size */
1268 lda sp,-24(sp) /* allocate stack space */
1269 stq ra,0(sp) /* save return address */
1270 s8addq a1,a0,t1 /* add index*8 to arrayref */
1271 cmpult a1,t0,t0 /* do bound check */
1272 beq t0,nb_aastore_bound /* if out of bounds throw exception */
1273 mov a2,a1 /* object is second argument */
1274 stq t1,8(sp) /* save store position */
1275 stq a1,16(sp) /* save object */
1276 jsr ra,builtin_canstore /* builtin_canstore(arrayref,object) */
1278 ldq ra,0(sp) /* restore return address */
1279 ldq a0,8(sp) /* restore store position */
1280 ldq a1,16(sp) /* restore object */
1281 lda sp,24(sp) /* free stack space */
1282 beq v0,nb_aastore_throw /* if (false) throw exception */
1283 stq a1,offobjarrdata(a0) /* store objectptr in array */
1287 ldq xptr,string_java_lang_NullPointerException
1289 jmp zero,asm_throw_and_handle_nat_exception
1291 subq sp,8,sp /* allocate stack space */
1292 stq ra,0(sp) /* save return address */
1293 jsr ra,new_nullpointerexception
1299 mov ra,xpc /* faulting address is return adress */
1300 br asm_handle_nat_exception
1307 jmp zero,asm_throw_and_handle_arrayindexoutofbounds_exception
1309 ldq a0,string_java_lang_ArrayIndexOutOfBoundsException
1310 jsr ra,new_exception_int /* a1 already contains the index */
1314 ldq ra,0(sp) /* restore return address */
1315 lda sp,24(sp) /* free stack space */
1316 mov ra,xpc /* faulting address is return adress */
1317 br asm_handle_nat_exception
1321 ldq xptr,string_java_lang_ArrayStoreException
1322 jmp zero,asm_throw_and_handle_nat_exception
1324 subq sp,8,sp /* allocate stack space */
1325 stq ra,0(sp) /* save return address */
1326 jsr ra,new_arraystoreexception
1332 mov ra,xpc /* faulting address is return adress */
1333 br asm_handle_nat_exception
1335 .end asm_builtin_aastore
1338 /******************* function asm_initialize_thread_stack **********************
1340 * initialized a thread stack *
1342 *******************************************************************************/
1344 .ent asm_initialize_thread_stack
1346 asm_initialize_thread_stack:
1367 .end asm_initialize_thread_stack
1370 /******************* function asm_perform_threadswitch *************************
1372 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1374 * performs a threadswitch *
1376 *******************************************************************************/
1378 .ent asm_perform_threadswitch
1380 asm_perform_threadswitch:
1421 .end asm_perform_threadswitch
1424 /********************* function asm_switchstackandcall *************************
1426 * void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1429 * Switches to a new stack, calls a function and switches back. *
1430 * a0 new stack pointer *
1431 * a1 function pointer *
1432 * a2 pointer to variable where stack top should be stored *
1433 * a3 pointer to user data, is passed to the function *
1435 *******************************************************************************/
1438 .ent asm_switchstackandcall
1440 asm_switchstackandcall:
1441 lda a0,-2*8(a0) /* allocate new stack */
1442 stq ra,0(a0) /* save return address on new stack */
1443 stq sp,1*8(a0) /* save old stack pointer on new stack */
1444 stq sp,0(a2) /* save old stack pointer to variable */
1445 mov a0,sp /* switch to new stack */
1447 mov a1,pv /* load function pointer */
1448 mov a3,a0 /* pass pointer */
1449 jmp ra,(pv) /* and call function */
1451 ldq ra,0(sp) /* load return address */
1452 ldq sp,1*8(sp) /* switch to old stack */
1454 jmp zero,(ra) /* return */
1456 .end asm_switchstackandcall
1458 .ent asm_getclassvalues_atomic
1460 asm_getclassvalues_atomic:
1463 ldl t0,offbaseval(a0)
1464 ldl t1,offdiffval(a0)
1465 ldl t2,offbaseval(a1)
1467 stl t0,offcast_super_baseval(a2)
1468 stl t1,offcast_super_diffval(a2)
1469 stl t2,offcast_sub_baseval(a2)
1472 .end asm_getclassvalues_atomic
1476 asm_criticalsections:
1477 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1480 .quad _crit_restart1
1483 .quad _crit_restart2
1488 .ent asm_prepare_native_stackinfo
1489 asm_prepare_native_stackinfo:
1492 jsr ra,builtin_asm_get_stackframeinfo
1500 .end asm_prepare_native_stackinfo
1502 .ent asm_remove_native_stackinfo
1503 asm_remove_native_stackinfo:
1509 .end asm_remove_native_stackinfo
1512 * These are local overrides for various environment variables in Emacs.
1513 * Please do not remove this and leave it at the end of the file, where
1514 * Emacs will automagically detect them.
1515 * ---------------------------------------------------------------------
1518 * indent-tabs-mode: t