/* src/vm/jit/s390/asmpart.S - Java-C interface functions for s390 Copyright (C) 2006, 2007 R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, Institut f. Computersprachen - TU Wien This file is part of CACAO. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "config.h" #include "vm/jit/s390/arch.h" #include "vm/jit/s390/md-abi.h" #include "vm/jit/s390/md-asm.h" #include "vm/jit/abi-asm.h" #include "vm/jit/methodheader.h" .text /* export functions ***********************************************************/ .globl asm_vm_call_method .globl asm_vm_call_method_int .globl asm_vm_call_method_long .globl asm_vm_call_method_float .globl asm_vm_call_method_double .globl asm_vm_call_method_exception_handler .globl asm_vm_call_method_end .globl asm_handle_exception .globl asm_handle_nat_exception .globl asm_abstractmethoderror .globl asm_builtin_f2i .globl asm_builtin_f2l .globl asm_builtin_d2i .globl asm_builtin_d2l asm_abstractmethoderror: .long 0 asm_builtin_f2i: .long 0 asm_builtin_f2l: .long 0 asm_builtin_d2i: .long 0 asm_builtin_d2l: .long 0 /* Generates a PIC call. * * func: function to call * tag: tag unique for this call to generate a label * tmp: one temporary register needed for calculation * * The offset table used is located at the bottom of this file. * * Note: destroys r12. r12 MUST contain GOT for PIC calls! */ #define CALL_PIC(func, tag) \ bras %r14, L_bras_##tag; /* get PC */ \ L_bras_##tag: \ l %r12, L_offsets - L_bras_##tag (%r14); /* load offset to PLT */ \ la %r12, L_offsets - L_bras_##tag (%r12, %r14); /* load PLT address */ \ l %r14, L_offset_##func - L_bras_##tag (%r14); /* load offset to func */ \ bas %r14, 0(%r14, %r12); /********************* function asm_calljavafunction *************************** * * * This function calls a Java-method (which possibly needs compilation) * * with up to 4 address parameters. * * * * This functions calls the JIT-compiler which eventually translates the * * method into machine code. * * * * C-prototype: * * javaobject_header *asm_calljavamethod (methodinfo *m, * * void *arg1, void *arg2, void *arg3, void *arg4); * * * *******************************************************************************/ .long 0 /* fltsave */ .long 0 /* intsave */ .long 0 /* IsLeaf */ .long 0 /* frame size */ .long 0 /* codeinfo pointer */ asm_vm_call_method: asm_vm_call_method_int: asm_vm_call_method_long: asm_vm_call_method_float: asm_vm_call_method_double: ahi sp, -8*4 /* allocate stack frame */ /* a0: PV */ /* a1: data structure */ /* a2: number of stack arguments */ st s0, 0*4(sp) /* store used calle saved registers */ st s1, 1*4(sp) st a0, 2*4(sp) st %r12, 3*4(sp) /* %r12 is callee saved, we'll need it as GOT */ st pv, 4*4(sp) st a4, 5*4(sp) /* a4 is callee saved in terms of C abi */ std ftmp1, 6*4(sp) /* ftmp1 and ftmp2 are callees saved in terms of C abi */ std ftmp2, 8*4(sp) st ra, 10*4(sp) lr s0, a1 /* data structure */ lr %r0, a2 /* number of stack arguments */ l a0, 0*8+4(s0) /* big endian */ l a1, 1*8+4(s0) l a2, 2*8+4(s0) l a3, 3*8+4(s0) l a4, 4*8+4(s0) ld fa0, 5*8(s0) ld fa1, 6*8(s0) lr s1, sp /* backup stack pointer */ ltr %r0, %r0 /* are there any stack arguments ? */ je L_asm_vm_call_method_stack_copy_done lr %r1, %r0 /* copy number of stack arguments */ sll %r1, 3 /* calculate stackframe size */ sr sp, %r1 /* allocate stack frame */ lr %r1, sp /* temporary stack pointer */ L_asm_vm_call_method_stack_copy_loop: mvc 0(8, %r1), 7*8(s0) /* copy argument */ ahi %r1, 8 /* increase sp */ ahi s0, 8 /* set address of next argument */ ahi %r0, -1 /* substract 1 argument */ jh L_asm_vm_call_method_stack_copy_loop L_asm_vm_call_method_stack_copy_done: la mptr, 2*4(s1) /* load method pointer */ l pv, 0(mptr) /* load procedure vector from method pointer */ basr ra, pv /* call method */ L_asm_vm_call_method_return: lr sp, s1 /* restore stack pointer */ l s0, 0*4(sp) /* restore used callee saved registers */ l s1, 1*4(sp) l %r12, 3*4(sp) l pv, 4*4(sp) l a4, 5*4(sp) ld ftmp1, 6*4(sp) ld ftmp2, 8*4(sp) l ra, 10*4(sp) ahi sp, 8*4 /* remove stackframe */ br ra /* return */ asm_vm_call_method_exception_handler: lr a0, xptr ahi sp, -96 CALL_PIC(builtin_throw_exception, avcmeh) ahi sp, 96 j L_asm_vm_call_method_return asm_vm_call_method_end: brc 0,0 /* asm_handle_exception ******************************************************** * * * This function handles an exception. It does not use the usual calling * * conventions. The exception pointer is passed in REG_ITMP1 and the * * pc from the exception raising position is passed in REG_ITMP2. It searches * * the local exception table for a handler. If no one is found, it unwinds * * stacks and continues searching the callers. * * * *******************************************************************************/ asm_handle_nat_exception: L_asm_handle_nat_exception: /* TODO really nothing here ? */ asm_handle_exception: L_asm_handle_exception: /* a wrapper for md_handle_exception */ # define STACKFRAMESIZE (96 + (16 * 4) + (16 * 8) + (4 * 4)) # define REGS 96 # define FREGS (96 + (16 * 4)) # define OUT (96 + (16 * 4) + (16 * 8)) ahi sp, -STACKFRAMESIZE /* allocate stack frame containing the arrays */ /* store special registers to array */ st xptr, REGS+(0*4)(sp) st xpc, REGS+(1*4)(sp) st pv, REGS+(13*4)(sp) la itmp3, STACKFRAMESIZE(sp) st itmp3, REGS+(15*4)(sp) /* store temporary and argument registers */ stm a0, a4, REGS+(2*4)(sp) std %f0, FREGS+(0*8)(sp) std %f1, FREGS+(1*8)(sp) std %f2, FREGS+(2*8)(sp) std %f3, FREGS+(3*8)(sp) std %f5, FREGS+(5*8)(sp) std %f7, FREGS+(7*8)(sp) std %f8, FREGS+(8*8)(sp) std %f9, FREGS+(9*8)(sp) std %f10, FREGS+(10*8)(sp) std %f11, FREGS+(11*8)(sp) std %f12, FREGS+(12*8)(sp) std %f13, FREGS+(13*8)(sp) std %f14, FREGS+(14*8)(sp) std %f15, FREGS+(15*8)(sp) /* store %r12 used as GOT */ st %r12, REGS+(12*4)(sp) /* call md_handle_exception */ la a0, REGS(sp) la a1, FREGS(sp) la a2, OUT(sp) CALL_PIC(md_handle_exception, ahe) /* restore %r12 */ l %r12, REGS+(12*4)(sp) l itmp3, OUT+(2*4)(sp) /* out[2] contains maybe leaf flag */ ltr itmp3, itmp3 je L_restore_saved L_restore_temporary_and_argument: /* if we are maybe leaf, * we have to restore argument and temporary registers */ lm a0, a4, REGS+(2*4)(sp) ld %f0, FREGS+(0*8)(sp) ld %f1, FREGS+(1*8)(sp) ld %f2, FREGS+(2*8)(sp) ld %f3, FREGS+(3*8)(sp) ld %f5, FREGS+(5*8)(sp) ld %f7, FREGS+(7*8)(sp) ld %f8, FREGS+(8*8)(sp) ld %f9, FREGS+(9*8)(sp) ld %f10, FREGS+(10*8)(sp) ld %f11, FREGS+(11*8)(sp) ld %f12, FREGS+(12*8)(sp) ld %f13, FREGS+(13*8)(sp) ld %f14, FREGS+(14*8)(sp) ld %f15, FREGS+(15*8)(sp) j L_restore_done L_restore_saved: /* if we are not a maybe leaf, * we have to restore callee saved registers of the callee */ l itmp3, OUT+(0*4)(sp) /* out[0] contains IntSav */ ahi itmp3, -1 jl L_int_done l s5, REGS+(12*4)(sp) ahi itmp3, -1 jl L_int_done l s4, REGS+(11*4)(sp) ahi itmp3, -1 jl L_int_done l s3, REGS+(10*4)(sp) ahi itmp3, -1 jl L_int_done l s2, REGS+(9*4)(sp) ahi itmp3, -1 jl L_int_done l s1, REGS+(8*4)(sp) ahi itmp3, -1 jl L_int_done l s0, REGS+(7*4)(sp) L_int_done: /* restore callee saved float registers */ /* there are currently none */ L_flt_done: L_restore_done: /* write new values for special registers */ l xptr, REGS+(0*4)(sp) l xpc, REGS+(1*4)(sp) l pv, REGS+(13*4)(sp) l sp, REGS+(15*4)(sp) br xpc /* jump to handler */ # undef STACKFRAMESIZE # undef REGS # undef FREGS # undef OUT /* Offset table for PIC calls, see CALL_PIC */ L_offsets: .long _GLOBAL_OFFSET_TABLE_ - L_offsets L_offset_builtin_throw_exception: .long builtin_throw_exception@PLTOFF L_offset_md_handle_exception: .long md_handle_exception@PLTOFF /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where * Emacs will automagically detect them. * --------------------------------------------------------------------- * Local variables: * mode: asm * indent-tabs-mode: t * c-basic-offset: 4 * tab-width: 4 * End: * vim:noexpandtab:sw=4:ts=4: */