1 /* -*- mode: asm; tab-width: 4 -*- */
2 /****************************** asmpart.c **************************************
4 * is an assembly language file, but called .c to fake the preprocessor. *
5 * It contains the Java-C interface functions for Alpha processors. *
7 * Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst *
9 * See file COPYRIGHT for information on usage and disclaimer of warranties *
11 * Authors: Andreas Krall EMAIL: cacao@complang.tuwien.ac.at *
13 * Last Change: 1998/11/23 *
15 *******************************************************************************/
109 #define aaddiu daddiu
116 #define MethodPointer -8
117 #define FrameSize -12
122 #define ExTableSize -32
123 #define ExTableStart -32
125 #define ExEntrySize -32
128 #define ExHandlerPC -24
129 #define ExCatchType -32
136 /********************* exported functions and variables ***********************/
138 .globl has_no_x_instr_set
139 .globl synchronize_caches
140 .globl asm_calljavafunction
141 .globl asm_call_jit_compiler
142 .globl asm_dumpregistersandcall
143 .globl asm_handle_exception
144 .globl asm_handle_nat_exception
145 .globl asm_builtin_checkarraycast
146 .globl asm_builtin_checkcast
147 .globl asm_builtin_aastore
148 .globl asm_builtin_monitorenter
149 .globl asm_builtin_monitorexit
150 .globl asm_builtin_idiv
151 .globl asm_builtin_irem
152 .globl asm_builtin_ldiv
153 .globl asm_builtin_lrem
154 .globl asm_perform_threadswitch
155 .globl asm_initialize_thread_stack
156 .globl asm_switchstackandcall
159 /*************************** imported functions *******************************/
162 .globl builtin_monitorexit
163 .globl builtin_throw_exception
164 .globl builtin_trace_exception
165 .globl class_java_lang_Object
168 /*********************** function has_no_x_instr_set ***************************
170 * determines if the byte support instruction set (21164a and higher) *
173 *******************************************************************************/
175 .ent has_no_x_instr_set
178 move v0,zero /* result code 0 (not used for MIPS) */
181 .end has_no_x_instr_set
184 /********************* function synchronize_caches ****************************/
186 .ent synchronize_caches
189 /* li a0,BCACHE */ /* flush both caches */
190 /* li v0,SYS_cacheflush */ /* Syscall number for cacheflush() */
191 /* syscall */ /* call cacheflush() */
194 .end synchronize_caches
199 /********************* function asm_calljavafunction ****************************
201 * This function calls a Java-method (which possibly needs compilation) *
202 * with up to 4 address parameters. *
204 * This functions calls the JIT-compiler which eventually translates the *
205 * method into machine code. *
207 * A possibly throwed exception will be returned to the caller as function *
208 * return value, so the java method cannot return a fucntion value (this *
209 * function usually calls 'main' and '<clinit>' which do not return a *
213 * javaobject_header *asm_calljavafunction (methodinfo *m, *
214 * void *arg1, void *arg2, void *arg3, void *arg4); *
216 *******************************************************************************/
218 .ent asm_calljavafunction
222 .ascii "calljavafunction\0\0"
225 .dword 0 /* catch type all */
226 .dword calljava_xhandler /* handler pc */
227 .dword calljava_xhandler /* end pc */
228 .dword asm_calljavafunction /* start pc */
229 .word 1 /* extable size */
230 .word 0 /* fltsave */
231 .word 0 /* intsave */
234 .word 80 /* frame size */
235 .dword 0 /* method pointer (pointer to name) */
237 asm_calljavafunction:
239 aaddiu sp,sp,-10*8 /* allocate stack space */
240 sd ra,0(sp) /* save return address */
244 sd pv,3*8(sp) /* procedure vector */
250 sdc1 fss0,4*8(sp) /* save non JavaABI saved flt registers */
256 sd a0,2*8(sp) /* save method pointer for compiler */
257 aaddiu itmp1,sp,16 /* pass pointer to methodptr via itmp1 */
259 move a0,a1 /* pass the remaining parameters */
264 ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
265 ast mptr,1*8(sp) /* store function address */
266 move mptr,sp /* set method pointer */
270 ald pv,1*8(mptr) /* method call as in Java */
271 jalr pv /* call JIT compiler */
273 aaddiu pv,ra,-23*4 /* recompute procedure vector */
274 move v0,zero /* clear return value (exception ptr) */
280 ld ra,0(sp) /* restore return address */
281 ld pv,3*8(sp) /* restore procedure vector */
283 ldc1 fss0,4*8(sp) /* restore non JavaABI saved flt regs */
289 aaddiu sp,sp,10*8 /* free stack space */
295 jal builtin_throw_exception
298 .end asm_calljavafunction
303 /****************** function asm_call_jit_compiler *****************************
305 * invokes the compiler for untranslated JavaVM methods. *
307 * Register REG_ITEMP1 contains a pointer to the method info structure *
308 * (prepared by createcompilerstub). Using the return address in R31 and the *
309 * offset in the LDA instruction or using the value in methodptr R25 the *
310 * patching address for storing the method address can be computed: *
312 * method address was either loaded using *
313 * M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
314 * M_JSR (REG_RA, REG_PV); *
316 * M_LDA (REG_PV, REG_RA, val) *
318 * M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
319 * M_JSR (REG_RA, REG_PV); *
321 * in the static case the method pointer can be computed using the *
322 * return address and the lda function following the jmp instruction *
324 *******************************************************************************/
327 .ent asm_call_jit_compiler
328 asm_call_jit_compiler:
330 lw t0,-12(ra) /* load instruction LD PV,xxx($y) */
331 srl t0,t0,21 /* shift right register number $y */
332 and t0,t0,31 /* isolate register number */
333 addiu t0,t0,-mptrreg /* test for REG_METHODPTR */
336 lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
338 sra t0,t0,16 /* isolate offset */
339 aaddu mptr,t0,ra /* compute update address */
343 aaddiu sp,sp,-18*8 /* allocate stack space */
344 sd a0,0*8(sp) /* save all argument registers */
345 sd a1,1*8(sp) /* they could be used by method */
360 sd mptr,16*8(sp) /* save method pointer */
361 sd ra,17*8(sp) /* save return address */
363 ald a0,0(itmp1) /* pass 'methodinfo' pointer to */
364 jal jit_compile /* jit compiler */
366 ld a0,0*8(sp) /* restore argument registers */
367 ld a1,1*8(sp) /* they could be used by method */
382 ld mptr,16*8(sp) /* restore method pointer */
383 ld ra,17*8(sp) /* restore return address */
384 aaddiu sp,sp,18*8 /* deallocate stack area */
386 lw t0,-12(ra) /* load instruction LDQ PV,xxx($yy) */
388 sra t0,t0,16 /* isolate offset */
390 aaddu t0,t0,mptr /* compute update address via method pointer*/
391 ast v0,0(t0) /* save new method address there */
393 move pv,v0 /* move method address into pv */
395 jr pv /* and call method. The method returns */
396 /* directly to the caller (ra). */
398 .end asm_call_jit_compiler
401 /****************** function asm_dumpregistersandcall **************************
403 * This funtion saves all callee saved (address) registers and calls the *
404 * function which is passed as parameter. *
406 * This function is needed by the garbage collector, which needs to access *
407 * all registers which are stored on the stack. Unused registers are *
408 * cleared to avoid interferances with the GC. *
410 * void asm_dumpregistersandcall (functionptr f); *
412 *******************************************************************************/
414 .ent asm_dumpregistersandcall
415 asm_dumpregistersandcall:
416 aaddiu sp,sp,-10*8 /* allocate stack */
417 sd ra,0(sp) /* save return address */
419 sd s0,1*8(sp) /* save all callee saved registers */
430 jalr itmp3 /* and call function */
432 ld ra,0(sp) /* restore return address */
433 aaddiu sp,sp,10*8 /* deallocate stack */
436 .end asm_dumpregistersandcall
439 /********************* function asm_handle_exception ***************************
441 * This function handles an exception. It does not use the usual calling *
442 * conventions. The exception pointer is passed in REG_ITMP1 and the *
443 * pc from the exception raising position is passed in REG_ITMP2. It searches *
444 * the local exception table for a handler. If no one is found, it unwinds *
445 * stacks and continues searching the callers. *
447 * void asm_handle_exception (exceptionptr, exceptionpc); *
449 *******************************************************************************/
451 .ent asm_handle_nat_exception
452 asm_handle_nat_exception:
454 lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
456 sra t0,t0,16 /* isolate offset */
457 aaddu pv,t0,ra /* compute update address */
459 .aent asm_handle_exception
460 asm_handle_exception:
462 aaddiu sp,sp,-14*8 /* allocate stack */
463 sd v0,0*8(sp) /* save possible used registers */
464 sd t0,1*8(sp) /* also registers used by trace_exception */
478 addu t3,zero,1 /* set no unwind flag */
480 aaddiu sp,sp,-6*8 /* allocate stack */
481 sd xptr,0*8(sp) /* save used registers */
488 ald a1,MethodPointer(pv)
491 jal builtin_trace_exception /* trace_exception(xptr,methodptr) */
493 ld xptr,0*8(sp) /* restore used register */
498 aaddiu sp,sp,6*8 /* deallocate stack */
500 lw t0,ExTableSize(pv) /* t0 = exception table size */
501 beqz t0,empty_table /* if empty table skip */
502 aaddiu t1,pv,ExTableStart /* t1 = start of exception table */
505 ald t2,ExStartPC(t1) /* t2 = exception start pc */
506 slt t2,t2,xpc /* t2 = (xpc < startpc) */
507 beqz t2,ex_table_cont /* if (true) continue */
508 ald t2,ExEndPC(t1) /* t2 = exception end pc */
509 slt t2,t2,xpc /* t2 = (xpc < endpc) */
510 bnez t2,ex_table_cont /* if (false) continue */
511 ald a1,ExCatchType(t1) /* arg1 = exception catch type */
512 beqz a1,ex_handle_it /* NULL catches everything */
514 ald a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
515 ald a1,offobjvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
516 lw a0,offbaseval(a0) /* a0 = baseval(xptr) */
517 lw v0,offbaseval(a1) /* a2 = baseval(catchtype) */
518 lw a1,offdiffval(a1) /* a1 = diffval(catchtype) */
519 subu a0,a0,v0 /* a0 = baseval(xptr) - baseval(catchtype) */
520 sltu v0,a1,a0 /* v0 = xptr is instanceof catchtype */
521 bnez v0,ex_table_cont /* if (false) continue */
525 ald xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
527 beqz t3,ex_jump /* if (!(no stack unwinding) skip */
529 ld v0,0*8(sp) /* restore possible used registers */
530 ld t0,1*8(sp) /* also registers used by trace_exception */
544 aaddiu sp,sp,14*8 /* deallocate stack */
547 jr xpc /* jump to the handler */
550 aaddiu t1,t1,ExEntrySize /* next exception table entry */
551 addiu t0,t0,-1 /* decrement entry counter */
552 bgtz t0,ex_table_loop /* if (t0 > 0) next entry */
555 beqz t3,ex_already_cleared /* if here the first time, then */
556 aaddiu sp,sp,14*8 /* deallocate stack and */
557 move t3,zero /* clear the no unwind flag */
559 lw t0,IsSync(pv) /* t0 = SyncOffset */
560 beqz t0,no_monitor_exit /* if zero no monitorexit */
561 aaddu t0,sp,t0 /* add stackptr to Offset */
562 ald a0,-8(t0) /* load monitorexit pointer */
564 aaddiu sp,sp,-8*8 /* allocate stack */
565 sd t0,0*8(sp) /* save used register */
573 jal builtin_monitorexit /* builtin_monitorexit(objectptr) */
575 ld t0,0*8(sp) /* restore used register */
582 aaddiu sp,sp,8*8 /* deallocate stack */
585 lw t0,FrameSize(pv) /* t0 = frame size */
586 aaddu sp,sp,t0 /* unwind stack */
587 move t0,sp /* t0 = pointer to save area */
588 lw t1,IsLeaf(pv) /* t1 = is leaf procedure */
589 bnez t1,ex_no_restore /* if (leaf) skip */
590 ld ra,-8(t0) /* restore ra */
591 aaddiu t0,t0,-8 /* t0-- */
593 move xpc,ra /* the new xpc is ra */
594 lw t1,IntSave(pv) /* t1 = saved int register count */
595 ala t2,ex_int2 /* t2 = current pc */
596 sll t1,t1,2 /* t1 = register count * 4 */
597 asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
598 jr t2 /* jump to save position */
608 sll t1,t1,1 /* t1 = register count * 4 * 2 */
609 asubu t0,t0,t1 /* t0 = t0 - 8 * register count */
611 lw t1,FltSave(pv) /* t1 = saved flt register count */
612 ala t2,ex_flt2 /* t2 = current pc */
613 sll t1,t1,2 /* t1 = register count * 4 */
614 asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
615 jr t2 /* jump to save position */
621 lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
623 sra t0,t0,16 /* isolate offset */
624 aaddu pv,t0,ra /* compute update address */
627 .end asm_handle_nat_exception
630 /********************* function asm_builtin_monitorenter ***********************
632 * Does null check and calls monitorenter or throws an exception *
634 *******************************************************************************/
636 .ent asm_builtin_monitorenter
637 asm_builtin_monitorenter:
639 beqz a0,nb_monitorenter /* if (null) throw exception */
640 ala t9,builtin_monitorenter /* else call builtin_monitorenter */
644 ald xptr,proto_java_lang_NullPointerException
645 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
646 b asm_handle_nat_exception
647 .end asm_builtin_monitorenter
650 /********************* function asm_builtin_monitorexit ************************
652 * Does null check and calls monitorexit or throws an exception *
654 *******************************************************************************/
656 .ent asm_builtin_monitorexit
657 asm_builtin_monitorexit:
659 beqz a0,nb_monitorexit /* if (null) throw exception */
660 ala t9,builtin_monitorexit /* else call builtin_monitorexit */
664 ald xptr,proto_java_lang_NullPointerException
665 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
666 b asm_handle_nat_exception
667 .end asm_builtin_monitorexit
670 /************************ function asm_builtin_idiv ****************************
672 * Does null check and calls idiv or throws an exception *
674 *******************************************************************************/
676 .ent asm_builtin_idiv
679 beqz a1,nb_idiv /* if (null) throw exception */
680 ala itmp3,builtin_idiv /* else call builtin_idiv */
684 ald xptr,proto_java_lang_ArithmeticException
685 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
686 b asm_handle_nat_exception
687 .end asm_builtin_idiv
690 /************************ function asm_builtin_ldiv ****************************
692 * Does null check and calls ldiv or throws an exception *
694 *******************************************************************************/
696 .ent asm_builtin_ldiv
699 beqz a1,nb_ldiv /* if (null) throw exception */
700 ala itmp3,builtin_ldiv /* else call builtin_ldiv */
704 ald xptr,proto_java_lang_ArithmeticException
705 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
706 b asm_handle_nat_exception
707 .end asm_builtin_ldiv
710 /************************ function asm_builtin_irem ****************************
712 * Does null check and calls irem or throws an exception *
714 *******************************************************************************/
716 .ent asm_builtin_irem
719 beqz a1,nb_irem /* if (null) throw exception */
720 ala t9,builtin_irem /* else call builtin_irem */
724 ald xptr,proto_java_lang_ArithmeticException
725 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
726 b asm_handle_nat_exception
727 .end asm_builtin_irem
730 /************************ function asm_builtin_lrem ****************************
732 * Does null check and calls lrem or throws an exception *
734 *******************************************************************************/
736 .ent asm_builtin_lrem
739 beqz a1,nb_lrem /* if (null) throw exception */
740 ala t9,builtin_lrem /* else call builtin_lrem */
744 ald xptr,proto_java_lang_ArithmeticException
745 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
746 b asm_handle_nat_exception
747 .end asm_builtin_lrem
750 /******************* function asm_builtin_checkarraycast ***********************
752 * Does the cast check and eventually throws an exception *
754 *******************************************************************************/
756 .ent asm_builtin_checkarraycast
757 asm_builtin_checkarraycast:
759 aaddiu sp,sp,-16 /* allocate stack space */
760 sd ra,0(sp) /* save return address */
761 sd a0,8(sp) /* save object pointer */
762 jal builtin_checkarraycast /* builtin_checkarraycast */
763 beqz v0,nb_carray_throw /* if (false) throw exception */
764 ld ra,0(sp) /* restore return address */
765 ld v0,8(sp) /* return object pointer */
766 aaddiu sp,sp,16 /* deallocate stack */
770 ald xptr,proto_java_lang_ClassCastException
771 ld ra,0(sp) /* restore return address */
772 aaddiu sp,sp,16 /* free stack space */
773 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
774 b asm_handle_nat_exception
775 .end asm_builtin_checkarraycast
778 /********************* function asm_builtin_checkcast **************************
780 * Does the cast check and eventually throws an exception *
782 *******************************************************************************/
784 .ent asm_builtin_checkcast
785 asm_builtin_checkcast:
787 aaddiu sp,sp,-16 /* allocate stack space */
788 sd ra,0(sp) /* save return address */
789 sd a0,8(sp) /* save object pointer */
790 jal builtin_checkcast /* builtin_checkcast */
791 beqz v0,nb_ccast_throw /* if (false) throw exception */
792 ld ra,0(sp) /* restore return address */
793 ld v0,8(sp) /* return object pointer */
794 aaddiu sp,sp,16 /* deallocate stack */
798 ald xptr,proto_java_lang_ClassCastException
799 ld ra,0(sp) /* restore return address */
800 aaddiu sp,sp,16 /* free stack space */
801 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
802 b asm_handle_nat_exception
803 .end asm_builtin_checkcast
806 /******************* function asm_builtin_aastore ******************************
808 * Does the cast check and eventually throws an exception *
809 * a0 = arrayref, a1 = index, a2 = value *
811 *******************************************************************************/
813 .ent asm_builtin_aastore
816 beqz a0,nb_aastore_null /* if null pointer throw exception */
817 lw t0,offarraysize(a0) /* load size */
818 aaddiu sp,sp,-32 /* allocate stack space */
819 sd ra,0(sp) /* save return address */
820 asll t1,a1,ashift /* add index*8 to arrayref */
821 aaddu t1,a0,t1 /* add index * ashift to arrayref */
822 sltu t0,a1,t0 /* do bound check */
823 beqz t0,nb_aastore_bound /* if out of bounds throw exception */
824 move a1,a2 /* object is second argument */
825 sd t1,8(sp) /* save store position */
826 sd a1,16(sp) /* save object */
827 jal builtin_canstore /* builtin_canstore(arrayref,object) */
828 ld ra,0(sp) /* restore return address */
829 ld a0,8(sp) /* restore store position */
830 ld a1,16(sp) /* restore object */
831 aaddiu sp,sp,32 /* free stack space */
832 beqz v0,nb_aastore_throw /* if (false) throw exception */
833 ast a1,offobjarrdata(a0) /* store objectptr in array */
837 ald xptr,proto_java_lang_NullPointerException
838 move xpc,ra /* faulting address is return adress */
839 b asm_handle_nat_exception
842 ald xptr,proto_java_lang_ArrayIndexOutOfBoundsException
843 aaddiu sp,sp,32 /* free stack space */
844 move xpc,ra /* faulting address is return adress */
845 b asm_handle_nat_exception
848 ald xptr,proto_java_lang_ArrayStoreException
849 move xpc,ra /* faulting address is return adress */
850 b asm_handle_nat_exception
852 .end asm_builtin_aastore
855 /******************* function asm_initialize_thread_stack **********************
857 * u1* asm_initialize_thread_stack (void *func, u1 *stack); *
859 * initialize a thread stack *
861 *******************************************************************************/
863 .ent asm_initialize_thread_stack
864 asm_initialize_thread_stack:
866 aaddiu a1,a1,-14*8 /* allocate save area */
867 sd zero, 0*8(a1) /* s0 initalize thread area */
868 sd zero, 1*8(a1) /* s1 */
869 sd zero, 2*8(a1) /* s2 */
870 sd zero, 3*8(a1) /* s3 */
871 sd zero, 4*8(a1) /* s4 */
872 sd zero, 5*8(a1) /* s5 */
873 sd zero, 6*8(a1) /* s6 */
874 sd zero, 7*8(a1) /* s7 */
875 sd zero, 8*8(a1) /* s8 */
876 sd zero, 9*8(a1) /* fs0 */
877 sd zero,10*8(a1) /* fs1 */
878 sd zero,11*8(a1) /* fs2 */
879 sd zero,12*8(a1) /* fs3 */
883 .end asm_initialize_thread_stack
886 /******************* function asm_perform_threadswitch *************************
888 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
890 * performs a threadswitch *
892 *******************************************************************************/
894 .ent asm_perform_threadswitch
895 asm_perform_threadswitch:
897 aaddiu sp,sp,-14*8 /* allocate new stack */
898 sd s0, 0*8(sp) /* save saved registers of old thread */
912 ast sp,0(a0) /* save old stack pointer */
913 ast sp,0(a2) /* stackTop = old stack pointer */
914 ald sp,0(a1) /* load new stack pointer */
915 ld s0, 0*8(sp) /* load saved registers of new thread */
929 aaddiu sp,sp,14*8 /* deallocate new stack */
932 .end asm_perform_threadswitch
935 /********************* function asm_switchstackandcall *************************
937 * void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
939 * Switches to a new stack, calls a function and switches back. *
940 * a0 new stack pointer *
941 * a1 function pointer *
942 * a2 pointer to variable where stack top should be stored *
944 *******************************************************************************/
947 .ent asm_switchstackandcall
948 asm_switchstackandcall:
949 aaddiu a0,a0,-16 /* allocate new stack */
950 sd ra,0(a0) /* save return address on new stack */
951 sd sp,8(a0) /* save old stack pointer on new stack */
952 sd sp,0(a2) /* save old stack pointer to variable */
953 move sp,a0 /* switch to new stack */
956 jalr itmp3 /* and call function */
958 ld ra,0(sp) /* load return address */
959 ld sp,8(sp) /* switch to old stack */
963 .end asm_switchstackandcall