1 /* src/vm/jit/arm/asmpart.S - Java-C interface functions for ARM
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: asmpart.S 7932 2007-05-22 07:00:57Z michi $
32 #include "vm/jit/arm/offsets.h"
33 #include "vm/jit/arm/md-asm.h"
35 #include "vm/jit/methodheader.h"
43 /* export functions ***********************************************************/
45 .globl asm_vm_call_method
46 .globl asm_vm_call_method_int
47 .globl asm_vm_call_method_long
48 .globl asm_vm_call_method_float
49 .globl asm_vm_call_method_double
50 .globl asm_vm_call_method_exception_handler
51 .globl asm_vm_call_method_end
53 .globl asm_call_jit_compiler
55 .globl asm_handle_exception
56 .globl asm_handle_nat_exception
58 .globl asm_abstractmethoderror
60 .globl asm_patcher_wrapper
64 .globl asm_getclassvalues_atomic
65 .globl asm_criticalsections
68 #if !defined(ENABLE_THREADS)
70 .word _no_threads_exceptionptr
74 .word asm_call_jit_compiler
77 #if defined(ENABLE_THREADS)
85 /* asm_vm_call_method **********************************************************
87 This function calls a Java-method (which possibly needs compilation)
88 with up to 4 address parameters.
90 This functions calls the JIT-compiler which eventually translates the
91 method into machine code.
93 *******************************************************************************/
97 .word 0 /* catch type all */
98 .word 0 /* handler pc */
100 .word 0 /* start pc */
101 .word 1 /* extable size */
102 .word 0 /* line number table start */
103 .word 0 /* line number table size */
104 .word 0 /* FltSave */
105 .word 0 /* IntSave */
108 .word 0 /* FrameSize */
109 .word 0 /* CodeinfoPointer */
112 asm_vm_call_method_int:
113 asm_vm_call_method_long:
114 /* asm_vm_call_method_float:
115 asm_vm_call_method_double: */
116 SAVE_SCRATCH_REGISTERS /* save our personal scratch regs */
117 stmfd sp!, {v1} /* V1 is used to recompute SP ... */
118 mov v1, #0 /* ... when using stack arguments */
119 ldr ip, asm_jitcompilerptr
120 str ip, [sp, #-4]! /* store fake address */
121 mov mptr, sp /* set method pointer */
123 mov itmp1, a0 /* pass methodinfo* via ITMP1 */
125 cmp a1, #0 /* do we have arguments? */
126 ble asm_calljava_copyfinish /* no -> do not care :-) */
128 /* REMEMBER: stack space for arguments is reserved here! */
129 /* TODO: we possibly reserve to much here */
130 mov v1, a1, lsl #3 /* how much stack do we alloc? */
131 sub sp, sp, v1 /* allocate stack for arguments! */
133 mov itmp3, #0 /* stack position */
134 asm_calljava_copyloop: /* reorder stack arguments! */
135 #if defined(__ARMEL__)
136 ldr ip, [a2,#offvmargtype] /* align 2_WORD_TYPEs */
139 addne itmp3, itmp3, #4
140 ldr ip, [a2,#offvmargdata] /* get LOW word of argument */
143 ldr ip, [a2,#offvmargtype] /* is it a 2_WORD_TYPE? */
145 ldrne ip, [a2,#offvmargdata + 4] /* yes -> get HIGH word of argument */
146 strne ip, [sp, itmp3]
147 addne itmp3, itmp3, #4
148 #else /* defined(__ARMEB__) */
149 ldr ip, [a2,#offvmargtype + 4] /* get our item type (it is u8) */
150 tst ip, #1 /* align 2_WORD_TYPEs */
152 addne itmp3, itmp3, #4
153 teq ip, #2 /* is it a TYPE_FLOAT? */
154 ldreq ip, [a2,#offvmargdata] /* yes -> get LOW word of float */
155 streq ip, [sp, itmp3]
156 addeq itmp3, itmp3, #4
157 beq asm_calljava_copydone
158 tst ip, #1 /* is it a 2_WORD_TYPE? */
159 ldrne ip, [a2,#offvmargdata] /* yes -> get HIGH word of argument */
160 strne ip, [sp, itmp3]
161 addne itmp3, itmp3, #4
162 ldr ip, [a2,#offvmargdata + 4] /* get LOW word of argument */
165 asm_calljava_copydone:
167 add a2, a2, #sizevmarg /* next argument block */
169 bgt asm_calljava_copyloop
171 /* REMEMBER: first four args are passed in regs, take them out again */
172 ldmfd sp, {a0, a1, a2, a3} /* load first four args to register */
173 cmp v1, #16 /* do we have four arguments? */
179 asm_calljava_copyfinish:
180 /* REMEMBER: do the method call just like in java! */
181 ldr ip, [mptr] /* fake virtual function call */
185 sub ip, pc, #(fake2 - asm_vm_call_method)+8
187 add sp, sp, v1 /* free stack arguments! */
188 add sp, sp, #4 /* free fake address */
190 RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
192 asm_vm_call_method_exception_handler:
193 mov a0, xptr /* exception pointer is arg1 */
194 bl builtin_throw_exception /* throw the exception */
195 mov res1, #0 /* return NULL */
196 mov res2, #0 /* return NULL */
197 add sp, sp, v1 /* free stack arguments! */
198 add sp, sp, #4 /* free fake address */
200 RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
202 asm_vm_call_method_float:
205 asm_vm_call_method_double:
209 asm_vm_call_method_end:
212 /****************** function asm_call_jit_compiler *****************************
214 * Invokes the compiler for untranslated JavaVM methods. *
215 * What this method does: *
216 * - save args and LR *
217 * - fire up jit_compile (pass methodinfo pointer) *
218 * - try to find out where to write back the new method pointer *
219 * - restore args and LR *
220 * - check for exceptions *
221 * - eventually write back new method pointer *
222 * - call jit code (wich will then return to caller) *
224 * These methods can call us: codegen_compilerstub & asm_calljavafunction *
225 * ATTENTION: use REG_ITMP1 to pass methodinfo pointer to me! *
227 *******************************************************************************/
229 #define MYSTACKSIZE (6*4)
231 asm_call_jit_compiler:
232 SAVE_ARGUMENT_REGISTERS /* save our argument registers & LR */
233 sub sp, sp, #4 /* keep stack 8-byte aligned */
235 mov a0, itmp1 /* pass methodinfo pointer */
236 mov a1, mptr /* pass method pointer */
237 add a2, sp, #MYSTACKSIZE /* pass Java sp */
238 mov a3, lr /* pass Java RA (correct for leafs) */
240 mov itmp1, res1 /* save pointer to new jit-code */
242 tst itmp1,itmp1 /* check for exeption */
243 beq L_asm_call_jit_compiler_exception
245 add sp, sp, #4 /* keep stack 8-byte aligned */
246 RESTORE_ARGUMENT_REGISTERS /* load our argument registers & LR */
249 mov pc, ip /* call jit-code */
251 L_asm_call_jit_compiler_exception:
252 bl exceptions_get_and_clear_exception
253 mov xptr, res1 /* get exception */
255 add sp, sp, #4 /* keep stack 8-byte aligned */
256 RESTORE_ARGUMENT_REGISTERS /* load LR */
258 sub xpc, lr, #4 /* xpc = instruction that called us */
259 b asm_handle_nat_exception
262 /********************* function asm_handle_exception ***************************
264 * This function handles an exception. It does not use the usual calling *
265 * conventions. The exception pointer is passed in REG_ITMP1 and the *
266 * pc from the exception raising position is passed in REG_ITMP2. It searches *
267 * the local exception table for a handler. If no one is found, it unwinds *
268 * stacks and continues searching the callers. *
270 * void asm_handle_exception (exceptionptr, exceptionpc); *
272 *******************************************************************************/
274 asm_handle_nat_exception:
275 /*TODO:maybe make a macro out of it!!!*/
276 SAVE_ARGUMENT_REGISTERS
278 bl md_codegen_get_pv_from_pc
280 RESTORE_ARGUMENT_REGISTERS
283 asm_handle_exception:
284 stmfd sp!, {r0 - r3} /* save possible used registers */
285 mov itmp3, #1 /* set maybe-leaf flag */
286 mov a3, #(4*4) /* prepare a3 for handle_exception */
288 asm_handle_exception_loop:
289 stmfd sp!, {ip,lr} /* call exception helper here! */
290 mov a0, xptr /* pass exception pointer */
291 mov a1, xpc /* pass exception pointer */
292 mov a2, ip /* pass data segment pointer */
293 add a3, sp, a3 /* calculate Java sp into a3... */
295 bl exceptions_handle_exception
299 beq asm_handle_exception_not_catched
301 mov xpc, a0 /* move handlerpc into xpc */
302 tst itmp3,itmp3 /* if this is a lead method ... */
303 ldmnefd sp!, {r0 - r3} /* restore argument registers */
305 mov pc, xpc /* jump to handler */
307 asm_handle_exception_not_catched:
308 tst itmp3,itmp3 /* if this is a lead method ... */
309 addne sp, sp, #(4*4) /* remove maybe-leaf stackframe */
310 movne itmp3, #0 /* remove maybe-leaf flag */
312 ldr a2, [ip, #FrameSize] /* t2 = frame size */
313 add a0, sp, a2 /* t0 = pointer to save area */
314 ldr a1, [ip, #IsLeaf] /* t1 = is leaf procedure */
315 tst a1, a1 /* if is leaf ... */
316 ldreq lr, [a0, #-4]! /* ... restore RA */
317 mov xpc, lr /* the new xpc is RA */
319 ldr a1, [ip, #IntSave] /* t1 = saved int register count */
320 rsb a1, a1, #5 /* t1 = count of unsaved registers */
322 add pc, pc, a1, lsl #2 /* do not load unsaved registers */
323 ldr v1, [a0, #-20] /* ... but restore the other ones */
329 add sp, sp, a2 /* unwind stack (using t2) */
330 mov a3, #0 /* prepare a3 for handle_exception */
332 /*TODO:maybe make a macro out of it!!!*/
333 SAVE_ARGUMENT_REGISTERS
335 bl md_codegen_get_pv_from_pc
337 RESTORE_ARGUMENT_REGISTERS
339 b asm_handle_exception_loop
342 /* asm_patcher_wrapper *********************************************************
344 * TODO: document me *
346 * Stack layout when calling patcher function: *
347 * 28 empty because stack needs to be aligned *
348 * 24 saved REG_ITMP3, should be restored ( -8) *
349 * 20 data segment displacement from load instructions (-12) *
350 * 16 return address into JIT code (patch position) (-16) *
351 * 12 pointer to virtual java_objectheader *
352 * 8 machine code (which is patched back later) *
353 * [ 8 result of patcher function (indicates exception) ] *
354 * 4 unresolved class/method/field reference *
355 * [ 0 patcher function pointer to call ] *
356 * 0 saved IP of caller (caller needs it!) *
358 *******************************************************************************/
360 #define PATCHSTACKSIZE 8*4
363 mov itmp3, sp /* preserve original SP in ITMP3 */
365 SAVE_ARGUMENT_REGISTERS_IP /* save our argument registers & LR */
366 SAVE_FLOAT_REGISTERS /* save our float registers here */
368 mov a0, itmp3 /* pass SP of patcher stub */
369 mov a1, ip /* pass PV */
370 mov a2, lr /* pass RA (correct for leafs) */
372 mov itmp3, res1 /* save return value */
374 RESTORE_FLOAT_REGISTERS /* restore our float registers here */
375 RESTORE_ARGUMENT_REGISTERS_IP /* load our argument registers & LR */
377 add sp, sp, #PATCHSTACKSIZE /* remove patcher stack frame */
379 tst itmp3, itmp3 /* check for an exception */
380 bne L_asm_patcher_wrapper_exception
382 ldr itmp3, [sp, #-8] /* restore ITMP3 for calling method */
383 ldr pc, [sp, #-16] /* jump to new patched code */
385 L_asm_patcher_wrapper_exception:
386 mov xptr, itmp3 /* get exception */
387 ldr xpc, [sp, #-16] /* RA is xpc */
389 /* Note: A normal branch instruction could modify the PV here, */
390 /* so we use this construct instead. */
392 .word asm_handle_exception
395 /* asm_abstractmethoderror *****************************************************
397 Creates and throws an AbstractMethodError.
399 *******************************************************************************/
401 asm_abstractmethoderror:
402 stmfd sp!, {lr} /* save return address */
403 add a0, sp, #(1*4) /* pass java sp */
404 mov a1, lr /* pass exception address */
405 bl exceptions_asm_new_abstractmethoderror
406 ldmfd sp!, {lr} /* restore return address */
408 mov xptr, res1 /* get exception pointer */
409 sub xpc, lr, #4 /* exception address is ra - 4 */
410 b asm_handle_nat_exception
413 /********************* function asm_cacheflush *********************************
415 * TODO: document me *
417 * void asm_cacheflush(void *p, s4 size); *
419 *******************************************************************************/
422 .equ sys_cacheflush, 0x9f0002
428 /* TWISTI: required on iyonix, maybe a linux-2.4 bug */
429 /* TODO: repeair this! */
430 /* cacheflush is messed up beyond all repair! */
440 /********************* function asm_getclassvalues_atomic *********************/
442 asm_getclassvalues_atomic:
443 stmfd sp!, {r4, r5, r6}
446 ldr r4,[a0,#offbaseval]
447 ldr r5,[a0,#offdiffval]
448 ldr r6,[a1,#offbaseval]
450 str r4,[a2,#offcast_super_baseval]
451 str r5,[a2,#offcast_super_diffval]
452 str r6,[a2,#offcast_sub_baseval]
453 ldmfd sp!, {r4, r5, r6}
457 /* disable exec-stacks ********************************************************/
459 #if defined(__linux__) && defined(__ELF__)
460 .section .note.GNU-stack,"",%progbits
465 * These are local overrides for various environment variables in Emacs.
466 * Please do not remove this and leave it at the end of the file, where
467 * Emacs will automagically detect them.
468 * ---------------------------------------------------------------------
471 * indent-tabs-mode: t
475 * vim:noexpandtab:sw=4:ts=4: