1 /* src/vm/jit/arm/asmpart.S - Java-C interface functions for ARM
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
28 #include <sys/syscall.h>
30 #include "vm/jit/arm/md-asm.h"
32 #include "vm/jit/methodheader.h"
40 /* export functions ***********************************************************/
42 .globl asm_vm_call_method
43 .globl asm_vm_call_method_int
44 .globl asm_vm_call_method_long
45 .globl asm_vm_call_method_float
46 .globl asm_vm_call_method_double
47 .globl asm_vm_call_method_exception_handler
48 .globl asm_vm_call_method_end
50 .globl asm_handle_exception
51 .globl asm_handle_nat_exception
53 .globl asm_abstractmethoderror
58 /* asm_vm_call_method **********************************************************
60 This function calls a Java-method (which possibly needs compilation)
61 with up to 4 address parameters.
63 This functions calls the JIT-compiler which eventually translates the
64 method into machine code.
66 *******************************************************************************/
73 .word 0 /* FrameSize */
74 .word 0 /* CodeinfoPointer */
77 asm_vm_call_method_int:
78 asm_vm_call_method_long:
79 asm_vm_call_method_float:
80 asm_vm_call_method_double:
81 SAVE_SCRATCH_REGISTERS /* save our personal scratch regs */
82 stmfd sp!, {v1} /* V1 is used to remember SP */
83 str a0, [sp, #-4]! /* store methods entrypoint */
85 mov v1, sp /* remember SP */
87 mov itmp1, a1 /* address of data structure */
88 mov itmp3, a2 /* stack argument count */
90 ldr a0, [itmp1], #8 /* load argument registers */
95 cmp itmp3, #0 /* do we have stack arguments? */
96 ble asm_calljava_copyfinish /* no -> do not care :-) */
99 sub sp, sp, itmp3, lsl #3 /* create stackframe for arguments */
100 asm_calljava_copyloop: /* reorder stack arguments! */
101 ldr ip, [itmp1], #4 /* load argument */
102 str ip, [sp, itmp2] /* store argument on stack */
103 add itmp2, itmp2, #4 /* next stackslot */
104 ldr ip, [itmp1], #4 /* load argument */
105 str ip, [sp, itmp2] /* store argument on stack */
106 add itmp2, itmp2, #4 /* next stackslot */
107 subs itmp3, itmp3, #1 /* next argument */
108 bgt asm_calljava_copyloop
110 asm_calljava_copyfinish:
111 mov mptr, v1 /* set method pointer */
113 /* REMEMBER: do the method call just like in java! */
114 ldr ip, [mptr] /* fake virtual function call */
118 sub ip, pc, #(fake - asm_vm_call_method)+8
120 mov sp, v1 /* restore SP */
121 add sp, sp, #4 /* free fake address */
123 RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
125 asm_vm_call_method_exception_handler:
126 mov a0, xptr /* exception pointer is arg1 */
127 bl builtin_throw_exception /* throw the exception */
128 mov res1, #0 /* return NULL */
129 mov res2, #0 /* return NULL */
130 mov sp, v1 /* restore SP */
131 add sp, sp, #4 /* free fake address */
133 RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
135 asm_vm_call_method_end:
138 /********************* function asm_handle_exception ***************************
140 * This function handles an exception. It does not use the usual calling *
141 * conventions. The exception pointer is passed in REG_ITMP1 and the *
142 * pc from the exception raising position is passed in REG_ITMP2. It searches *
143 * the local exception table for a handler. If no one is found, it unwinds *
144 * stacks and continues searching the callers. *
146 * void asm_handle_exception (exceptionptr, exceptionpc); *
148 *******************************************************************************/
150 asm_handle_nat_exception:
151 /*TODO:maybe make a macro out of it!!!*/
152 SAVE_ARGUMENT_REGISTERS
154 bl md_asm_codegen_get_pv_from_pc
156 RESTORE_ARGUMENT_REGISTERS
159 asm_handle_exception:
160 stmfd sp!, {r0 - r3} /* save possible used registers */
161 mov itmp3, #1 /* set maybe-leaf flag */
162 mov a3, #(4*4) /* prepare a3 for handle_exception */
164 asm_handle_exception_loop:
165 stmfd sp!, {ip,lr} /* call exception helper here! */
166 mov a0, xptr /* pass exception pointer */
167 mov a1, xpc /* pass exception pointer */
168 mov a2, ip /* pass data segment pointer */
169 add a3, sp, a3 /* calculate Java sp into a3... */
171 bl exceptions_handle_exception
175 beq asm_handle_exception_not_catched
177 mov xpc, a0 /* move handlerpc into xpc */
178 tst itmp3,itmp3 /* if this is a lead method ... */
179 ldmnefd sp!, {r0 - r3} /* restore argument registers */
181 mov pc, xpc /* jump to handler */
183 asm_handle_exception_not_catched:
184 tst itmp3,itmp3 /* if this is a lead method ... */
185 addne sp, sp, #(4*4) /* remove maybe-leaf stackframe */
186 movne itmp3, #0 /* remove maybe-leaf flag */
188 ldr a2, [ip, #FrameSize] /* t2 = frame size */
189 add a0, sp, a2 /* t0 = pointer to save area */
190 ldr a1, [ip, #IsLeaf] /* t1 = is leaf procedure */
191 tst a1, a1 /* if is leaf ... */
192 ldreq lr, [a0, #-4]! /* ... restore RA */
193 mov xpc, lr /* the new xpc is RA */
195 ldr a1, [ip, #IntSave] /* t1 = saved int register count */
196 rsb a1, a1, #5 /* t1 = count of unsaved registers */
198 add pc, pc, a1, lsl #2 /* do not load unsaved registers */
199 ldr v1, [a0, #-20] /* ... but restore the other ones */
205 add sp, sp, a2 /* unwind stack (using t2) */
206 mov a3, #0 /* prepare a3 for handle_exception */
208 /*TODO:maybe make a macro out of it!!!*/
209 SAVE_ARGUMENT_REGISTERS
211 bl md_asm_codegen_get_pv_from_pc
213 RESTORE_ARGUMENT_REGISTERS
215 b asm_handle_exception_loop
218 /* asm_abstractmethoderror *****************************************************
220 Creates and throws an AbstractMethodError.
222 *******************************************************************************/
224 asm_abstractmethoderror:
225 stmfd sp!, {lr} /* save return address */
226 add a0, sp, #(1*4) /* pass java sp */
227 mov a1, lr /* pass exception address */
228 bl exceptions_asm_new_abstractmethoderror
229 ldmfd sp!, {lr} /* restore return address */
231 mov xptr, res1 /* get exception pointer */
232 sub xpc, lr, #4 /* exception address is ra - 4 */
233 b asm_handle_nat_exception
236 /********************* function asm_cacheflush *********************************
238 * TODO: document me *
240 * void asm_cacheflush(void *p, s4 size); *
242 *******************************************************************************/
244 L___ARM_NR_cacheflush:
246 .word __ARM_NR_cacheflush
252 #if defined(__ARM_EABI__)
253 /* According to EABI, the syscall number should be passed via R7,
254 see "http://wiki.debian.org/ArmEabiPort" for additional details. */
257 ldr r7, L___ARM_NR_cacheflush
262 /* TWISTI: required on iyonix, maybe a linux-2.4 bug */
267 swi __ARM_NR_cacheflush
273 /* disable exec-stacks ********************************************************/
275 #if defined(__linux__) && defined(__ELF__)
276 .section .note.GNU-stack,"",%progbits
281 * These are local overrides for various environment variables in Emacs.
282 * Please do not remove this and leave it at the end of the file, where
283 * Emacs will automagically detect them.
284 * ---------------------------------------------------------------------
287 * indent-tabs-mode: t
291 * vim:noexpandtab:sw=4:ts=4: