1 /* src/vm/jit/arm/asmpart.S - Java-C interface functions for ARM
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: Michael Starzinger
29 Changes: Christian Thalinger
31 $Id: asmpart.S 6541 2006-08-22 14:48:01Z twisti $
38 #include "vm/jit/arm/offsets.h"
39 #include "vm/jit/arm/md-asm.h"
41 #include "vm/jit/methodheader.h"
49 /* export functions ***********************************************************/
51 .globl asm_vm_call_method
52 .globl asm_vm_call_method_int
53 .globl asm_vm_call_method_long
54 .globl asm_vm_call_method_float
55 .globl asm_vm_call_method_double
56 .globl asm_vm_call_method_exception_handler
58 .globl asm_call_jit_compiler
60 .globl asm_handle_exception
61 .globl asm_handle_nat_exception
63 .globl asm_abstractmethoderror
65 .globl asm_patcher_wrapper
69 .globl asm_getclassvalues_atomic
70 .globl asm_criticalsections
73 #if !defined(ENABLE_THREADS)
75 .word _no_threads_exceptionptr
79 .word asm_call_jit_compiler
82 #if defined(ENABLE_THREADS)
90 /* asm_vm_call_method **********************************************************
92 This function calls a Java-method (which possibly needs compilation)
93 with up to 4 address parameters.
95 This functions calls the JIT-compiler which eventually translates the
96 method into machine code.
98 *******************************************************************************/
102 .word 0 /* catch type all */
103 .word 0 /* handler pc */
105 .word 0 /* start pc */
106 .word 1 /* extable size */
107 .word 0 /* line number table start */
108 .word 0 /* line number table size */
109 .word 0 /* FltSave */
110 .word 0 /* IntSave */
113 .word 0 /* FrameSize */
114 .word 0 /* CodeinfoPointer */
117 asm_vm_call_method_int:
118 asm_vm_call_method_long:
119 /* asm_vm_call_method_float:
120 asm_vm_call_method_double: */
121 SAVE_SCRATCH_REGISTERS /* save our personal scratch regs */
122 stmfd sp!, {v1} /* V1 is used to recompute SP ... */
123 mov v1, #0 /* ... when using stack arguments */
124 ldr ip, asm_jitcompilerptr
125 str ip, [sp, #-4]! /* store fake address */
126 mov mptr, sp /* set method pointer */
128 mov itmp1, a1 /* pass methodinfo* via ITMP1 */
130 cmp a2, #0 /* do we have arguments? */
131 ble asm_calljava_copyfinish /* no -> do not care :-) */
133 /* REMEMBER: stack space for arguments is reserved here! */
134 /* TODO: we possibly reserve to much here */
135 mov v1, a2, lsl #3 /* how much stack do we alloc? */
136 sub sp, sp, v1 /* allocate stack for arguments! */
138 mov itmp3, #0 /* stack position */
139 asm_calljava_copyloop: /* reorder stack arguments! */
140 #if defined(__ARMEL__)
141 ldr ip, [a3,#offvmargdata] /* get LOW word of argument */
144 ldr ip, [a3,#offvmargtype] /* is it a 2_WORD_TYPE? */
146 ldrne ip, [a3,#offvmargdata + 4] /* yes -> get HIGH word of argument */
147 strne ip, [sp, itmp3]
148 addne itmp3, itmp3, #4
149 #else /* defined(__ARMEB__) */
150 ldr ip, [a3,#offvmargtype + 4] /* get our item type (it is u8) */
151 teq ip, #2 /* is it a TYPE_FLOAT? */
152 ldreq ip, [a3,#offvmargdata] /* yes -> get LOW word of float */
153 streq ip, [sp, itmp3]
154 addeq itmp3, itmp3, #4
155 beq asm_calljava_copydone
156 tst ip, #1 /* is it a 2_WORD_TYPE? */
157 ldrne ip, [a3,#offvmargdata] /* yes -> get HIGH word of argument */
158 strne ip, [sp, itmp3]
159 addne itmp3, itmp3, #4
160 ldr ip, [a3,#offvmargdata + 4] /* get LOW word of argument */
163 asm_calljava_copydone:
165 add a3, a3, #sizevmarg /* next argument block */
167 bgt asm_calljava_copyloop
169 /* REMEMBER: first four args are passed in regs, take them out again */
170 ldmfd sp, {a1, a2, a3, a4} /* load first four args to register */
171 cmp v1, #16 /* do we have four arguments? */
177 asm_calljava_copyfinish:
178 /* REMEMBER: do the method call just like in java! */
179 ldr ip, [mptr] /* fake virtual function call */
183 sub ip, pc, #(fake2 - asm_vm_call_method)+8
185 add sp, sp, v1 /* free stack arguments! */
186 add sp, sp, #4 /* free fake address */
188 RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
190 asm_vm_call_method_exception_handler:
191 mov a1, xptr /* exception pointer is arg1 */
192 bl builtin_throw_exception /* throw the exception */
193 mov res1, #0 /* return NULL */
194 mov res2, #0 /* return NULL */
195 add sp, sp, v1 /* free stack arguments! */
196 add sp, sp, #4 /* free fake address */
198 RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
200 asm_vm_call_method_float:
203 asm_vm_call_method_double:
208 /****************** function asm_call_jit_compiler *****************************
210 * Invokes the compiler for untranslated JavaVM methods. *
211 * What this method does: *
212 * - save args and LR *
213 * - fire up jit_compile (pass methodinfo pointer) *
214 * - try to find out where to write back the new method pointer *
215 * - restore args and LR *
216 * - check for exceptions *
217 * - eventually write back new method pointer *
218 * - call jit code (wich will then return to caller) *
220 * These methods can call us: codegen_compilerstub & asm_calljavafunction *
221 * ATTENTION: use REG_ITMP1 to pass methodinfo pointer to me! *
223 *******************************************************************************/
225 #define MYSTACKSIZE (5*4)
227 asm_call_jit_compiler:
228 SAVE_ARGUMENT_REGISTERS /* save our argument registers & LR */
230 mov a1, itmp1 /* pass methodinfo pointer */
231 mov a2, mptr /* pass method pointer */
232 add a3, sp, #MYSTACKSIZE /* pass Java sp */
233 mov a4, lr /* pass Java RA (correct for leafs) */
235 mov itmp1, res1 /* save pointer to new jit-code */
237 tst itmp1,itmp1 /* check for exeption */
238 beq L_asm_call_jit_compiler_exception
240 RESTORE_ARGUMENT_REGISTERS /* load our argument registers & LR */
243 mov pc, ip /* call jit-code */
245 L_asm_call_jit_compiler_exception:
246 bl exceptions_get_and_clear_exception
247 mov xptr, res1 /* get exception */
249 RESTORE_ARGUMENT_REGISTERS /* load LR */
251 sub xpc, lr, #4 /* xpc = instruction that called us */
252 b asm_handle_nat_exception
255 /********************* function asm_handle_exception ***************************
257 * This function handles an exception. It does not use the usual calling *
258 * conventions. The exception pointer is passed in REG_ITMP1 and the *
259 * pc from the exception raising position is passed in REG_ITMP2. It searches *
260 * the local exception table for a handler. If no one is found, it unwinds *
261 * stacks and continues searching the callers. *
263 * void asm_handle_exception (exceptionptr, exceptionpc); *
265 *******************************************************************************/
267 asm_handle_nat_exception:
268 /*TODO:maybe make a macro out of it!!!*/
269 SAVE_ARGUMENT_REGISTERS
271 bl md_codegen_get_pv_from_pc
273 RESTORE_ARGUMENT_REGISTERS
276 asm_handle_exception:
277 stmfd sp!, {r0 - r3} /* save possible used registers */
278 mov itmp3, #1 /* set maybe-leaf flag */
279 mov a4, #(4*4) /* prepare a4 for handle_exception */
281 asm_handle_exception_loop:
282 stmfd sp!, {ip,lr} /* call exception helper here! */
283 mov a1, xptr /* pass exception pointer */
284 mov a2, xpc /* pass exception pointer */
285 mov a3, ip /* pass data segment pointer */
286 add a4, sp, a4 /* calculate Java sp into a4... */
288 bl exceptions_handle_exception
292 beq asm_handle_exception_not_catched
294 mov xpc, a1 /* move handlerpc into xpc */
295 tst itmp3,itmp3 /* if this is a lead method ... */
296 ldmnefd sp!, {r0 - r3} /* restore argument registers */
298 mov pc, xpc /* jump to handler */
300 asm_handle_exception_not_catched:
301 tst itmp3,itmp3 /* if this is a lead method ... */
302 addne sp, sp, #(4*4) /* remove maybe-leaf stackframe */
303 movne itmp3, #0 /* remove maybe-leaf flag */
305 ldr a3, [ip, #FrameSize] /* t2 = frame size */
306 add a1, sp, a3 /* t0 = pointer to save area */
307 ldr a2, [ip, #IsLeaf] /* t1 = is leaf procedure */
308 tst a2, a2 /* if is leaf ... */
309 ldreq lr, [a1, #-4]! /* ... restore RA */
310 mov xpc, lr /* the new xpc is RA */
312 ldr a2, [ip, #IntSave] /* t1 = saved int register count */
313 rsb a2, a2, #5 /* t1 = count of unsaved registers */
315 add pc, pc, a2, lsl #2 /* do not load unsaved registers */
316 ldr v1, [a1, #-20] /* ... but restore the other ones */
322 add sp, sp, a3 /* unwind stack (using t2) */
323 mov a4, #0 /* prepare a4 for handle_exception */
325 /*TODO:maybe make a macro out of it!!!*/
326 SAVE_ARGUMENT_REGISTERS
328 bl md_codegen_get_pv_from_pc
330 RESTORE_ARGUMENT_REGISTERS
332 b asm_handle_exception_loop
335 /* asm_patcher_wrapper *********************************************************
337 * TODO: document me *
339 * Stack layout when calling patcher function: *
340 * 24 saved REG_ITMP3, should be restored ( -4) *
341 * 20 data segment displacement from load instructions ( -8) *
342 * 16 return address into JIT code (patch position) (-12) *
343 * 12 pointer to virtual java_objectheader *
344 * 8 machine code (which is patched back later) *
345 * [ 8 result of patcher function (indicates exception) ] *
346 * 4 unresolved class/method/field reference *
347 * [ 0 patcher function pointer to call ] *
348 * 0 saved IP of caller (caller needs it!) *
350 *******************************************************************************/
352 #define PATCHSTACKSIZE 7*4
355 mov itmp3, sp /* preserve original SP in ITMP3 */
357 SAVE_ARGUMENT_REGISTERS_IP /* save our argument registers & LR */
358 SAVE_FLOAT_REGISTERS /* save our float registers here */
360 mov a1, itmp3 /* pass SP of patcher stub */
361 mov a2, ip /* pass PV */
362 mov a3, lr /* pass RA (correct for leafs) */
364 mov itmp3, res1 /* save return value */
366 RESTORE_FLOAT_REGISTERS /* restore our float registers here */
367 RESTORE_ARGUMENT_REGISTERS_IP /* load our argument registers & LR */
369 tst itmp3, itmp3 /* check for an exception */
370 bne L_asm_patcher_wrapper_exception
372 add sp, sp, #PATCHSTACKSIZE /* remove patcher stack frame */
374 ldr itmp3, [sp, #-4] /* restore ITMP3 for calling method */
375 ldr pc, [sp, #-12] /* jump to new patched code */
377 L_asm_patcher_wrapper_exception:
378 mov xptr, itmp3 /* get exception */
379 ldr xpc, [sp, #16] /* RA is xpc */
381 add sp, sp, #PATCHSTACKSIZE /* remove patcher stack frame */
383 b asm_handle_exception
386 /* asm_abstractmethoderror *****************************************************
388 Creates and throws an AbstractMethodError.
390 *******************************************************************************/
392 asm_abstractmethoderror:
393 stmfd sp!, {lr} /* save return address */
394 add a1, sp, #(1*4) /* pass java sp */
395 mov a2, lr /* pass exception address */
396 bl exceptions_asm_new_abstractmethoderror
397 ldmfd sp!, {lr} /* restore return address */
399 mov xptr, res1 /* get exception pointer */
400 sub xpc, lr, #4 /* exception address is ra - 4 */
401 b asm_handle_nat_exception
404 /********************* function asm_cacheflush *********************************
406 * TODO: document me *
408 * void asm_cacheflush(void *p, s4 size); *
410 *******************************************************************************/
413 .equ sys_cacheflush, 0x9f0002
418 /* TODO: repeair this! */
419 /* cacheflush is messed up beyond all repair! */
429 /* clean and invalidate the entire cache!!! */
435 /********************* function asm_getclassvalues_atomic *********************/
437 asm_getclassvalues_atomic:
438 stmfd sp!, {r4, r5, r6}
441 ldr r4,[a1,#offbaseval]
442 ldr r5,[a1,#offdiffval]
443 ldr r6,[a2,#offbaseval]
445 str r4,[a3,#offcast_super_baseval]
446 str r5,[a3,#offcast_super_diffval]
447 str r6,[a3,#offcast_sub_baseval]
448 ldmfd sp!, {r4, r5, r6}
452 /* Disable exec-stacks, required for Gentoo ***********************************/
454 #if defined(__GCC__) && defined(__ELF__)
455 .section .note.GNU-stack,"",@progbits
460 * These are local overrides for various environment variables in Emacs.
461 * Please do not remove this and leave it at the end of the file, where
462 * Emacs will automagically detect them.
463 * ---------------------------------------------------------------------
466 * indent-tabs-mode: t
470 * vim:noexpandtab:sw=4:ts=4: