1 /* src/vm/jit/mips/asmpart.S - Java-C interface functions for MIPS
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
29 Changes: Christian Thalinger
32 $Id: asmpart.S 4735 2006-04-05 10:02:14Z twisti $
39 #include "vm/jit/mips/md-abi.h"
40 #include "vm/jit/mips/md-asm.h"
41 #include "vm/jit/mips/offsets.h"
43 #include "vm/jit/abi-asm.h"
44 #include "vm/jit/methodheader.h"
51 /* export functions ***********************************************************/
53 .globl asm_vm_call_method
54 .globl asm_vm_call_method_int
55 .globl asm_vm_call_method_long
56 .globl asm_vm_call_method_float
57 .globl asm_vm_call_method_double
58 .globl asm_vm_call_method_exception_handler
60 .globl asm_call_jit_compiler
61 .globl asm_handle_exception
62 .globl asm_handle_nat_exception
64 .globl asm_wrapper_patcher
66 .globl asm_replacement_out
67 .globl asm_replacement_in
69 .globl asm_perform_threadswitch
70 .globl asm_initialize_thread_stack
71 .globl asm_switchstackandcall
72 .globl asm_getclassvalues_atomic
73 .globl asm_criticalsections
75 .globl compare_and_swap
78 /********************* function asm_calljavafunction ***************************
80 * This function calls a Java-method (which possibly needs compilation) *
81 * with up to 4 address parameters. *
83 * This functions calls the JIT-compiler which eventually translates the *
84 * method into machine code. *
86 * A possibly throwed exception will be returned to the caller as function *
87 * return value, so the java method cannot return a fucntion value (this *
88 * function usually calls 'main' and '<clinit>' which do not return a *
92 * javaobject_header *asm_calljavafunction (methodinfo *m, *
93 * void *arg1, void *arg2, void *arg3, void *arg4); *
95 *******************************************************************************/
97 .ent asm_vm_call_method
101 .dword 0 /* catch type all */
102 .dword 0 /* handler pc */
103 .dword 0 /* end pc */
104 .dword 0 /* start pc */
105 .word 1 /* extable size */
106 .word 0 /* 4-byte ALIGNMENT PADDING */
107 .dword 0 /* line number table start */
108 .dword 0 /* line number table size */
109 .word 0 /* 4-byte ALIGNMENT PADDING */
110 .word 0 /* fltsave */
111 .word 0 /* intsave */
114 .word 0 /* frame size */
115 .dword 0 /* method pointer (pointer to name) */
118 asm_vm_call_method_int:
119 asm_vm_call_method_long:
120 asm_vm_call_method_float:
121 asm_vm_call_method_double:
122 .set noreorder /* XXX we need to recompute pv */
124 aaddiu sp,sp,-12*8 /* allocate stack space (only 11 needed)*/
125 ast ra,0(sp) /* save return address */
127 bal L_asm_vm_call_method_compute_pv
128 ast pv,1*8(sp) /* procedure vector */
129 L_asm_vm_call_method_compute_pv:
133 sdc1 fss0,5*8(sp) /* save non JavaABI saved flt registers */
140 ast a0,4*8(sp) /* save method pointer for compiler */
144 blez s7,calljava_argsloaded
147 ald a0,offvmargdata(t0)
148 ldc1 fa0,offvmargdata(t0)
150 blez s7,calljava_argsloaded
153 ald a1,offvmargdata+sizevmarg*1(t0)
154 ldc1 fa1,offvmargdata+sizevmarg*1(t0)
156 blez s7,calljava_argsloaded
159 ald a2,offvmargdata+sizevmarg*2(t0)
160 ldc1 fa2,offvmargdata+sizevmarg*2(t0)
162 blez s7,calljava_argsloaded
165 ald a3,offvmargdata+sizevmarg*3(t0)
166 ldc1 fa3,offvmargdata+sizevmarg*3(t0)
168 blez s7,calljava_argsloaded
171 ald a4,offvmargdata+sizevmarg*4(t0)
172 ldc1 fa4,offvmargdata+sizevmarg*4(t0)
174 blez s7,calljava_argsloaded
177 ald a5,offvmargdata+sizevmarg*5(t0)
178 ldc1 fa5,offvmargdata+sizevmarg*5(t0)
180 blez s7,calljava_argsloaded
183 ald a6,offvmargdata+sizevmarg*6(t0)
184 ldc1 fa6,offvmargdata+sizevmarg*6(t0)
186 blez s7,calljava_argsloaded
189 ald a7,offvmargdata+sizevmarg*7(t0)
190 ldc1 fa7,offvmargdata+sizevmarg*7(t0)
194 move t8,sp /* save stack pointer */
195 blez s7,calljava_nocopy
203 ald t3,offvmargdata+sizevmarg*8(t0)
208 bnez t1,calljava_copyloop
212 ald itmp1,4*8(t8) /* pass method pointer via itmp1 */
214 ala mptr,asm_call_jit_compiler/* fake virtual function call (2 instr) */
215 ast mptr,2*8(t8) /* store function address */
216 ala mptr,1*8(t8) /* set method pointer */
218 ald pv,1*8(mptr) /* method call as in Java */
219 jalr pv /* call JIT compiler */
221 L_asm_vm_call_method_recompute_pv:
222 /* aaddiu pv,ra,(asm_vm_call_method - L_asm_vm_call_method_recompute_pv)*/
223 aaddiu pv,ra,-76*4 /* recompute procedure vector */
225 .set reorder /* XXX we need to recompute pv */
228 ald ra,0(sp) /* restore return address */
229 ald pv,8(sp) /* restore procedure vector */
232 ldc1 fss0,5*8(sp) /* restore non JavaABI saved flt regs */
239 aaddiu sp,sp,12*8 /* free stack space */
242 asm_vm_call_method_exception_handler:
246 jal builtin_throw_exception
247 move v0,zero /* clear return value for exception */
250 .end asm_vm_call_method
253 /****************** function asm_call_jit_compiler *****************************
255 * invokes the compiler for untranslated JavaVM methods. *
257 * Register REG_ITEMP1 contains a pointer to the method info structure *
258 * (prepared by createcompilerstub). Using the return address in R31 and the *
259 * offset in the LDA instruction or using the value in methodptr R25 the *
260 * patching address for storing the method address can be computed: *
262 * method address was either loaded using *
263 * M_ALD (REG_PV, REG_PV, a) ; invokestatic/special ($28) *
264 * M_JSR (REG_RA, REG_PV); *
266 * M_LDA (REG_PV, REG_RA, val) *
268 * M_ALD (REG_PV, REG_METHODPTR, m) ; invokevirtual/interface ($25) *
269 * M_JSR (REG_RA, REG_PV); *
271 * in the static case the method pointer can be computed using the *
272 * return address and the lda function following the jmp instruction *
274 *******************************************************************************/
277 .ent asm_call_jit_compiler
279 asm_call_jit_compiler:
280 aaddiu sp,sp,-(20*8+sizestackframeinfo) /* allocate stack space */
282 SAVE_ARGUMENT_REGISTERS(0)
284 ast mptr,16*8(sp) /* save method pointer */
285 ast ra,17*8(sp) /* save return address */
286 ast itmp1,18*8(sp) /* save methodinfo pointer */
288 aaddiu a0,sp,20*8 /* create stackframe info */
289 move a1,zero /* we don't have pv handy */
290 aaddiu a2,sp,(20*8+sizestackframeinfo) /* pass java sp */
291 ald a3,17*8(sp) /* pass java ra */
292 move a4,a3 /* xpc is equal to ra */
293 jal stacktrace_create_extern_stackframeinfo
295 ald a0,18*8(sp) /* pass methodinfo pointer */
296 jal jit_compile /* jit compiler */
297 ast v0,18*8(sp) /* save return value */
299 aaddiu a0,sp,20*8 /* remove stackframe info */
300 jal stacktrace_remove_stackframeinfo
302 ald a0,17*8(sp) /* pass return address */
303 aaddiu a1,sp,20*8 /* pass stackframeinfo (for PV) */
304 ald a2,16*8(sp) /* pass method pointer */
305 jal md_assembler_get_patch_address /* get address of patch position */
306 move t0,v0 /* move offset to t0 for later use */
308 RESTORE_ARGUMENT_REGISTERS(0)
310 ald ra,17*8(sp) /* restore return address */
311 ald v0,18*8(sp) /* restore return value */
312 aaddiu sp,sp,20*8+sizestackframeinfo /* deallocate stack area */
314 beqz v0,L_asm_call_jit_compiler_exception
316 ast v0,0(t0) /* store new method address */
317 move pv,v0 /* move method address into pv */
318 jr pv /* and call method. The method returns */
319 /* directly to the caller (ra). */
321 L_asm_call_jit_compiler_exception:
322 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
325 jal builtin_asm_get_exceptionptrptr
331 ald xptr,0(v0) /* get the exception pointer */
332 ast zero,0(v0) /* clear the exception pointer */
334 aaddiu xpc,ra,-4 /* faulting address is return adress - 4 */
335 b asm_handle_nat_exception
337 .end asm_call_jit_compiler
340 /* asm_handle_exception ********************************************************
342 This function handles an exception. It does not use the usual calling
343 conventions. The exception pointer is passed in REG_ITMP1 and the
344 pc from the exception raising position is passed in REG_ITMP2. It searches
345 the local exception table for a handler. If no one is found, it unwinds
346 stacks and continues searching the callers.
348 *******************************************************************************/
350 .ent asm_handle_nat_exception
352 asm_handle_nat_exception:
353 L_asm_handle_exception_stack_loop:
354 aaddiu sp,sp,-6*8 /* allocate stack */
355 ast xptr,0*8(sp) /* save exception pointer */
356 ast xpc,1*8(sp) /* save exception pc */
357 ast ra,3*8(sp) /* save return address */
358 ast zero,4*8(sp) /* save maybe-leaf flag (cleared) */
360 move a0,ra /* pass return address */
361 jal md_codegen_findmethod /* get PV from RA */
362 ast v0,2*8(sp) /* save data segment pointer */
364 ald a0,0*8(sp) /* pass exception pointer */
365 ald a1,1*8(sp) /* pass exception pc */
366 move a2,v0 /* pass data segment pointer */
367 aaddiu a3,sp,6*8 /* pass Java stack pointer */
369 b L_asm_handle_exception_continue
371 .aent asm_handle_exception
373 asm_handle_exception:
374 aaddiu sp,sp,-(ARG_CNT+TMP_CNT)*8 /* create maybe-leaf stackframe */
376 SAVE_ARGUMENT_REGISTERS(0) /* we save arg and temp registers in */
377 SAVE_TEMPORARY_REGISTERS(ARG_CNT) /* case this is a leaf method */
379 aaddiu sp,sp,-6*8 /* allocate stack */
380 ast xptr,0*8(sp) /* save exception pointer */
381 ast xpc,1*8(sp) /* save exception pc */
382 ast pv,2*8(sp) /* save data segment pointer */
383 ast ra,3*8(sp) /* save return address */
384 addu t0,zero,1 /* set maybe-leaf flag */
385 ast t0,4*8(sp) /* save maybe-leaf flag */
387 move a0,xptr /* pass exception pointer */
388 move a1,xpc /* pass exception pc */
389 move a2,pv /* pass data segment pointer */
390 aaddiu a3,sp,(ARG_CNT+TMP_CNT+6)*8 /* pass Java stack pointer */
392 L_asm_handle_exception_continue:
393 jal exceptions_handle_exception
395 beqz v0,L_asm_handle_exception_not_catched
397 move xpc,v0 /* move handlerpc into xpc */
398 ald xptr,0*8(sp) /* restore exception pointer */
399 ald pv,2*8(sp) /* restore data segment pointer */
400 ald ra,3*8(sp) /* restore return address */
401 ald t0,4*8(sp) /* get maybe-leaf flag */
402 aaddiu sp,sp,6*8 /* free stackframe */
404 beqz t0,L_asm_handle_exception_no_leaf
406 RESTORE_ARGUMENT_REGISTERS(0) /* if this is a leaf method, we have */
407 RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers */
409 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
411 L_asm_handle_exception_no_leaf:
412 jr xpc /* jump to the handler */
414 L_asm_handle_exception_not_catched:
415 ald xptr,0*8(sp) /* restore exception pointer */
416 ald pv,2*8(sp) /* restore data segment pointer */
417 ald ra,3*8(sp) /* restore return address */
418 ald t0,4*8(sp) /* get maybe-leaf flag */
419 aaddiu sp,sp,6*8 /* free stackframe */
421 beqz t0,L_asm_handle_exception_no_leaf_stack
423 aaddiu sp,sp,(ARG_CNT+TMP_CNT)*8 /* remove maybe-leaf stackframe */
424 move t0,zero /* clear the maybe-leaf flag */
426 L_asm_handle_exception_no_leaf_stack:
427 lw t1,FrameSize(pv) /* get frame size */
428 aaddu t1,sp,t1 /* pointer to save area */
430 lw t2,IsLeaf(pv) /* is leaf procedure */
431 bnez t2,L_asm_handle_exception_no_ra_restore
433 ald ra,-1*8(t1) /* restore ra */
434 aaddiu t1,t1,-8 /* t1-- */
436 L_asm_handle_exception_no_ra_restore:
437 move xpc,ra /* the new xpc is ra */
438 lw t2,IntSave(pv) /* t1 = saved int register count */
439 ala t3,ex_int2 /* t3 = current pc */
440 sll t2,t2,2 /* t2 = register count * 4 */
441 asubu t3,t3,t2 /* t3 = IntSave - 4 * register count */
442 jr t3 /* jump to save position */
453 sll t2,t2,1 /* t2 = register count * 4 * 2 */
454 asubu t1,t1,t2 /* t1 = t0 - 8 * register count */
456 lw t2,FltSave(pv) /* t2 = saved flt register count */
457 ala t3,ex_flt2 /* t3 = current pc */
458 sll t2,t2,2 /* t2 = register count * 4 */
459 asubu t3,t3,t2 /* t3 = ex_int_sav - 4 * register count */
460 jr t3 /* jump to save position */
468 lw t1,FrameSize(pv) /* get frame size */
469 aaddu sp,sp,t1 /* unwind stack */
470 b L_asm_handle_exception_stack_loop
472 .end asm_handle_nat_exception
475 /* asm_wrapper_patcher *********************************************************
480 40 return address into JIT code (patch position)
481 32 pointer to virtual java_objectheader
482 24 machine code (which is patched back later)
483 16 unresolved class/method/field reference
484 8 data segment displacement from load instructions
485 0 patcher function pointer to call
487 *******************************************************************************/
489 .ent asm_wrapper_patcher
492 aaddiu sp,sp,-((2+16+22+4)*8+sizestackframeinfo) /* create stack frame */
494 SAVE_RETURN_REGISTERS(0) /* save 1 int/1 float return registers */
495 SAVE_ARGUMENT_REGISTERS(2) /* save 8 int/8 float argument registers */
496 SAVE_TEMPORARY_REGISTERS(18) /* save 5 int/16 float temporary registers */
498 ast itmp1,(2+16+22+0)*8(sp) /* save itmp1 */
499 ast itmp2,(2+16+22+1)*8(sp) /* save itmp2 */
500 ast ra,(2+16+22+2)*8(sp) /* save method return address (for leafs) */
501 ast pv,(2+16+22+3)*8(sp) /* save pv of calling java function */
503 aaddiu a0,sp,(2+16+22+4)*8 /* create stackframe info */
504 move a1,pv /* pass java pv */
505 aaddiu a2,sp,((6+2+16+22+4)*8+sizestackframeinfo) /* pass java sp */
506 move a3,ra /* this is correct for leafs */
507 ald a4,((5+2+16+22+4)*8+sizestackframeinfo)(sp) /* pass xpc */
508 jal stacktrace_create_extern_stackframeinfo
510 aaddiu a0,sp,((0+2+16+22+4)*8+sizestackframeinfo) /* pass sp */
511 ald itmp3,((0+2+16+22+4)*8+sizestackframeinfo)(sp) /* get function */
512 ald itmp1,(2+16+22+3)*8(sp) /* save pv to the position of fp */
513 ast itmp1,((0+2+16+22+4)*8+sizestackframeinfo)(sp)
515 ast v0,((0+2+16+22+4)*8+sizestackframeinfo)(sp) /* save return value */
517 aaddiu a0,sp,(2+16+22+4)*8 /* remove stackframe info */
518 jal stacktrace_remove_stackframeinfo
520 RESTORE_RETURN_REGISTERS(0) /* restore 1 int/1 float return registers */
521 RESTORE_ARGUMENT_REGISTERS(2) /* restore 8 int/8 float argument registers */
522 RESTORE_TEMPORARY_REGISTERS(18) /* restore 5 int/16 float temporary reg. */
524 ald itmp1,(2+16+22+0)*8(sp) /* restore itmp1 */
525 ald itmp2,(2+16+22+1)*8(sp) /* restore itmp2 */
526 ald ra,(2+16+22+2)*8(sp) /* restore method return address (for leafs)*/
527 ald pv,(2+16+22+3)*8(sp) /* restore pv of calling java function */
529 ald itmp3,((0+2+16+22+4)*8+sizestackframeinfo)(sp) /* get return value*/
530 beqz itmp3,L_asm_wrapper_patcher_exception
532 ald itmp3,((5+2+16+22+4)*8+sizestackframeinfo)(sp) /* get RA to JIT */
533 aaddiu sp,sp,((6+2+16+22+4)*8+sizestackframeinfo) /* remove stack frame */
535 jr itmp3 /* jump to new patched code */
537 L_asm_wrapper_patcher_exception:
538 ald xpc,((5+2+16+22+4)*8+sizestackframeinfo)(sp) /* RA to JIT is xpc */
539 aaddiu sp,sp,((6+2+16+22+4)*8+sizestackframeinfo) /* remove stack frame */
541 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
546 jal builtin_asm_get_exceptionptrptr
554 ld xptr,0(v0) /* get the exception pointer */
555 sd zero,0(v0) /* clear the exception pointer */
556 b asm_handle_exception
558 .end asm_wrapper_patcher
561 /* asm_replacement_out *********************************************************
563 This code is jumped to from the replacement-out stubs that are executed
564 when a thread reaches an activated replacement point.
566 The purpose of asm_replacement_out is to read out the parts of the
567 execution state that cannot be accessed from C code, store this state,
568 and then call the C function replace_me.
571 16 start of stack inside method to replace
572 0 rplpoint * info on the replacement point that was reached
574 NOTE: itmp3 has been clobbered by the replacement-out stub!
576 *******************************************************************************/
578 /* some room to accomodate changes of the stack frame size during replacement */
579 /* XXX we should find a cleaner solution here */
580 #define REPLACEMENT_ROOM 512
582 #define REPLACEMENT_STACK_OFFSET ((sizeexecutionstate + REPLACEMENT_ROOM + 0xf) & ~0xf)
584 .ent asm_replacement_out
587 /* create stack frame */
588 daddiu sp,sp,-REPLACEMENT_STACK_OFFSET
590 /* save registers in execution state */
591 sd $0 ,( 0*8+offes_intregs)(sp)
592 sd $1 ,( 1*8+offes_intregs)(sp)
593 sd $2 ,( 2*8+offes_intregs)(sp)
594 sd $3 ,( 3*8+offes_intregs)(sp)
595 sd $4 ,( 4*8+offes_intregs)(sp)
596 sd $5 ,( 5*8+offes_intregs)(sp)
597 sd $6 ,( 6*8+offes_intregs)(sp)
598 sd $7 ,( 7*8+offes_intregs)(sp)
599 sd $8 ,( 8*8+offes_intregs)(sp)
600 sd $9 ,( 9*8+offes_intregs)(sp)
601 sd $10,(10*8+offes_intregs)(sp)
602 sd $11,(11*8+offes_intregs)(sp)
603 sd $12,(12*8+offes_intregs)(sp)
604 sd $13,(13*8+offes_intregs)(sp)
605 sd $14,(14*8+offes_intregs)(sp)
606 sd $15,(15*8+offes_intregs)(sp)
607 sd $16,(16*8+offes_intregs)(sp)
608 sd $17,(17*8+offes_intregs)(sp)
609 sd $18,(18*8+offes_intregs)(sp)
610 sd $19,(19*8+offes_intregs)(sp)
611 sd $20,(20*8+offes_intregs)(sp)
612 sd $21,(21*8+offes_intregs)(sp)
613 sd $22,(22*8+offes_intregs)(sp)
614 sd $23,(23*8+offes_intregs)(sp)
615 sd $24,(24*8+offes_intregs)(sp)
616 sd $25,(25*8+offes_intregs)(sp)
617 sd $26,(26*8+offes_intregs)(sp)
618 sd $27,(27*8+offes_intregs)(sp)
619 sd $28,(28*8+offes_intregs)(sp)
620 sd $29,(29*8+offes_intregs)(sp)
621 sd $30,(30*8+offes_intregs)(sp)
622 sd $31,(31*8+offes_intregs)(sp)
624 sdc1 $f0 ,( 0*8+offes_fltregs)(sp)
625 sdc1 $f1 ,( 1*8+offes_fltregs)(sp)
626 sdc1 $f2 ,( 2*8+offes_fltregs)(sp)
627 sdc1 $f3 ,( 3*8+offes_fltregs)(sp)
628 sdc1 $f4 ,( 4*8+offes_fltregs)(sp)
629 sdc1 $f5 ,( 5*8+offes_fltregs)(sp)
630 sdc1 $f6 ,( 6*8+offes_fltregs)(sp)
631 sdc1 $f7 ,( 7*8+offes_fltregs)(sp)
632 sdc1 $f8 ,( 8*8+offes_fltregs)(sp)
633 sdc1 $f9 ,( 9*8+offes_fltregs)(sp)
634 sdc1 $f10,(10*8+offes_fltregs)(sp)
635 sdc1 $f11,(11*8+offes_fltregs)(sp)
636 sdc1 $f12,(12*8+offes_fltregs)(sp)
637 sdc1 $f13,(13*8+offes_fltregs)(sp)
638 sdc1 $f14,(14*8+offes_fltregs)(sp)
639 sdc1 $f15,(15*8+offes_fltregs)(sp)
640 sdc1 $f16,(16*8+offes_fltregs)(sp)
641 sdc1 $f17,(17*8+offes_fltregs)(sp)
642 sdc1 $f18,(18*8+offes_fltregs)(sp)
643 sdc1 $f19,(19*8+offes_fltregs)(sp)
644 sdc1 $f20,(20*8+offes_fltregs)(sp)
645 sdc1 $f21,(21*8+offes_fltregs)(sp)
646 sdc1 $f22,(22*8+offes_fltregs)(sp)
647 sdc1 $f23,(23*8+offes_fltregs)(sp)
648 sdc1 $f24,(24*8+offes_fltregs)(sp)
649 sdc1 $f25,(25*8+offes_fltregs)(sp)
650 sdc1 $f26,(26*8+offes_fltregs)(sp)
651 sdc1 $f27,(27*8+offes_fltregs)(sp)
652 sdc1 $f28,(28*8+offes_fltregs)(sp)
653 sdc1 $f29,(29*8+offes_fltregs)(sp)
654 sdc1 $f30,(30*8+offes_fltregs)(sp)
655 sdc1 $f31,(31*8+offes_fltregs)(sp)
657 /* calculate sp of method */
658 daddiu itmp1,sp,(REPLACEMENT_STACK_OFFSET + 2*8)
659 sd itmp1,(offes_sp)(sp)
664 /* call replace_me */
665 ld a0,-(2*8)(itmp1) /* arg0: rplpoint * */
666 move a1,sp /* arg1: execution state */
667 jal replace_me /* call C function replace_me */
668 jal abort /* NEVER REACHED */
670 .end asm_replacement_out
672 /* asm_replacement_in **********************************************************
674 This code writes the given execution state and jumps to the replacement
677 This function never returns!
679 NOTE: itmp3 is not restored!
682 void asm_replacement_in(executionstate *es);
684 *******************************************************************************/
686 .ent asm_replacement_in
689 /* a0 == executionstate *es */
691 /* set new sp and pv */
695 /* copy registers from execution state */
697 ld $1 ,( 1*8+offes_intregs)(a0)
698 ld $2 ,( 2*8+offes_intregs)(a0)
699 ld $3 ,( 2*8+offes_intregs)(a0)
700 /* a0 is loaded below */
701 ld $5 ,( 5*8+offes_intregs)(a0)
702 ld $6 ,( 6*8+offes_intregs)(a0)
703 ld $7 ,( 7*8+offes_intregs)(a0)
704 ld $8 ,( 8*8+offes_intregs)(a0)
705 ld $9 ,( 9*8+offes_intregs)(a0)
706 ld $10,(10*8+offes_intregs)(a0)
707 ld $11,(11*8+offes_intregs)(a0)
708 ld $12,(12*8+offes_intregs)(a0)
709 ld $13,(13*8+offes_intregs)(a0)
710 ld $14,(14*8+offes_intregs)(a0)
711 ld $15,(15*8+offes_intregs)(a0)
712 ld $16,(16*8+offes_intregs)(a0)
713 ld $17,(17*8+offes_intregs)(a0)
714 ld $18,(18*8+offes_intregs)(a0)
715 ld $19,(19*8+offes_intregs)(a0)
716 ld $20,(20*8+offes_intregs)(a0)
717 ld $21,(21*8+offes_intregs)(a0)
718 ld $22,(22*8+offes_intregs)(a0)
719 ld $23,(23*8+offes_intregs)(a0)
720 ld $24,(24*8+offes_intregs)(a0)
721 ld $25,(25*8+offes_intregs)(a0)
722 ld $26,(26*8+offes_intregs)(a0)
723 ld $27,(27*8+offes_intregs)(a0)
724 ld $28,(28*8+offes_intregs)(a0)
727 ld $31,(31*8+offes_intregs)(a0)
729 ldc1 $f0 ,( 0*8+offes_fltregs)(a0)
730 ldc1 $f1 ,( 1*8+offes_fltregs)(a0)
731 ldc1 $f2 ,( 2*8+offes_fltregs)(a0)
732 ldc1 $f3 ,( 3*8+offes_fltregs)(a0)
733 ldc1 $f4 ,( 4*8+offes_fltregs)(a0)
734 ldc1 $f5 ,( 5*8+offes_fltregs)(a0)
735 ldc1 $f6 ,( 6*8+offes_fltregs)(a0)
736 ldc1 $f7 ,( 7*8+offes_fltregs)(a0)
737 ldc1 $f8 ,( 8*8+offes_fltregs)(a0)
738 ldc1 $f9 ,( 9*8+offes_fltregs)(a0)
739 ldc1 $f10,(10*8+offes_fltregs)(a0)
740 ldc1 $f11,(11*8+offes_fltregs)(a0)
741 ldc1 $f12,(12*8+offes_fltregs)(a0)
742 ldc1 $f13,(13*8+offes_fltregs)(a0)
743 ldc1 $f14,(14*8+offes_fltregs)(a0)
744 ldc1 $f15,(15*8+offes_fltregs)(a0)
745 ldc1 $f16,(16*8+offes_fltregs)(a0)
746 ldc1 $f17,(17*8+offes_fltregs)(a0)
747 ldc1 $f18,(18*8+offes_fltregs)(a0)
748 ldc1 $f19,(19*8+offes_fltregs)(a0)
749 ldc1 $f20,(20*8+offes_fltregs)(a0)
750 ldc1 $f21,(21*8+offes_fltregs)(a0)
751 ldc1 $f22,(22*8+offes_fltregs)(a0)
752 ldc1 $f23,(23*8+offes_fltregs)(a0)
753 ldc1 $f24,(24*8+offes_fltregs)(a0)
754 ldc1 $f25,(25*8+offes_fltregs)(a0)
755 ldc1 $f26,(26*8+offes_fltregs)(a0)
756 ldc1 $f27,(27*8+offes_fltregs)(a0)
757 ldc1 $f28,(28*8+offes_fltregs)(a0)
758 ldc1 $f29,(29*8+offes_fltregs)(a0)
759 ldc1 $f30,(30*8+offes_fltregs)(a0)
760 ldc1 $f31,(31*8+offes_fltregs)(a0)
764 ld itmp3,offes_pc(a0)
768 ld a0,(4*8+offes_intregs)(a0)
770 /* jump to new code */
774 .end asm_replacement_in
776 /******************* function asm_initialize_thread_stack **********************
778 * u1* asm_initialize_thread_stack (void *func, u1 *stack); *
780 * initialize a thread stack *
782 *******************************************************************************/
784 .ent asm_initialize_thread_stack
786 asm_initialize_thread_stack:
787 aaddiu a1,a1,-14*8 /* allocate save area */
788 sd zero, 0*8(a1) /* s0 initalize thread area */
789 sd zero, 1*8(a1) /* s1 */
790 sd zero, 2*8(a1) /* s2 */
791 sd zero, 3*8(a1) /* s3 */
792 sd zero, 4*8(a1) /* s4 */
793 sd zero, 5*8(a1) /* s5 */
794 sd zero, 6*8(a1) /* s6 */
795 sd zero, 7*8(a1) /* s7 */
796 sd zero, 8*8(a1) /* s8 */
797 sd zero, 9*8(a1) /* fs0 */
798 sd zero,10*8(a1) /* fs1 */
799 sd zero,11*8(a1) /* fs2 */
800 sd zero,12*8(a1) /* fs3 */
805 .end asm_initialize_thread_stack
808 /******************* function asm_perform_threadswitch *************************
810 * void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop); *
812 * performs a threadswitch *
814 *******************************************************************************/
816 .ent asm_perform_threadswitch
818 asm_perform_threadswitch:
819 aaddiu sp,sp,-14*8 /* allocate new stack */
820 sd s0, 0*8(sp) /* save saved registers of old thread */
834 ast sp,0(a0) /* save old stack pointer */
835 ast sp,0(a2) /* stackTop = old stack pointer */
836 ald sp,0(a1) /* load new stack pointer */
837 ld s0, 0*8(sp) /* load saved registers of new thread */
851 aaddiu sp,sp,14*8 /* deallocate new stack */
855 .end asm_perform_threadswitch
858 /********************* function asm_switchstackandcall *************************
860 * void asm_switchstackandcall (void *stack, void *func, void **stacktopsave); *
862 * Switches to a new stack, calls a function and switches back. *
863 * a0 new stack pointer *
864 * a1 function pointer *
865 * a2 pointer to variable where stack top should be stored *
867 *******************************************************************************/
869 .ent asm_switchstackandcall
871 asm_switchstackandcall:
872 aaddiu a0,a0,-16 /* allocate new stack */
873 sd ra,0(a0) /* save return address on new stack */
874 sd sp,8(a0) /* save old stack pointer on new stack */
875 sd sp,0(a2) /* save old stack pointer to variable */
876 move sp,a0 /* switch to new stack */
880 jalr itmp3 /* and call function */
882 ld ra,0(sp) /* load return address */
883 ld sp,8(sp) /* switch to old stack */
887 .end asm_switchstackandcall
890 .ent asm_getclassvalues_atomic
892 asm_getclassvalues_atomic:
899 sw t0,offcast_super_baseval(a2)
900 sw t1,offcast_super_diffval(a2)
901 sw t2,offcast_sub_baseval(a2)
904 .end asm_getclassvalues_atomic
908 asm_criticalsections:
909 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
919 .ent compare_and_swap
932 .end compare_and_swap
935 /* Disable exec-stacks, required for Gentoo ***********************************/
937 #if defined(__GCC__) && defined(__ELF__)
938 .section .note.GNU-stack,"",@progbits
943 * These are local overrides for various environment variables in Emacs.
944 * Please do not remove this and leave it at the end of the file, where
945 * Emacs will automagically detect them.
946 * ---------------------------------------------------------------------
949 * indent-tabs-mode: t
953 * vim:noexpandtab:sw=4:ts=4: