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 2399 2005-04-27 12:53:03Z twisti $
39 #include "vm/jit/alpha/offsets.h"
40 #include "vm/jit/alpha/asmoffsets.h"
134 /* save and restore macros ****************************************************/
136 #define SAVE_ARGUMENT_REGISTERS(off) \
137 stq a0,(0+(off))*8(sp) ; \
138 stq a1,(1+(off))*8(sp) ; \
139 stq a2,(2+(off))*8(sp) ; \
140 stq a3,(3+(off))*8(sp) ; \
141 stq a4,(4+(off))*8(sp) ; \
142 stq a5,(5+(off))*8(sp) ; \
144 stt fa0,(6+(off))*8(sp) ; \
145 stt fa1,(7+(off))*8(sp) ; \
146 stt fa2,(8+(off))*8(sp) ; \
147 stt fa3,(9+(off))*8(sp) ; \
148 stt fa4,(10+(off))*8(sp) ; \
149 stt fa5,(11+(off))*8(sp) ;
151 #define RESTORE_ARGUMENT_REGISTERS(off) \
152 ldq a0,(0+(off))*8(sp) ; \
153 ldq a1,(1+(off))*8(sp) ; \
154 ldq a2,(2+(off))*8(sp) ; \
155 ldq a3,(3+(off))*8(sp) ; \
156 ldq a4,(4+(off))*8(sp) ; \
157 ldq a5,(5+(off))*8(sp) ; \
159 ldt fa0,(6+(off))*8(sp) ; \
160 ldt fa1,(7+(off))*8(sp) ; \
161 ldt fa2,(8+(off))*8(sp) ; \
162 ldt fa3,(9+(off))*8(sp) ; \
163 ldt fa4,(10+(off))*8(sp) ; \
164 ldt fa5,(11+(off))*8(sp) ;
166 #define SAVE_TEMPORARY_REGISTERS(off) \
167 stq t0,(0+(off))*8(sp) ; \
168 stq t1,(1+(off))*8(sp) ; \
169 stq t2,(2+(off))*8(sp) ; \
170 stq t3,(3+(off))*8(sp) ; \
171 stq t4,(4+(off))*8(sp) ; \
172 stq t5,(5+(off))*8(sp) ; \
173 stq t6,(6+(off))*8(sp) ; \
174 stq t7,(7+(off))*8(sp) ; \
175 stq t8,(8+(off))*8(sp) ; \
176 stq t9,(9+(off))*8(sp) ; \
177 stq t10,(10+(off))*8(sp) ; \
179 stt ft0,(11+(off))*8(sp) ; \
180 stt ft1,(12+(off))*8(sp) ; \
181 stt ft2,(13+(off))*8(sp) ; \
182 stt ft3,(14+(off))*8(sp) ; \
183 stt ft4,(15+(off))*8(sp) ; \
184 stt ft5,(16+(off))*8(sp) ; \
185 stt ft6,(17+(off))*8(sp) ; \
186 stt ft7,(18+(off))*8(sp) ; \
187 stt ft8,(19+(off))*8(sp) ; \
188 stt ft9,(20+(off))*8(sp) ; \
189 stt ft10,(21+(off))*8(sp) ; \
190 stt ft11,(22+(off))*8(sp) ; \
191 stt ft12,(23+(off))*8(sp) ; \
192 stt ft13,(24+(off))*8(sp) ; \
193 stt ft14,(25+(off))*8(sp) ; \
194 stt ft15,(26+(off))*8(sp) ;
197 #define RESTORE_TEMPORARY_REGISTERS(off) \
198 ldq t0,(0+(off))*8(sp) ; \
199 ldq t1,(1+(off))*8(sp) ; \
200 ldq t2,(2+(off))*8(sp) ; \
201 ldq t3,(3+(off))*8(sp) ; \
202 ldq t4,(4+(off))*8(sp) ; \
203 ldq t5,(5+(off))*8(sp) ; \
204 ldq t6,(6+(off))*8(sp) ; \
205 ldq t7,(7+(off))*8(sp) ; \
206 ldq t8,(8+(off))*8(sp) ; \
207 ldq t9,(9+(off))*8(sp) ; \
208 ldq t10,(10+(off))*8(sp) ; \
210 ldt ft0,(11+(off))*8(sp) ; \
211 ldt ft1,(12+(off))*8(sp) ; \
212 ldt ft2,(13+(off))*8(sp) ; \
213 ldt ft3,(14+(off))*8(sp) ; \
214 ldt ft4,(15+(off))*8(sp) ; \
215 ldt ft5,(16+(off))*8(sp) ; \
216 ldt ft6,(17+(off))*8(sp) ; \
217 ldt ft7,(18+(off))*8(sp) ; \
218 ldt ft8,(19+(off))*8(sp) ; \
219 ldt ft9,(20+(off))*8(sp) ; \
220 ldt ft10,(21+(off))*8(sp) ; \
221 ldt ft11,(22+(off))*8(sp) ; \
222 ldt ft12,(23+(off))*8(sp) ; \
223 ldt ft13,(24+(off))*8(sp) ; \
224 ldt ft14,(25+(off))*8(sp) ; \
225 ldt ft15,(26+(off))*8(sp) ;
233 /********************* exported functions and variables ***********************/
235 .globl asm_sync_instruction_cache
236 .globl has_no_x_instr_set
238 .globl asm_calljavafunction
239 .globl asm_calljavafunction_int
241 .globl asm_calljavafunction2
242 .globl asm_calljavafunction2int
243 .globl asm_calljavafunction2long
244 .globl asm_calljavafunction2float
245 .globl asm_calljavafunction2double
247 .globl asm_call_jit_compiler
248 .globl asm_throw_and_handle_exception
249 .globl asm_throw_and_handle_nat_exception
250 .globl asm_throw_and_handle_arithmetic_exception
251 .globl asm_throw_and_handle_arrayindexoutofbounds_exception
252 .globl asm_handle_exception
253 .globl asm_handle_nat_exception
255 .globl asm_wrapper_patcher
257 .globl asm_builtin_checkarraycast
258 .globl asm_builtin_aastore
260 .globl asm_builtin_idiv
261 .globl asm_builtin_irem
262 .globl asm_builtin_ldiv
263 .globl asm_builtin_lrem
265 .globl asm_perform_threadswitch
266 .globl asm_initialize_thread_stack
267 .globl asm_switchstackandcall
268 .globl asm_criticalsections
269 .globl asm_getclassvalues_atomic
270 .globl asm_prepare_native_stackinfo
271 .globl asm_remove_native_stackinfo
272 .globl asm_refillin_and_handle_exception
275 /* asm_sync_instruction_cache **************************************************
279 *******************************************************************************/
281 .ent asm_sync_instruction_cache
283 asm_sync_instruction_cache:
284 call_pal PAL_imb /* synchronize instruction cache */
287 .end asm_sync_instruction_cache
289 /*********************** function has_no_x_instr_set ***************************
291 * determines if the byte support instruction set (21164a and higher) *
294 *******************************************************************************/
296 .ent has_no_x_instr_set
299 .long 0x47e03c20 /* amask 1,v0 */
300 jmp zero,(ra) /* return */
302 .end has_no_x_instr_set
305 /********************* function asm_calljavafunction ***************************
307 * This function calls a Java-method (which possibly needs compilation) *
308 * with up to 4 address parameters. *
310 * This functions calls the JIT-compiler which eventually translates the *
311 * method into machine code. *
314 * javaobject_header *asm_calljavafunction (methodinfo *m, *
315 * void *arg1, void *arg2, void *arg3, void *arg4); *
317 *******************************************************************************/
319 .ent asm_calljavafunction
322 .ascii "calljavafunction\0\0"
325 .quad 0 /* catch type all */
326 .quad calljava_xhandler /* handler pc */
327 .quad calljava_xhandler /* end pc */
328 .quad asm_calljavafunction /* start pc */
329 .long 1 /* extable size */
330 .long 0 /* PADDING */
331 .quad 0 /* line number table start */
332 .quad 0 /* line number table size */
333 .long 0 /* PADDING */
334 .long 0 /* fltsave */
335 .long 0 /* intsave */
338 .long 32 /* frame size */
339 .quad 0 /* method pointer (pointer to name) */
341 asm_calljavafunction:
342 asm_calljavafunction_int:
344 lda sp,-32(sp) /* allocate stack space */
345 stq gp,24(sp) /* save global pointer */
346 stq ra,0(sp) /* save return address */
348 stq a0,16(sp) /* save method pointer for compiler */
349 lda v0,16(sp) /* pass pointer to method pointer via v0*/
351 mov a1,a0 /* pass the remaining parameters */
356 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
357 stq $28,8(sp) /* store function address */
358 mov sp,$28 /* set method pointer */
360 ldq pv,8($28) /* method call as in Java */
361 jmp ra,(pv) /* call JIT compiler */
363 lda pv,-64(ra) /* asm_calljavafunction-calljava_jit !!!!!*/
366 ldq ra,0(sp) /* restore return address */
367 ldq gp,24(sp) /* restore global pointer */
368 lda sp,32(sp) /* free stack space */
374 ldq gp,24(sp) /* restore global pointer */
376 jsr ra,builtin_throw_exception
377 ldq ra,0(sp) /* restore return address */
378 lda sp,32(sp) /* free stack space */
379 mov zero,v0 /* return NULL */
381 .end asm_calljavafunction
386 .ent asm_calljavafunction2
391 .quad 0 /* catch type all */
392 .quad calljava_xhandler2 /* handler pc */
393 .quad calljava_xhandler2 /* end pc */
394 .quad asm_calljavafunction2 /* start pc */
395 .long 1 /* extable size */
396 .long 0 /* PADDING */
397 .quad 0 /* line number table start */
398 .quad 0 /* line number table size */
399 .long 0 /* PADDING */
400 .long 0 /* fltsave */
401 .long 1 /* intsave */
404 .long 40 /* frame size */
405 .quad 0 /* method pointer (pointer to name) */
407 asm_calljavafunction2:
408 asm_calljavafunction2int:
409 asm_calljavafunction2long:
410 asm_calljavafunction2float:
411 asm_calljavafunction2double:
413 lda sp,-40(sp) /* allocate stack space */
414 stq ra,0(sp) /* save return address */
416 stq gp,8(sp) /* save global pointer */
418 stq a0,32(sp) /* save method pointer for compiler */
419 mov a3,t0 /* pointer to arg block */
420 mov a1,s6 /* arg count */
422 ble s6,calljava_argsloaded
424 ldq a0,offjniitem(t0)
425 ldt $f16,offjniitem(t0)
426 ble s6,calljava_argsloaded
428 ldq a1,offjniitem+sizejniblock*1(t0)
429 ldt $f17,offjniitem+sizejniblock*1(t0)
430 ble s6,calljava_argsloaded
432 ldq a2,offjniitem+sizejniblock*2(t0)
433 ldt $f18,offjniitem+sizejniblock*2(t0)
434 ble s6,calljava_argsloaded
436 ldq a3,offjniitem+sizejniblock*3(t0)
437 ldt $f19,offjniitem+sizejniblock*3(t0)
438 ble s6,calljava_argsloaded
440 ldq a4,offjniitem+sizejniblock*4(t0)
441 ldt $f20,offjniitem+sizejniblock*4(t0)
442 ble s6,calljava_argsloaded
444 ldq a5,offjniitem+sizejniblock*5(t0)
445 ldt $f21,offjniitem+sizejniblock*5(t0)
448 ble s6,calljava_nocopy
454 ldq t3,offjniitem+sizejniblock*6(t0)
457 lda t0,sizejniblock(t0)
459 bne t1,calljava_copyloop
462 lda v0,32(t4) /* pass pointer to method pointer via v0*/
464 lda $28,asm_call_jit_compiler /* fake virtual function call (2 instr) */
465 stq $28,16(t4) /* store function address */
466 lda $28,8(t4) /* set method pointer */
468 ldq pv,8($28) /* method call as in Java */
469 jmp ra,(pv) /* call JIT compiler */
471 lda pv,-200(ra) /* asm_calljavafunction-calljava_jit !!!*/
475 ldq ra,0(sp) /* restore return address */
476 ldq gp,8(sp) /* restore global pointer */
478 lda sp,40(sp) /* free stack space */
485 ldq gp,8(sp) /* restore global pointer */
487 jsr ra,builtin_throw_exception
488 ldq ra,0(sp) /* restore return address */
490 lda sp,40(sp) /* free stack space */
491 mov zero,v0 /* return NULL */
493 .end asm_calljavafunction2
496 /****************** function asm_call_jit_compiler *****************************
498 * invokes the compiler for untranslated JavaVM methods. *
500 * Register R0 contains a pointer to the method info structure (prepared *
501 * by createcompilerstub). Using the return address in R26 and the *
502 * offset in the LDA instruction or using the value in methodptr R28 the *
503 * patching address for storing the method address can be computed: *
505 * method address was either loaded using *
506 * M_LDQ (REG_PV, REG_PV, a) ; invokestatic/special ($27) *
507 * M_LDA (REG_PV, REG_RA, low) *
508 * M_LDAH(REG_PV, REG_RA, high) ; optional *
510 * M_LDQ (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($28) *
511 * in the static case the method pointer can be computed using the *
512 * return address and the lda function following the jmp instruction *
514 *******************************************************************************/
516 .ent asm_call_jit_compiler
518 asm_call_jit_compiler:
520 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
521 srl t8,16,t8 /* shift right register number $yy */
522 and t8,31,t8 /* isolate register number */
523 subl t8,28,t8 /* test for REG_METHODPTR */
525 ldl t8,0(ra) /* load instruction LDA PV,xxx(RA) */
527 sra t8,48,t8 /* isolate offset */
528 addq t8,ra,$28 /* compute update address */
529 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
530 srl t8,16,t8 /* isolate instruction code */
531 lda t8,-0x177b(t8) /* test for LDAH */
533 ldl t8,4(ra) /* load instruction LDAH PV,xxx(PV) */
534 sll t8,16,t8 /* compute high offset */
535 addl t8,0,t8 /* sign extend high offset */
536 addq t8,$28,$28 /* compute update address */
538 lda sp,-14*8(sp) /* reserve stack space */
540 SAVE_ARGUMENT_REGISTERS(0) /* save 6 int/6 float argument registers */
542 stq $28,12*8(sp) /* save method pointer */
543 stq ra,13*8(sp) /* save return address */
545 ldq a0,0(v0) /* pass 'methodinfo' pointer to */
546 jsr ra,jit_compile /* jit compiler */
549 RESTORE_ARGUMENT_REGISTERS(0) /* restore 6 int/6 float argument registers */
551 ldq $28,12*8(sp) /* load method pointer */
552 ldq ra,13*8(sp) /* load return address */
553 lda sp,14*8(sp) /* deallocate stack area */
555 beq v0,asm_call_jit_compiler_exception
557 ldl t8,-8(ra) /* load instruction LDQ PV,xxx($yy) */
559 sra t8,48,t8 /* isolate offset */
561 addq t8,$28,t8 /* compute update address via method pointer*/
562 stq v0,0(t8) /* save new method address there */
564 call_pal PAL_imb /* synchronise instruction cache */
566 mov v0,pv /* load method address into pv */
567 jmp zero,(pv) /* and call method. The method returns */
568 /* directly to the caller (ra). */
570 asm_call_jit_compiler_exception:
571 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
574 jsr ra,builtin_asm_get_exceptionptrptr
580 ldq xptr,0(v0) /* get the exception pointer */
581 stq zero,0(v0) /* clear the exception pointer */
584 br asm_handle_nat_exception
586 .end asm_call_jit_compiler
589 /**************** function asm_refillin_and_handle_exception *******************
591 * This function handles an exception. It does not use the usual calling *
592 * conventions. The exception is passed in REG_ITMP1 and the *
593 * pc from the exception raising position is passed in REG_ITMP2. *
594 * a0 contains the PV of the function causing the problem *
596 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
598 *******************************************************************************/
599 .ent asm_refillin_and_handle_exception
600 asm_refillin_and_handle_exception:
602 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
604 sra t0,48,t0 /* isolate offset */
605 addq t0,ra,pv /* compute update address */
606 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
607 srl t0,16,t0 /* isolate instruction code */
608 lda t0,-0x177b(t0) /* test for LDAH */
609 bne t0, asm_refillin_and_handle_exception_cont
610 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
611 sll t0,16,t0 /* compute high offset */
612 addl t0,0,t0 /* sign extend high offset */
613 addq t0,pv,pv /* compute update address */
615 asm_refillin_and_handle_exception_cont:
618 lda sp,-6*8(sp) /* prepare stackframe*/
619 stq pv,5*8(sp) /* store pv of caller */
620 stq xptr,4*8(sp) /*exception ptr*/
621 stq xpc,3*8(sp) /*address of failure*/
622 stq t0,2*8(sp) /*begin of java stack frame*/
623 stq pv,1*8(sp) /* store pv of caller */
624 stq zero,0*8(sp) /*builtin (invisible) function */
625 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
628 ldq a2,utf_void__java_lang_Throwable
629 ldq a1,utf_fillInStackTrace
631 ldq t1,offobjvftbl(t0)
633 jsr ra,class_resolvemethod
635 /* now we have the method */
640 jsr ra,asm_calljavafunction
644 jsr ra,asm_remove_native_stackinfo
653 br asm_handle_exception
655 .end asm_refillin_and_handle_exception
657 /****** function asm_throw_and_handle_arrayindexoutofbounds_exception **********
659 * This function handles an exception. It does not use the usual calling *
660 * conventions. The integer parameter is passed in REG_ITMP1 and the *
661 * pc from the exception raising position is passed in REG_ITMP2. *
663 * void asm_handle_arithmetic_exception (exceptionclass, exceptionpc); *
665 *******************************************************************************/
667 .ent asm_throw_and_handle_arrayindexoutofbounds_exception
669 asm_throw_and_handle_arrayindexoutofbounds_exception:
672 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
674 sra t0,48,t0 /* isolate offset */
675 addq t0,ra,pv /* compute update address */
676 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
677 srl t0,16,t0 /* isolate instruction code */
678 lda t0,-0x177b(t0) /* test for LDAH */
679 bne t0,asm_throw_and_handle_arrayindexoutofbounds_exception_cont
680 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
681 sll t0,16,t0 /* compute high offset */
682 addl t0,0,t0 /* sign extend high offset */
683 addq t0,pv,pv /* compute update address */
685 asm_throw_and_handle_arrayindexoutofbounds_exception_cont:
687 lda sp,-6*8(sp) /*prepare stackframe*/
688 stq pv,5*8(sp) /*pv of failure*/
689 stq itmp1,4*8(sp) /*int parameter of the exception*/
690 stq xpc,3*8(sp) /*address of failure */
691 stq t0,2*8(sp) /*store begin of java stack frame*/
692 stq pv,1*8(sp) /*store pv of caller in structure*/
693 stq zero,0*8(sp) /*builtin (invisible function)*/
695 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
698 ldq a0,6*8(sp) /*int of exception*/
699 jsr ra,new_arrayindexoutofboundsexception
702 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
704 jsr ra,asm_remove_native_stackinfo
710 br asm_handle_exception
712 .end asm_throw_and_handle_arrayindexoutofbounds_exception
715 /* asm_throw_and_handle_arithmetic_exception ***********************************
719 *******************************************************************************/
721 .ent asm_throw_and_handle_arithmetic_exception
723 asm_throw_and_handle_arithmetic_exception:
724 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
726 sra t0,48,t0 /* isolate offset */
727 addq t0,ra,pv /* compute update address */
728 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
729 srl t0,16,t0 /* isolate instruction code */
730 lda t0,-0x177b(t0) /* test for LDAH */
731 bne t0,asm_throw_and_handle_arithmetic_exception_cont
732 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
733 sll t0,16,t0 /* compute high offset */
734 addl t0,0,t0 /* sign extend high offset */
735 addq t0,pv,pv /* compute update address */
737 asm_throw_and_handle_arithmetic_exception_cont:
739 lda sp,-6*8(sp) /*prepare stackframe*/
740 stq pv,5*8(sp) /*pv of failure*/
741 stq itmp1,4*8(sp) /*exception string of the exception*/
742 stq xpc,3*8(sp) /*address of failure */
743 stq t0,2*8(sp) /*store begin of java stack frame*/
744 stq pv,1*8(sp) /*store pv of caller in structure*/
745 stq zero,0*8(sp) /*builtin (invisible function)*/
746 jsr ra,asm_prepare_native_stackinfo /* puts 2 additional quadwords on stack */
749 jsr ra,new_arithmeticexception
751 mov v0,itmp1 /*itmp1 is not touched in asm_remove_native_stackinfo*/
753 jsr ra,asm_remove_native_stackinfo
759 br asm_handle_exception
761 .end asm_throw_and_handle_arithmetic_exception
764 /* asm_throw_and_handle_exception **********************************************
768 *******************************************************************************/
770 .ent asm_throw_and_handle_nat_exception
772 asm_throw_and_handle_nat_exception:
774 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
776 sra t0,48,t0 /* isolate offset */
777 addq t0,ra,pv /* compute update address */
778 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
779 srl t0,16,t0 /* isolate instruction code */
780 lda t0,-0x177b(t0) /* test for LDAH */
781 bne t0,asm_throw_and_handle_exception
782 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
783 sll t0,16,t0 /* compute high offset */
784 addl t0,0,t0 /* sign extend high offset */
785 addq t0,pv,pv /* compute update address */
787 .aent asm_throw_and_handle_exception
789 asm_throw_and_handle_exception:
791 lda sp,-6*8(sp) /* prepare stackframe */
792 stq pv,5*8(sp) /* pv of failure */
793 stq xptr,4*8(sp) /* classname of the exception */
794 stq xpc,3*8(sp) /* address of failure */
795 stq t0,2*8(sp) /* store begin of java stack frame */
796 stq pv,1*8(sp) /* store pv of caller in structure */
797 stq zero,0*8(sp) /* builtin (invisible function) */
798 /* puts 2 additional quadwords on stack */
800 br ra,L_asm_throw_and_handle_exception_load_gp
801 L_asm_throw_and_handle_exception_load_gp:
802 ldgp gp,0(ra) /* load gp (it's not set correctly in jit) */
804 jsr ra,asm_prepare_native_stackinfo
807 ldq a0,6*8(sp) /* classname of exception */
811 mov v0,xptr /* xptr (itmp1) is not touched in */
812 /* asm_remove_native_stackinfo */
814 jsr ra,asm_remove_native_stackinfo
820 br asm_handle_exception
822 .end asm_throw_and_handle_nat_exception
825 /********************* function asm_handle_exception ***************************
827 * This function handles an exception. It does not use the usual calling *
828 * conventions. The exception pointer is passed in REG_ITMP1 and the *
829 * pc from the exception raising position is passed in REG_ITMP2. It searches *
830 * the local exception table for a handler. If no one is found, it unwinds *
831 * stacks and continues searching the callers. *
833 * void asm_handle_exception (exceptionptr, exceptionpc); *
835 *******************************************************************************/
837 .ent asm_handle_nat_exception
839 asm_handle_nat_exception:
840 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
842 sra t0,48,t0 /* isolate offset */
843 addq t0,ra,pv /* compute update address */
844 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
845 srl t0,16,t0 /* isolate instruction code */
846 lda t0,-0x177b(t0) /* test for LDAH */
847 bne t0,asm_handle_exception
848 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
849 sll t0,16,t0 /* compute high offset */
850 addl t0,0,t0 /* sign extend high offset */
851 addq t0,pv,pv /* compute update address */
853 .aent asm_handle_exception
855 asm_handle_exception:
856 lda sp,-18*8(sp) /* allocate stack */
857 stq t0,0*8(sp) /* save possible used registers */
858 stq t1,1*8(sp) /* also registers used by trace_exception */
876 lda t3,1(zero) /* set no unwind flag */
878 lda sp,-5*8(sp) /* allocate stack */
879 stq xptr,0*8(sp) /* save used register */
886 ldq a1,MethodPointer(pv)
891 br ra,ex_trace /* set ra for gp loading */
893 ldgp gp,0(ra) /* load gp */
894 jsr ra,builtin_trace_exception /* trace_exception(xptr,methodptr) */
896 ldq xptr,0*8(sp) /* restore used register */
901 lda sp,5*8(sp) /* deallocate stack */
903 ldl t0,ExTableSize(pv) /* t0 = exception table size */
904 beq t0,empty_table /* if empty table skip */
906 lda t1,ExTableStart(pv) /* t1 = start of exception table */
909 ldq t2,ExStartPC(t1) /* t2 = exception start pc */
910 cmple t2,xpc,t2 /* t2 = (startpc <= xpc) */
911 beq t2,ex_table_cont /* if (false) continue */
912 ldq t2,ExEndPC(t1) /* t2 = exception end pc */
913 cmplt xpc,t2,t2 /* t2 = (xpc < endpc) */
914 beq t2,ex_table_cont /* if (false) continue */
915 ldq a1,ExCatchType(t1) /* arg1 = exception catch type */
916 beq a1,ex_handle_it /* NULL catches everything */
918 ldl itmp3,offclassloaded(a1)
919 bne itmp3,L_class_loaded
921 subq sp,8*8,sp /* allocate stack */
922 stq t0,0*8(sp) /* save used register */
933 br ra,L_class_load_ra /* set ra for gp loading */
935 ldgp gp,0(ra) /* load gp */
936 jsr ra,load_class_bootstrap
938 ldq t0,0*8(sp) /* restore used register */
946 addq sp,8*8,sp /* deallocate stack */
949 ldl itmp3,offclasslinked(a1)
950 subq sp,8*8,sp /* allocate stack */
952 bne itmp3,L_class_linked
954 stq t0,0*8(sp) /* save used register */
964 br ra,L_class_link_ra /* set ra for gp loading */
966 ldgp gp,0(ra) /* load gp */
969 ldq t0,0*8(sp) /* restore used register */
981 ldq a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
982 ldq a1,offclassvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
983 ldl a0,offbaseval(a0) /* a0 = baseval(xptr) */
984 ldl v0,offbaseval(a1) /* a2 = baseval(catchtype) */
985 ldl a1,offdiffval(a1) /* a1 = diffval(catchtype) */
987 subl a0,v0,a0 /* a0 = baseval(xptr) - baseval(catchtype) */
988 cmpule a0,a1,v0 /* v0 = xptr is instanceof catchtype */
989 addq sp,8*8,sp /* deallocate stack */
990 beq v0,ex_table_cont /* if (false) continue */
993 ldq xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
995 beq t3,ex_jump /* if (!(no stack unwinding) skip */
997 ldq t0,0*8(sp) /* restore possible used registers */
998 ldq t1,1*8(sp) /* also registers used by trace_exception */
1015 lda sp,18*8(sp) /* deallocate stack */
1018 jmp zero,(xpc) /* jump to the handler */
1021 lda t1,ExEntrySize(t1) /* next exception table entry */
1022 subl t0,1,t0 /* decrement entry counter */
1023 bgt t0,ex_table_loop /* if (t0 > 0) next entry */
1026 beq t3,ex_already_cleared /* if here the first time, then */
1027 lda sp,18*8(sp) /* deallocate stack and */
1028 clr t3 /* clear the no unwind flag */
1030 ldl t0,IsSync(pv) /* t0 = SyncOffset */
1031 beq t0,no_monitor_exit /* if zero no monitorexit */
1033 #if defined(USE_THREADS)
1034 addq sp,t0,t0 /* add stackptr to Offset */
1035 ldq a0,-8(t0) /* load monitorexit pointer */
1037 lda sp,-7*8(sp) /* allocate stack */
1038 stq t0,0*8(sp) /* save used register */
1046 br ra,ex_mon_load /* set ra for gp loading */
1048 ldgp gp,0(ra) /* load gp */
1049 jsr ra,builtin_monitorexit/* builtin_monitorexit(objectptr) */
1051 ldq t0,0*8(sp) /* restore used register */
1058 lda sp,7*8(sp) /* deallocate stack */
1062 ldl t0,FrameSize(pv) /* t0 = frame size */
1063 addq sp,t0,sp /* unwind stack */
1064 mov sp,t0 /* t0 = pointer to save area */
1065 ldl t1,IsLeaf(pv) /* t1 = is leaf procedure */
1066 bne t1,ex_no_restore /* if (leaf) skip */
1067 ldq ra,-8(t0) /* restore ra */
1068 lda t0,-8(t0) /* t0-- */
1070 mov ra,xpc /* the new xpc is ra */
1071 ldl t1,IntSave(pv) /* t1 = saved int register count */
1072 br t2,ex_int1 /* t2 = current pc */
1074 lda t2,44(t2) /* lda t2,ex_int2-ex_int1(t2) !!!!!!!!!!!!! */
1075 negl t1,t1 /* negate register count */
1076 s4addq t1,t2,t2 /* t2 = ex_int_sav - 4 * register count */
1077 jmp zero,(t2) /* jump to save position */
1086 s8addq t1,t0,t0 /* t0 = t0 - 8 * register count */
1088 ldl t1,FltSave(pv) /* t1 = saved flt register count */
1089 br t2,ex_flt1 /* t2 = current pc */
1091 lda t2,48(t2) /* lda t2,ex_flt2-ex_flt1(t2) !!!!!!!!!!!!! */
1092 negl t1,t1 /* negate register count */
1093 s4addq t1,t2,t2 /* t2 = ex_flt_sav - 4 * register count */
1094 jmp zero,(t2) /* jump to save position */
1104 ldl t0,0(ra) /* load instruction LDA PV,xxx(RA) */
1106 sra t0,48,t0 /* isolate offset */
1107 addq t0,ra,pv /* compute update address */
1108 ldl t0,4(ra) /* load instruction LDAH PV,xxx(PV) */
1109 srl t0,16,t0 /* isolate instruction code */
1110 lda t0,-0x177b(t0) /* test for LDAH */
1111 bne t0,ex_stack_loop
1112 ldl t0,4(ra) /* load instruction LDAH PV,xxx(RA) */
1113 sll t0,16,t0 /* compute high offset */
1114 addl t0,0,t0 /* sign extend high offset */
1115 addq t0,pv,pv /* compute update address */
1118 .end asm_handle_nat_exception
1121 /* asm_wrapper_patcher *********************************************************
1126 24 return address into JIT code (patch position)
1127 16 machine code (which is patched back later)
1128 8 unresolved class/method/field reference
1129 0 patcher function pointer to call
1131 ATTENTION: itmp3 == gp! But we don't need gp do call the patcher function.
1133 *******************************************************************************/
1135 .ent asm_wrapper_patcher
1137 asm_wrapper_patcher:
1138 lda sp,-(12+27+4)*8(sp) /* create stack frame */
1140 SAVE_ARGUMENT_REGISTERS(0) /* save 6 int/6 float argument registers */
1141 SAVE_TEMPORARY_REGISTERS(12) /* save 11 int/16 float temporary registers */
1143 stq itmp1,(12+27+0)*8(sp) /* save itmp1 */
1144 stq itmp2,(12+27+1)*8(sp) /* save itmp2 */
1145 stq ra,(12+27+2)*8(sp) /* save method return address (for leafs) */
1146 stq pv,(12+27+3)*8(sp) /* save pv of calling java function */
1148 lda a0,(1+12+27+4)*8(sp) /* pass sp, skip patcher function pointer */
1149 ldq pv,(0+12+27+4)*8(sp) /* get function pointer */
1150 jmp ra,(pv) /* call the patcher function */
1153 RESTORE_ARGUMENT_REGISTERS(0) /* restore 6 int/6 float argument registers */
1154 RESTORE_TEMPORARY_REGISTERS(12)/* restore 11 integer temporary registers */
1156 ldq itmp1,(12+27+0)*8(sp) /* restore itmp1 */
1157 ldq itmp2,(12+27+1)*8(sp) /* restore itmp2 */
1158 ldq ra,(12+27+2)*8(sp) /* restore method return address (for leafs)*/
1159 ldq pv,(12+27+3)*8(sp) /* restore pv of calling java function */
1161 ldq itmp3,(3+12+27+4)*8(sp)/* get return address (into JIT code) */
1162 lda sp,(4+12+27+4)*8(sp) /* remove stack frame */
1164 beq v0,L_asm_wrapper_patcher_exception
1166 jmp zero,(itmp3) /* jump to new patched code */
1168 L_asm_wrapper_patcher_exception:
1169 mov itmp3,xpc /* return address into JIT code is xpc */
1171 br itmp1,L_asm_wrapper_patcher_exception_load_gp
1172 L_asm_wrapper_patcher_exception_load_gp:
1173 ldgp gp,0(itmp1) /* itmp3 == gp, load the current gp */
1175 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1177 stq xpc,0*8(sp) /* save return address (xpc) */
1180 jsr ra,builtin_asm_get_exceptionptrptr
1181 ldq xpc,0*8(sp) /* restore return address (xpc) */
1186 lda v0,_exceptionptr
1188 ldq xptr,0(v0) /* get the exception pointer */
1189 stq zero,0(v0) /* clear the exception pointer */
1190 br asm_handle_exception /* we have the pv of the calling java func. */
1192 .end asm_wrapper_patcher
1195 /************************ function asm_builtin_idiv ****************************
1197 * Does null check and calls idiv or throws an exception *
1199 *******************************************************************************/
1201 .ent asm_builtin_idiv
1206 beq a1,nb_idiv /* if (null) throw exception */
1207 jmp zero,(pv) /* else call builtin_idiv */
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_idiv
1217 /************************ function asm_builtin_ldiv ****************************
1219 * Does null check and calls ldiv or throws an exception *
1221 *******************************************************************************/
1223 .ent asm_builtin_ldiv
1228 beq a1,nb_ldiv /* if (null) throw exception */
1229 jmp zero,(pv) /* else call builtin_ldiv */
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_ldiv
1239 /************************ function asm_builtin_irem ****************************
1241 * Does null check and calls irem or throws an exception *
1243 *******************************************************************************/
1245 .ent asm_builtin_irem
1250 beq a1,nb_irem /* if (null) throw exception */
1251 jmp zero,(pv) /* else call builtin_irem */
1254 ldq xptr,string_java_lang_ArithmeticException_message
1255 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1256 br asm_throw_and_handle_arithmetic_exception
1258 .end asm_builtin_irem
1261 /************************ function asm_builtin_lrem ****************************
1263 * Does null check and calls lrem or throws an exception *
1265 *******************************************************************************/
1267 .ent asm_builtin_lrem
1272 beq a1,nb_lrem /* if (null) throw exception */
1273 jmp zero,(pv) /* else call builtin_lrem */
1276 ldq xptr,string_java_lang_ArithmeticException_message
1277 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1278 br asm_throw_and_handle_arithmetic_exception
1280 .end asm_builtin_lrem
1283 /******************* function asm_builtin_checkarraycast ***********************
1285 * Does the cast check and eventually throws an exception *
1287 *******************************************************************************/
1289 .ent asm_builtin_checkarraycast
1291 asm_builtin_checkarraycast:
1293 lda sp,-16(sp) /* allocate stack space */
1294 stq ra,0(sp) /* save return address */
1295 stq a0,8(sp) /* save object pointer */
1296 jsr ra,builtin_checkarraycast /* builtin_checkarraycast */
1298 beq v0,nb_carray_throw /* if (false) throw exception */
1299 ldq ra,0(sp) /* restore return address */
1300 ldq v0,8(sp) /* return object pointer */
1301 lda sp,16(sp) /* free stack space */
1308 ldq xptr,string_java_lang_ClassCastException
1309 jmp zero,asm_throw_and_handle_nat_exception
1311 ldq a0,string_java_lang_ClassCastException
1312 jsr ra,new_exception
1316 ldq ra,0(sp) /* restore return address */
1317 lda sp,16(sp) /* free stack space */
1318 lda xpc,-4(ra) /* faulting address is return adress - 4*/
1319 br asm_handle_nat_exception
1322 .end asm_builtin_checkarraycast
1325 /******************* function asm_builtin_aastore ******************************
1327 * Does the cast check and eventually throws an exception *
1329 *******************************************************************************/
1331 .ent asm_builtin_aastore
1333 asm_builtin_aastore:
1335 beq a0,nb_aastore_null /* if null pointer throw exception */
1336 ldl t0,offarraysize(a0) /* load size */
1337 lda sp,-24(sp) /* allocate stack space */
1338 stq ra,0(sp) /* save return address */
1339 s8addq a1,a0,t1 /* add index*8 to arrayref */
1340 cmpult a1,t0,t0 /* do bound check */
1341 beq t0,nb_aastore_bound /* if out of bounds throw exception */
1342 mov a2,a1 /* object is second argument */
1343 stq t1,8(sp) /* save store position */
1344 stq a1,16(sp) /* save object */
1345 jsr ra,builtin_canstore /* builtin_canstore(arrayref,object) */
1347 ldq ra,0(sp) /* restore return address */
1348 ldq a0,8(sp) /* restore store position */
1349 ldq a1,16(sp) /* restore object */
1350 lda sp,24(sp) /* free stack space */
1351 beq v0,nb_aastore_throw /* if (false) throw exception */
1352 stq a1,offobjarrdata(a0) /* store objectptr in array */
1356 ldq xptr,string_java_lang_NullPointerException
1358 jmp zero,asm_throw_and_handle_nat_exception
1360 subq sp,8,sp /* allocate stack space */
1361 stq ra,0(sp) /* save return address */
1362 jsr ra,new_nullpointerexception
1368 mov ra,xpc /* faulting address is return adress */
1369 br asm_handle_nat_exception
1376 jmp zero,asm_throw_and_handle_arrayindexoutofbounds_exception
1378 ldq a0,string_java_lang_ArrayIndexOutOfBoundsException
1379 jsr ra,new_exception_int /* a1 already contains the index */
1383 ldq ra,0(sp) /* restore return address */
1384 lda sp,24(sp) /* free stack space */
1385 mov ra,xpc /* faulting address is return adress */
1386 br asm_handle_nat_exception
1390 ldq xptr,string_java_lang_ArrayStoreException
1391 jmp zero,asm_throw_and_handle_nat_exception
1393 subq sp,8,sp /* allocate stack space */
1394 stq ra,0(sp) /* save return address */
1395 jsr ra,new_arraystoreexception
1401 mov ra,xpc /* faulting address is return adress */
1402 br asm_handle_nat_exception
1404 .end asm_builtin_aastore
1407 /******************* function asm_initialize_thread_stack **********************
1409 * initialized a thread stack *
1411 *******************************************************************************/
1413 .ent asm_initialize_thread_stack
1415 asm_initialize_thread_stack:
1436 .end asm_initialize_thread_stack
1439 /******************* function asm_perform_threadswitch *************************
1441 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1443 * performs a threadswitch *
1445 *******************************************************************************/
1447 .ent asm_perform_threadswitch
1449 asm_perform_threadswitch:
1490 .end asm_perform_threadswitch
1493 /********************* function asm_switchstackandcall *************************
1495 * void *asm_switchstackandcall (void *stack, void *func, void **stacktopsave, *
1498 * Switches to a new stack, calls a function and switches back. *
1499 * a0 new stack pointer *
1500 * a1 function pointer *
1501 * a2 pointer to variable where stack top should be stored *
1502 * a3 pointer to user data, is passed to the function *
1504 *******************************************************************************/
1507 .ent asm_switchstackandcall
1509 asm_switchstackandcall:
1510 lda a0,-2*8(a0) /* allocate new stack */
1511 stq ra,0(a0) /* save return address on new stack */
1512 stq sp,1*8(a0) /* save old stack pointer on new stack */
1513 stq sp,0(a2) /* save old stack pointer to variable */
1514 mov a0,sp /* switch to new stack */
1516 mov a1,pv /* load function pointer */
1517 mov a3,a0 /* pass pointer */
1518 jmp ra,(pv) /* and call function */
1520 ldq ra,0(sp) /* load return address */
1521 ldq sp,1*8(sp) /* switch to old stack */
1523 jmp zero,(ra) /* return */
1525 .end asm_switchstackandcall
1527 .ent asm_getclassvalues_atomic
1529 asm_getclassvalues_atomic:
1532 ldl t0,offbaseval(a0)
1533 ldl t1,offdiffval(a0)
1534 ldl t2,offbaseval(a1)
1536 stl t0,offcast_super_baseval(a2)
1537 stl t1,offcast_super_diffval(a2)
1538 stl t2,offcast_sub_baseval(a2)
1541 .end asm_getclassvalues_atomic
1545 asm_criticalsections:
1546 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1549 .quad _crit_restart1
1552 .quad _crit_restart2
1557 .ent asm_prepare_native_stackinfo
1558 asm_prepare_native_stackinfo:
1561 jsr ra,builtin_asm_get_stackframeinfo
1569 .end asm_prepare_native_stackinfo
1571 .ent asm_remove_native_stackinfo
1572 asm_remove_native_stackinfo:
1578 .end asm_remove_native_stackinfo
1581 * These are local overrides for various environment variables in Emacs.
1582 * Please do not remove this and leave it at the end of the file, where
1583 * Emacs will automagically detect them.
1584 * ---------------------------------------------------------------------
1587 * indent-tabs-mode: t