1 /* vm/jit/mips/asmpart.S - Java-C interface functions for mips
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
29 $Id: asmpart.S 1735 2004-12-07 14:33:27Z twisti $
35 #include "vm/jit/mips/offsets.h"
36 #include "vm/jit/mips/asmoffsets.h"
129 #define aaddiu daddiu
141 /********************* exported functions and variables ***********************/
143 .globl asm_calljavafunction
144 .globl asm_calljavafunction2
145 .globl asm_calljavafunction2long
146 .globl asm_calljavafunction2double
147 .globl asm_call_jit_compiler
148 .globl asm_dumpregistersandcall
149 .globl asm_handle_exception
150 .globl asm_handle_nat_exception
151 .globl asm_check_clinit
152 .globl asm_builtin_checkarraycast
153 .globl asm_builtin_checkcast
154 .globl asm_builtin_aastore
155 .globl asm_builtin_monitorenter
156 .globl asm_builtin_monitorexit
157 .globl asm_builtin_idiv
158 .globl asm_builtin_irem
159 .globl asm_builtin_ldiv
160 .globl asm_builtin_lrem
161 .globl asm_perform_threadswitch
162 .globl asm_initialize_thread_stack
163 .globl asm_switchstackandcall
164 .globl asm_builtin_trace
165 .globl asm_builtin_exittrace
166 .globl asm_getclassvalues_atomic
167 .globl asm_criticalsections
169 .globl compare_and_swap
172 /*************************** imported functions *******************************/
176 .globl builtin_monitorexit
177 .globl builtin_throw_exception
178 .globl builtin_trace_exception
179 .globl class_java_lang_Object
182 /********************* function asm_calljavafunction ***************************
184 * This function calls a Java-method (which possibly needs compilation) *
185 * with up to 4 address parameters. *
187 * This functions calls the JIT-compiler which eventually translates the *
188 * method into machine code. *
190 * A possibly throwed exception will be returned to the caller as function *
191 * return value, so the java method cannot return a fucntion value (this *
192 * function usually calls 'main' and '<clinit>' which do not return a *
196 * javaobject_header *asm_calljavafunction (methodinfo *m, *
197 * void *arg1, void *arg2, void *arg3, void *arg4); *
199 *******************************************************************************/
201 .ent asm_calljavafunction
206 .dword 0 /* catch type all */
207 .dword calljava_xhandler /* handler pc */
208 .dword calljava_xhandler /* end pc */
209 .dword asm_calljavafunction /* start pc */
210 .word 1 /* extable size */
211 .word 0 /* fltsave */
212 .word 0 /* intsave */
215 .word 10*8 /* frame size */
216 .dword 0 /* method pointer (pointer to name) */
218 asm_calljavafunction:
219 aaddiu sp,sp,-10*8 /* allocate stack space */
220 sd ra,0(sp) /* save return address */
224 sd pv,3*8(sp) /* procedure vector */
230 sdc1 fss0,4*8(sp) /* save non JavaABI saved flt registers */
236 sd a0,2*8(sp) /* save method pointer for compiler */
237 aaddiu itmp1,sp,16 /* pass pointer to methodptr via itmp1 */
239 move a0,a1 /* pass the remaining parameters */
244 ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
245 ast mptr,1*8(sp) /* store function address */
246 move mptr,sp /* set method pointer */
250 ald pv,1*8(mptr) /* method call as in Java */
251 jalr pv /* call JIT compiler */
253 aaddiu pv,ra,-23*4 /* recompute procedure vector */
255 move v0,zero /* clear return value (exception ptr) */
261 ld ra,0(sp) /* restore return address */
262 ld pv,3*8(sp) /* restore procedure vector */
264 ldc1 fss0,4*8(sp) /* restore non JavaABI saved flt regs */
271 aaddiu sp,sp,10*8 /* free stack space */
277 jal builtin_throw_exception
280 .end asm_calljavafunction
283 .ent asm_calljavafunction2
288 .dword 0 /* catch type all */
289 .dword calljava_xhandler2 /* handler pc */
290 .dword calljava_xhandler2 /* end pc */
291 .dword asm_calljavafunction2 /* start pc */
292 .word 1 /* extable size */
293 .word 0 /* fltsave */
294 .word 1 /* intsave */
297 .word 12*8 /* frame size */
298 .dword 0 /* method pointer (pointer to name) */
300 asm_calljavafunction2:
301 asm_calljavafunction2double:
302 asm_calljavafunction2long:
303 aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
304 sd ra,0(sp) /* save return address */
308 sd pv,1*8(sp) /* procedure vector */
315 sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
321 sd a0,4*8(sp) /* save method pointer for compiler */
325 blez s7,calljava_argsloaded
326 ald a0,offjniitem(t0)
327 ldc1 fa0,offjniitem(t0)
329 blez s7,calljava_argsloaded
331 ald a1,offjniitem+sizejniblock*1(t0)
332 ldc1 fa1,offjniitem+sizejniblock*1(t0)
334 blez s7,calljava_argsloaded
336 ald a2,offjniitem+sizejniblock*2(t0)
337 ldc1 fa2,offjniitem+sizejniblock*2(t0)
339 blez s7,calljava_argsloaded
341 ald a3,offjniitem+sizejniblock*3(t0)
342 ldc1 fa3,offjniitem+sizejniblock*3(t0)
344 blez s7,calljava_argsloaded
346 ald a4,offjniitem+sizejniblock*4(t0)
347 ldc1 fa4,offjniitem+sizejniblock*4(t0)
349 blez s7,calljava_argsloaded
351 ald a5,offjniitem+sizejniblock*5(t0)
352 ldc1 fa5,offjniitem+sizejniblock*5(t0)
354 blez s7,calljava_argsloaded
356 ald a6,offjniitem+sizejniblock*6(t0)
357 ldc1 fa6,offjniitem+sizejniblock*6(t0)
359 blez s7,calljava_argsloaded
361 ald a7,offjniitem+sizejniblock*7(t0)
362 ldc1 fa7,offjniitem+sizejniblock*7(t0)
367 blez s7,calljava_nocopy
374 ald t3,offjniitem+sizejniblock*8(t0)
377 ala t0,sizejniblock(t0)
379 bnez t1,calljava_copyloop
382 ala itmp1,32(t8) /* pass pointer to methodptr via itmp1 */
384 ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
385 ast mptr,16(sp) /* store function address */
386 ala mptr,8(t8) /* set method pointer */
390 ald pv,8(mptr) /* method call as in Java */
391 jalr pv /* call JIT compiler */
393 aaddiu pv,ra,-76*4 /* recompute procedure vector */
396 ld ra,0(sp) /* restore return address */
397 ld pv,8(sp) /* restore procedure vector */
400 ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
407 aaddiu sp,sp,12*8 /* free stack space */
415 jal builtin_throw_exception
418 .end asm_calljavafunction2
421 /****************** function asm_call_jit_compiler *****************************
423 * invokes the compiler for untranslated JavaVM methods. *
425 * Register REG_ITEMP1 contains a pointer to the method info structure *
426 * (prepared by createcompilerstub). Using the return address in R31 and the *
427 * offset in the LDA instruction or using the value in methodptr R25 the *
428 * patching address for storing the method address can be computed: *
430 * method address was either loaded using *
431 * M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
432 * M_JSR (REG_RA, REG_PV); *
434 * M_LDA (REG_PV, REG_RA, val) *
436 * M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
437 * M_JSR (REG_RA, REG_PV); *
439 * in the static case the method pointer can be computed using the *
440 * return address and the lda function following the jmp instruction *
442 *******************************************************************************/
445 .ent asm_call_jit_compiler
447 asm_call_jit_compiler:
448 lw t0,-12(ra) /* load instruction LD PV,xxx($y) */
449 srl t0,t0,21 /* shift right register number $y */
450 and t0,t0,31 /* isolate register number */
451 addiu t0,t0,-mptrreg /* test for REG_METHODPTR */
454 lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
456 sra t0,t0,16 /* isolate offset */
457 aaddu mptr,t0,ra /* compute update address */
460 aaddiu sp,sp,-18*8 /* allocate stack space */
461 sd a0,0*8(sp) /* save all argument registers */
462 sd a1,1*8(sp) /* they could be used by method */
477 sd mptr,16*8(sp) /* save method pointer */
478 sd ra,17*8(sp) /* save return address */
480 ald a0,0(itmp1) /* pass 'methodinfo' pointer to */
481 jal jit_compile /* jit compiler */
483 ld a0,0*8(sp) /* restore argument registers */
484 ld a1,1*8(sp) /* they could be used by method */
499 ld mptr,16*8(sp) /* restore method pointer */
500 ld ra,17*8(sp) /* restore return address */
501 aaddiu sp,sp,18*8 /* deallocate stack area */
503 lw t0,-12(ra) /* load instruction LDQ PV,xxx($yy) */
505 sra t0,t0,16 /* isolate offset */
507 aaddu t0,t0,mptr /* compute update address via method pointer*/
508 ast v0,0(t0) /* save new method address there */
510 move pv,v0 /* move method address into pv */
512 jr pv /* and call method. The method returns */
513 /* directly to the caller (ra). */
515 .end asm_call_jit_compiler
518 /********************* function asm_handle_exception ***************************
520 * This function handles an exception. It does not use the usual calling *
521 * conventions. The exception pointer is passed in REG_ITMP1 and the *
522 * pc from the exception raising position is passed in REG_ITMP2. It searches *
523 * the local exception table for a handler. If no one is found, it unwinds *
524 * stacks and continues searching the callers. *
526 * void asm_handle_exception (exceptionptr, exceptionpc); *
528 *******************************************************************************/
530 .ent asm_handle_nat_exception
532 asm_handle_nat_exception:
533 lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
535 sra t0,t0,16 /* isolate offset */
536 aaddu pv,t0,ra /* compute update address */
538 .aent asm_handle_exception
540 asm_handle_exception:
541 aaddiu sp,sp,-14*8 /* allocate stack */
542 sd v0,0*8(sp) /* save possible used registers */
543 sd t0,1*8(sp) /* also registers used by trace_exception */
557 addu t3,zero,1 /* set no unwind flag */
559 aaddiu sp,sp,-6*8 /* allocate stack */
560 sd xptr,0*8(sp) /* save used registers */
567 ald a1,MethodPointer(pv)
572 jal builtin_trace_exception /* trace_exception(xptr,methodptr) */
574 ld xptr,0*8(sp) /* restore used register */
579 aaddiu sp,sp,6*8 /* deallocate stack */
581 lw t0,ExTableSize(pv) /* t0 = exception table size */
582 beqz t0,empty_table /* if empty table skip */
583 aaddiu t1,pv,ExTableStart /* t1 = start of exception table */
586 ald t2,ExStartPC(t1) /* t2 = exception start pc */
587 sle t2,t2,xpc /* t2 = (startpc <= xpc) */
588 beqz t2,ex_table_cont /* if (false) continue */
589 ald t2,ExEndPC(t1) /* t2 = exception end pc */
590 slt t2,xpc,t2 /* t2 = (xpc < endpc) */
591 beqz t2,ex_table_cont /* if (false) continue */
592 ald a1,ExCatchType(t1) /* arg1 = exception catch type */
593 beqz a1,ex_handle_it /* NULL catches everything */
595 lw itmp3,offclassloaded(a1)
596 bnez itmp3,L_class_loaded
598 aaddiu sp,sp,-8*8 /* allocate stack */
599 sd t0,0*8(sp) /* save used register */
611 ld t0,0*8(sp) /* restore used register */
619 aaddiu sp,sp,8*8 /* deallocate stack */
622 lw itmp3,offclasslinked(a1)
623 aaddiu sp,sp,-8*8 /* allocate stack */
625 bnez itmp3,L_class_linked
627 sd t0,0*8(sp) /* save used register */
638 ld t0,0*8(sp) /* restore used register */
650 ald a0,offobjvftbl(xptr) /* a0 = vftblptr(xptr) */
651 ald a1,offclassvftbl(a1) /* a1 = vftblptr(catchtype) class (not obj) */
652 lw a0,offbaseval(a0) /* a0 = baseval(xptr) */
653 lw v0,offbaseval(a1) /* a2 = baseval(catchtype) */
654 lw a1,offdiffval(a1) /* a1 = diffval(catchtype) */
656 subu a0,a0,v0 /* a0 = baseval(xptr) - baseval(catchtype) */
657 sltu v0,a1,a0 /* v0 = xptr is instanceof catchtype */
658 aaddiu sp,sp,8*8 /* deallocate stack */
659 bnez v0,ex_table_cont /* if (false) continue */
662 ald xpc,ExHandlerPC(t1) /* xpc = exception handler pc */
664 beqz t3,ex_jump /* if (!(no stack unwinding) skip */
666 ld v0,0*8(sp) /* restore possible used registers */
667 ld t0,1*8(sp) /* also registers used by trace_exception */
681 aaddiu sp,sp,14*8 /* deallocate stack */
684 jr xpc /* jump to the handler */
687 aaddiu t1,t1,ExEntrySize /* next exception table entry */
688 addiu t0,t0,-1 /* decrement entry counter */
689 bgtz t0,ex_table_loop /* if (t0 > 0) next entry */
692 beqz t3,ex_already_cleared /* if here the first time, then */
693 aaddiu sp,sp,14*8 /* deallocate stack and */
694 move t3,zero /* clear the no unwind flag */
696 lw t0,IsSync(pv) /* t0 = SyncOffset */
697 beqz t0,no_monitor_exit /* if zero no monitorexit */
698 aaddu t0,sp,t0 /* add stackptr to Offset */
699 ald a0,-8(t0) /* load monitorexit pointer */
701 aaddiu sp,sp,-8*8 /* allocate stack */
702 sd t0,0*8(sp) /* save used register */
710 jal builtin_monitorexit /* builtin_monitorexit(objectptr) */
712 ld t0,0*8(sp) /* restore used register */
719 aaddiu sp,sp,8*8 /* deallocate stack */
722 lw t0,FrameSize(pv) /* t0 = frame size */
723 aaddu sp,sp,t0 /* unwind stack */
724 move t0,sp /* t0 = pointer to save area */
725 lw t1,IsLeaf(pv) /* t1 = is leaf procedure */
726 bnez t1,ex_no_restore /* if (leaf) skip */
727 ld ra,-8(t0) /* restore ra */
728 aaddiu t0,t0,-8 /* t0-- */
730 move xpc,ra /* the new xpc is ra */
731 lw t1,IntSave(pv) /* t1 = saved int register count */
732 ala t2,ex_int2 /* t2 = current pc */
733 sll t1,t1,2 /* t1 = register count * 4 */
734 asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
735 jr t2 /* jump to save position */
745 sll t1,t1,1 /* t1 = register count * 4 * 2 */
746 asubu t0,t0,t1 /* t0 = t0 - 8 * register count */
748 lw t1,FltSave(pv) /* t1 = saved flt register count */
749 ala t2,ex_flt2 /* t2 = current pc */
750 sll t1,t1,2 /* t1 = register count * 4 */
751 asubu t2,t2,t1 /* t2 = ex_int_sav - 4 * register count */
752 jr t2 /* jump to save position */
758 lw t0,0(ra) /* load instruction LDA PV,xxx(RA) */
760 sra t0,t0,16 /* isolate offset */
761 aaddu pv,t0,ra /* compute update address */
764 .end asm_handle_nat_exception
767 /********************* asm_check_clinit ****************************************
769 * Checks if class is initialized. If not, do it right now. *
771 *******************************************************************************/
773 .ent asm_check_clinit
778 sd ra,0*8(sp) /* save return address */
780 sd a0,1*8(sp) /* save argument registers for leaf funcs */
804 sd itmp2,22*8(sp) /* save machine code */
806 /* check if class is initialized */
807 lw itmp3,offclassinit(itmp1)
808 bnez itmp3,L_is_initialized
810 move a0,itmp1 /* move class pointer to a0 */
813 beqz v0,L_initializererror
816 ld ra,0*8(sp) /* get return address */
817 ld itmp1,22*8(sp) /* get machine code */
819 daddiu ra,ra,-2*4 /* go back 2 instructions (jal + nop delay) */
820 sw itmp1,0(ra) /* patch first instruction */
821 dsrl32 itmp1,itmp1,0 /* get high 32 bit */
822 sw itmp1,4(ra) /* patch second instruction */
824 move a0,ra /* start of flush area */
825 addiu a1,zero,2*4 /* 2 instruction words long */
826 jal docacheflush /* flush! */
828 ld ra,0*8(sp) /* restore return address */
830 ld a0,1*8(sp) /* restore argument registers */
856 daddiu ra,ra,-2*4 /* go back 2 instructions (jal + nop delay) */
860 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
861 jal builtin_asm_get_exceptionptrptr
865 ld xptr,0(v0) /* get the exception pointer */
866 sd zero,0(v0) /* clear the exception pointer */
868 ld ra,0*8(sp) /* restore return address */
870 ld a0,1*8(sp) /* restore argument registers */
896 aaddiu xpc,ra,-4 /* faulting address is return adress - 4 */
897 b asm_handle_exception
899 .end asm_check_clinit
902 /********************* function asm_builtin_monitorenter ***********************
904 * Does null check and calls monitorenter or throws an exception *
906 *******************************************************************************/
908 .ent asm_builtin_monitorenter
910 asm_builtin_monitorenter:
911 beqz a0,nb_monitorenter /* if (null) throw exception */
912 ala t9,builtin_monitorenter /* else call builtin_monitorenter */
918 ald a0,string_java_lang_NullPointerException
924 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
925 b asm_handle_nat_exception
927 .end asm_builtin_monitorenter
930 /********************* function asm_builtin_monitorexit ************************
932 * Does null check and calls monitorexit or throws an exception *
934 *******************************************************************************/
936 .ent asm_builtin_monitorexit
938 asm_builtin_monitorexit:
939 beqz a0,nb_monitorexit /* if (null) throw exception */
940 ala t9,builtin_monitorexit /* else call builtin_monitorexit */
946 jal new_nullpointerexception
951 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
952 b asm_handle_nat_exception
954 .end asm_builtin_monitorexit
957 /************************ function asm_builtin_idiv ****************************
959 * Does null check and calls idiv or throws an exception *
961 *******************************************************************************/
963 .ent asm_builtin_idiv
966 beqz a1,nb_idiv /* if (null) throw exception */
967 ala itmp3,builtin_idiv /* else call builtin_idiv */
973 jal new_arithmeticexception
978 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
979 b asm_handle_nat_exception
981 .end asm_builtin_idiv
984 /************************ function asm_builtin_ldiv ****************************
986 * Does null check and calls ldiv or throws an exception *
988 *******************************************************************************/
990 .ent asm_builtin_ldiv
993 beqz a1,nb_ldiv /* if (null) throw exception */
994 ala itmp3,builtin_ldiv /* else call builtin_ldiv */
1000 jal new_arithmeticexception
1005 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
1006 b asm_handle_nat_exception
1008 .end asm_builtin_ldiv
1011 /************************ function asm_builtin_irem ****************************
1013 * Does null check and calls irem or throws an exception *
1015 *******************************************************************************/
1017 .ent asm_builtin_irem
1020 beqz a1,nb_irem /* if (null) throw exception */
1021 ala t9,builtin_irem /* else call builtin_irem */
1027 jal new_arithmeticexception
1032 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
1033 b asm_handle_nat_exception
1035 .end asm_builtin_irem
1038 /************************ function asm_builtin_lrem ****************************
1040 * Does null check and calls lrem or throws an exception *
1042 *******************************************************************************/
1044 .ent asm_builtin_lrem
1047 beqz a1,nb_lrem /* if (null) throw exception */
1048 ala t9,builtin_lrem /* else call builtin_lrem */
1054 jal new_arithmeticexception
1059 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
1060 b asm_handle_nat_exception
1062 .end asm_builtin_lrem
1065 /******************* function asm_builtin_checkarraycast ***********************
1067 * Does the cast check and eventually throws an exception *
1069 *******************************************************************************/
1071 .ent asm_builtin_checkarraycast
1073 asm_builtin_checkarraycast:
1074 aaddiu sp,sp,-16 /* allocate stack space */
1075 sd ra,0(sp) /* save return address */
1076 sd a0,8(sp) /* save object pointer */
1077 jal builtin_checkarraycast /* builtin_checkarraycast */
1078 beqz v0,nb_carray_throw /* if (false) throw exception */
1079 ld ra,0(sp) /* restore return address */
1080 ld v0,8(sp) /* return object pointer */
1081 aaddiu sp,sp,16 /* deallocate stack */
1085 jal new_classcastexception
1088 ld ra,0(sp) /* restore return address */
1089 aaddiu sp,sp,16 /* free stack space */
1090 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
1091 b asm_handle_nat_exception
1093 .end asm_builtin_checkarraycast
1096 /********************* function asm_builtin_checkcast **************************
1098 * Does the cast check and eventually throws an exception *
1100 *******************************************************************************/
1102 .ent asm_builtin_checkcast
1104 asm_builtin_checkcast:
1105 aaddiu sp,sp,-16 /* allocate stack space */
1106 sd ra,0(sp) /* save return address */
1107 sd a0,8(sp) /* save object pointer */
1108 jal builtin_checkcast /* builtin_checkcast */
1109 beqz v0,nb_ccast_throw /* if (false) throw exception */
1110 ld ra,0(sp) /* restore return address */
1111 ld v0,8(sp) /* return object pointer */
1112 aaddiu sp,sp,16 /* deallocate stack */
1116 jal new_classcastexception
1119 ld ra,0(sp) /* restore return address */
1120 aaddiu sp,sp,16 /* free stack space */
1121 aaddiu xpc,ra,-4 /* faulting address is return adress - 4*/
1122 b asm_handle_nat_exception
1124 .end asm_builtin_checkcast
1127 /******************* function asm_builtin_aastore ******************************
1129 * Does the cast check and eventually throws an exception *
1130 * a0 = arrayref, a1 = index, a2 = value *
1132 *******************************************************************************/
1134 .ent asm_builtin_aastore
1136 asm_builtin_aastore:
1137 beqz a0,nb_aastore_null /* if null pointer throw exception */
1138 lw t0,offarraysize(a0) /* load size */
1139 aaddiu sp,sp,-32 /* allocate stack space */
1140 sd ra,0(sp) /* save return address */
1141 asll t1,a1,ashift /* add index*8 to arrayref */
1142 aaddu t1,a0,t1 /* add index * ashift to arrayref */
1143 sltu t0,a1,t0 /* do bound check */
1144 beqz t0,nb_aastore_bound /* if out of bounds throw exception */
1145 move a1,a2 /* object is second argument */
1146 sd t1,8(sp) /* save store position */
1147 sd a1,16(sp) /* save object */
1148 jal builtin_canstore /* builtin_canstore(arrayref,object) */
1149 ld ra,0(sp) /* restore return address */
1150 ld a0,8(sp) /* restore store position */
1151 ld a1,16(sp) /* restore object */
1152 aaddiu sp,sp,32 /* free stack space */
1153 beqz v0,nb_aastore_store /* if (false) throw exception */
1154 ast a1,offobjarrdata(a0) /* store objectptr in array */
1160 jal new_nullpointerexception
1165 move xpc,ra /* faulting address is return adress */
1166 b asm_handle_nat_exception
1171 move a0,a1 /* move index into a0 */
1172 jal new_arrayindexoutofboundsexception
1177 aaddiu sp,sp,32 /* free stack space */
1178 move xpc,ra /* faulting address is return adress */
1179 b asm_handle_nat_exception
1184 jal new_arraystoreexception
1189 move xpc,ra /* faulting address is return adress */
1190 b asm_handle_nat_exception
1192 .end asm_builtin_aastore
1195 /******************* function asm_initialize_thread_stack **********************
1197 * u1* asm_initialize_thread_stack (void *func, u1 *stack); *
1199 * initialize a thread stack *
1201 *******************************************************************************/
1203 .ent asm_initialize_thread_stack
1205 asm_initialize_thread_stack:
1206 aaddiu a1,a1,-14*8 /* allocate save area */
1207 sd zero, 0*8(a1) /* s0 initalize thread area */
1208 sd zero, 1*8(a1) /* s1 */
1209 sd zero, 2*8(a1) /* s2 */
1210 sd zero, 3*8(a1) /* s3 */
1211 sd zero, 4*8(a1) /* s4 */
1212 sd zero, 5*8(a1) /* s5 */
1213 sd zero, 6*8(a1) /* s6 */
1214 sd zero, 7*8(a1) /* s7 */
1215 sd zero, 8*8(a1) /* s8 */
1216 sd zero, 9*8(a1) /* fs0 */
1217 sd zero,10*8(a1) /* fs1 */
1218 sd zero,11*8(a1) /* fs2 */
1219 sd zero,12*8(a1) /* fs3 */
1224 .end asm_initialize_thread_stack
1227 /******************* function asm_perform_threadswitch *************************
1229 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
1231 * performs a threadswitch *
1233 *******************************************************************************/
1235 .ent asm_perform_threadswitch
1237 asm_perform_threadswitch:
1238 aaddiu sp,sp,-14*8 /* allocate new stack */
1239 sd s0, 0*8(sp) /* save saved registers of old thread */
1253 ast sp,0(a0) /* save old stack pointer */
1254 ast sp,0(a2) /* stackTop = old stack pointer */
1255 ald sp,0(a1) /* load new stack pointer */
1256 ld s0, 0*8(sp) /* load saved registers of new thread */
1270 aaddiu sp,sp,14*8 /* deallocate new stack */
1274 .end asm_perform_threadswitch
1277 /********************* function asm_switchstackandcall *************************
1279 * void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
1281 * Switches to a new stack, calls a function and switches back. *
1282 * a0 new stack pointer *
1283 * a1 function pointer *
1284 * a2 pointer to variable where stack top should be stored *
1286 *******************************************************************************/
1288 .ent asm_switchstackandcall
1290 asm_switchstackandcall:
1291 aaddiu a0,a0,-16 /* allocate new stack */
1292 sd ra,0(a0) /* save return address on new stack */
1293 sd sp,8(a0) /* save old stack pointer on new stack */
1294 sd sp,0(a2) /* save old stack pointer to variable */
1295 move sp,a0 /* switch to new stack */
1299 jalr itmp3 /* and call function */
1301 ld ra,0(sp) /* load return address */
1302 ld sp,8(sp) /* switch to old stack */
1306 .end asm_switchstackandcall
1309 .ent asm_getclassvalues_atomic
1311 asm_getclassvalues_atomic:
1314 lw t0,offbaseval(a0)
1315 lw t1,offdiffval(a0)
1316 lw t2,offbaseval(a1)
1318 sw t0,offcast_super_baseval(a2)
1319 sw t1,offcast_super_diffval(a2)
1320 sw t2,offcast_sub_baseval(a2)
1323 .end asm_getclassvalues_atomic
1327 asm_criticalsections:
1328 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1331 .dword _crit_restart1
1334 .dword _crit_restart2
1341 .ent compare_and_swap
1352 .end compare_and_swap
1354 * These are local overrides for various environment variables in Emacs.
1355 * Please do not remove this and leave it at the end of the file, where
1356 * Emacs will automagically detect them.
1357 * ---------------------------------------------------------------------
1360 * indent-tabs-mode: t