/* src/vm/jit/arm/asmpart.S - Java-C interface functions for ARM
- Copyright (C) 1996-2005, 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
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: asmpart.S 7454 2007-03-05 15:40:48Z tbfg $
-
*/
#include "config.h"
-#include "vm/jit/arm/offsets.h"
+#include <sys/syscall.h>
+
#include "vm/jit/arm/md-asm.h"
#include "vm/jit/methodheader.h"
.globl asm_vm_call_method_exception_handler
.globl asm_vm_call_method_end
- .globl asm_call_jit_compiler
-
.globl asm_handle_exception
.globl asm_handle_nat_exception
.globl asm_abstractmethoderror
- .globl asm_patcher_wrapper
-
.globl asm_cacheflush
- .globl asm_getclassvalues_atomic
- .globl asm_criticalsections
-
-
-#if !defined(ENABLE_THREADS)
-asm_exceptionptr:
- .word _no_threads_exceptionptr
-#endif
-
-asm_jitcompilerptr:
- .word asm_call_jit_compiler
-
-asm_criticalsections:
-#if defined(ENABLE_THREADS)
- .word _crit_begin
- .word _crit_end
- .word _crit_restart
-#endif
- .word 0
-
/* asm_vm_call_method **********************************************************
.align 2
- .word 0 /* catch type all */
- .word 0 /* handler pc */
- .word 0 /* end pc */
- .word 0 /* start pc */
- .word 1 /* extable size */
- .word 0 /* line number table start */
- .word 0 /* line number table size */
.word 0 /* FltSave */
.word 0 /* IntSave */
.word 0 /* IsLeaf */
- .word 0 /* IsSync */
.word 0 /* FrameSize */
.word 0 /* CodeinfoPointer */
asm_vm_call_method:
asm_vm_call_method_int:
asm_vm_call_method_long:
-/* asm_vm_call_method_float:
-asm_vm_call_method_double: */
+asm_vm_call_method_float:
+asm_vm_call_method_double:
SAVE_SCRATCH_REGISTERS /* save our personal scratch regs */
- stmfd sp!, {v1} /* V1 is used to recompute SP ... */
- mov v1, #0 /* ... when using stack arguments */
- ldr ip, asm_jitcompilerptr
- str ip, [sp, #-4]! /* store fake address */
- mov mptr, sp /* set method pointer */
+ stmfd sp!, {v1} /* V1 is used to remember SP */
+ str a0, [sp, #-4]! /* store methods entrypoint */
- mov itmp1, a0 /* pass methodinfo* via ITMP1 */
+ mov v1, sp /* remember SP */
- cmp a1, #0 /* do we have arguments? */
- ble asm_calljava_copyfinish /* no -> do not care :-) */
+ mov itmp1, a1 /* address of data structure */
+ mov itmp3, a2 /* stack argument count */
- /* REMEMBER: stack space for arguments is reserved here! */
- /* TODO: we possibly reserve to much here */
- mov v1, a1, lsl #3 /* how much stack do we alloc? */
- sub sp, sp, v1 /* allocate stack for arguments! */
+ ldr a0, [itmp1], #8 /* load argument registers */
+ ldr a1, [itmp1], #8
+ ldr a2, [itmp1], #8
+ ldr a3, [itmp1], #8
+
+ cmp itmp3, #0 /* do we have stack arguments? */
+ ble asm_calljava_copyfinish /* no -> do not care :-) */
- mov itmp3, #0 /* stack position */
+ mov itmp2, #0
+ sub sp, sp, itmp3, lsl #3 /* create stackframe for arguments */
asm_calljava_copyloop: /* reorder stack arguments! */
-#if defined(__ARMEL__)
- ldr ip, [a2,#offvmargdata] /* get LOW word of argument */
- str ip, [sp, itmp3]
- add itmp3, itmp3, #4
- ldr ip, [a2,#offvmargtype] /* is it a 2_WORD_TYPE? */
- tst ip, #1
- ldrne ip, [a2,#offvmargdata + 4] /* yes -> get HIGH word of argument */
- strne ip, [sp, itmp3]
- addne itmp3, itmp3, #4
-#else /* defined(__ARMEB__) */
- ldr ip, [a2,#offvmargtype + 4] /* get our item type (it is u8) */
- teq ip, #2 /* is it a TYPE_FLOAT? */
- ldreq ip, [a2,#offvmargdata] /* yes -> get LOW word of float */
- streq ip, [sp, itmp3]
- addeq itmp3, itmp3, #4
- beq asm_calljava_copydone
- tst ip, #1 /* is it a 2_WORD_TYPE? */
- ldrne ip, [a2,#offvmargdata] /* yes -> get HIGH word of argument */
- strne ip, [sp, itmp3]
- addne itmp3, itmp3, #4
- ldr ip, [a2,#offvmargdata + 4] /* get LOW word of argument */
- str ip, [sp, itmp3]
- add itmp3, itmp3, #4
-asm_calljava_copydone:
-#endif
- add a2, a2, #sizevmarg /* next argument block */
- subs a1, a1, #1
+ ldr ip, [itmp1], #4 /* load argument */
+ str ip, [sp, itmp2] /* store argument on stack */
+ add itmp2, itmp2, #4 /* next stackslot */
+ ldr ip, [itmp1], #4 /* load argument */
+ str ip, [sp, itmp2] /* store argument on stack */
+ add itmp2, itmp2, #4 /* next stackslot */
+ subs itmp3, itmp3, #1 /* next argument */
bgt asm_calljava_copyloop
- /* REMEMBER: first four args are passed in regs, take them out again */
- ldmfd sp, {a0, a1, a2, a3} /* load first four args to register */
- cmp v1, #16 /* do we have four arguments? */
- addlt sp, sp, v1
- movlt v1, #0
- addge sp, sp, #16
- subge v1, v1, #16
-
asm_calljava_copyfinish:
+ mov mptr, v1 /* set method pointer */
+
/* REMEMBER: do the method call just like in java! */
ldr ip, [mptr] /* fake virtual function call */
- mov lr, pc
- mov pc, ip
-fake2:
- sub ip, pc, #(fake2 - asm_vm_call_method)+8
+ mov lr, pc
+ mov pc, ip
+fake:
+ sub ip, pc, #(fake - asm_vm_call_method)+8
- add sp, sp, v1 /* free stack arguments! */
+ mov sp, v1 /* restore SP */
add sp, sp, #4 /* free fake address */
ldmfd sp!, {v1}
RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
bl builtin_throw_exception /* throw the exception */
mov res1, #0 /* return NULL */
mov res2, #0 /* return NULL */
- add sp, sp, v1 /* free stack arguments! */
+ mov sp, v1 /* restore SP */
add sp, sp, #4 /* free fake address */
ldmfd sp!, {v1}
RESTORE_SCRATCH_REGS_AND_RETURN /* return to caller, restore regs */
-asm_vm_call_method_float:
- mov a0,#0x51
- b asm_debug
-asm_vm_call_method_double:
- mov a0,#0x52
asm_vm_call_method_end:
- b asm_debug
-
-
-/****************** function asm_call_jit_compiler *****************************
-* *
-* Invokes the compiler for untranslated JavaVM methods. *
-* What this method does: *
-* - save args and LR *
-* - fire up jit_compile (pass methodinfo pointer) *
-* - try to find out where to write back the new method pointer *
-* - restore args and LR *
-* - check for exceptions *
-* - eventually write back new method pointer *
-* - call jit code (wich will then return to caller) *
-* *
-* These methods can call us: codegen_compilerstub & asm_calljavafunction *
-* ATTENTION: use REG_ITMP1 to pass methodinfo pointer to me! *
-* *
-*******************************************************************************/
-
-#define MYSTACKSIZE (6*4)
-
-asm_call_jit_compiler:
- SAVE_ARGUMENT_REGISTERS /* save our argument registers & LR */
- sub sp, sp, #4 /* keep stack 8-byte aligned */
-
- mov a0, itmp1 /* pass methodinfo pointer */
- mov a1, mptr /* pass method pointer */
- add a2, sp, #MYSTACKSIZE /* pass Java sp */
- mov a3, lr /* pass Java RA (correct for leafs) */
- bl jit_asm_compile
- mov itmp1, res1 /* save pointer to new jit-code */
-
- tst itmp1,itmp1 /* check for exeption */
- beq L_asm_call_jit_compiler_exception
-
- add sp, sp, #4 /* keep stack 8-byte aligned */
- RESTORE_ARGUMENT_REGISTERS /* load our argument registers & LR */
-
- mov ip, itmp1
- mov pc, ip /* call jit-code */
-
-L_asm_call_jit_compiler_exception:
- bl exceptions_get_and_clear_exception
- mov xptr, res1 /* get exception */
-
- add sp, sp, #4 /* keep stack 8-byte aligned */
- RESTORE_ARGUMENT_REGISTERS /* load LR */
-
- sub xpc, lr, #4 /* xpc = instruction that called us */
- b asm_handle_nat_exception
/********************* function asm_handle_exception ***************************
/*TODO:maybe make a macro out of it!!!*/
SAVE_ARGUMENT_REGISTERS
mov a0, lr
- bl md_codegen_get_pv_from_pc
+ bl md_asm_codegen_get_pv_from_pc
mov ip, res1
RESTORE_ARGUMENT_REGISTERS
/* fall through */
/*TODO:maybe make a macro out of it!!!*/
SAVE_ARGUMENT_REGISTERS
mov a0, lr
- bl md_codegen_get_pv_from_pc
+ bl md_asm_codegen_get_pv_from_pc
mov ip, res1
RESTORE_ARGUMENT_REGISTERS
b asm_handle_exception_loop
-/* asm_patcher_wrapper *********************************************************
-* *
-* TODO: document me *
-* *
-* Stack layout when calling patcher function: *
-* 24 saved REG_ITMP3, should be restored ( -4) *
-* 20 data segment displacement from load instructions ( -8) *
-* 16 return address into JIT code (patch position) (-12) *
-* 12 pointer to virtual java_objectheader *
-* 8 machine code (which is patched back later) *
-* [ 8 result of patcher function (indicates exception) ] *
-* 4 unresolved class/method/field reference *
-* [ 0 patcher function pointer to call ] *
-* 0 saved IP of caller (caller needs it!) *
-* *
-*******************************************************************************/
-
-#define PATCHSTACKSIZE 8*4
-
-asm_patcher_wrapper:
- mov itmp3, sp /* preserve original SP in ITMP3 */
-
- SAVE_ARGUMENT_REGISTERS_IP /* save our argument registers & LR */
- SAVE_FLOAT_REGISTERS /* save our float registers here */
-
- mov a0, itmp3 /* pass SP of patcher stub */
- mov a1, ip /* pass PV */
- mov a2, lr /* pass RA (correct for leafs) */
- bl patcher_wrapper
- mov itmp3, res1 /* save return value */
-
- RESTORE_FLOAT_REGISTERS /* restore our float registers here */
- RESTORE_ARGUMENT_REGISTERS_IP /* load our argument registers & LR */
-
- tst itmp3, itmp3 /* check for an exception */
- bne L_asm_patcher_wrapper_exception
-
- add sp, sp, #PATCHSTACKSIZE /* remove patcher stack frame */
-
- ldr itmp3, [sp, #-8] /* restore ITMP3 for calling method */
- ldr pc, [sp, #-16] /* jump to new patched code */
-
-L_asm_patcher_wrapper_exception:
- mov xptr, itmp3 /* get exception */
- ldr xpc, [sp, #16] /* RA is xpc */
-
- add sp, sp, #PATCHSTACKSIZE /* remove patcher stack frame */
-
- b asm_handle_exception
-
-
/* asm_abstractmethoderror *****************************************************
Creates and throws an AbstractMethodError.
* *
*******************************************************************************/
-#if 1
-.equ sys_cacheflush, 0x9f0002
+L___ARM_NR_cacheflush:
+ .align 2
+ .word __ARM_NR_cacheflush
+
asm_cacheflush:
add a1, a0, a1
mov a2, #0
-#if 0
+#if defined(__ARM_EABI__)
+ /* According to EABI, the syscall number should be passed via R7,
+ see "http://wiki.debian.org/ArmEabiPort" for additional details. */
+
+ stmfd sp!, {r7}
+ ldr r7, L___ARM_NR_cacheflush
+ swi 0x0
+ ldmfd sp!, {r7}
+#else
+# if 0
/* TWISTI: required on iyonix, maybe a linux-2.4 bug */
- /* TODO: repeair this! */
- /* cacheflush is messed up beyond all repair! */
- mov a0, #0x0
- mov a1, #0xff000000
-#endif
+ mov a0, #0x0
+ mov a1, #0xff000000
+# endif
- swi #sys_cacheflush
- mov pc, lr
+ swi __ARM_NR_cacheflush
#endif
-
-/********************* function asm_getclassvalues_atomic *********************/
-
-asm_getclassvalues_atomic:
- stmfd sp!, {r4, r5, r6}
-_crit_restart:
-_crit_begin:
- ldr r4,[a0,#offbaseval]
- ldr r5,[a0,#offdiffval]
- ldr r6,[a1,#offbaseval]
-_crit_end:
- str r4,[a2,#offcast_super_baseval]
- str r5,[a2,#offcast_super_diffval]
- str r6,[a2,#offcast_sub_baseval]
- ldmfd sp!, {r4, r5, r6}
mov pc, lr
-/* Disable exec-stacks, required for Gentoo ***********************************/
+/* disable exec-stacks ********************************************************/
-#if defined(__GCC__) && defined(__ELF__)
- .section .note.GNU-stack,"",@progbits
+#if defined(__linux__) && defined(__ELF__)
+ .section .note.GNU-stack,"",%progbits
#endif