* Merged executionstate branch.
[cacao.git] / src / vm / jit / arm / asmpart.S
1 /* src/vm/jit/arm/asmpart.S - Java-C interface functions for ARM
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
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.
12
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.
17
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
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <sys/syscall.h>
29
30 #include "vm/jit/arm/md-asm.h"
31
32 #include "vm/jit/methodheader.h"
33
34
35         .file "asmpart.S"
36         .text
37         .align 2
38
39
40 /* export functions ***********************************************************/
41
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
49
50         .globl asm_call_jit_compiler
51
52         .globl asm_handle_exception
53         .globl asm_handle_nat_exception
54
55         .globl asm_abstractmethoderror
56
57         .globl asm_cacheflush
58
59
60 /* asm_vm_call_method **********************************************************
61
62    This function calls a Java-method (which possibly needs compilation)
63    with up to 4 address parameters.
64
65    This functions calls the JIT-compiler which eventually translates the
66    method into machine code.
67
68 *******************************************************************************/
69
70         .align  2
71
72         .word   0                           /* FltSave                            */
73         .word   0                           /* IntSave                            */
74         .word   0                           /* IsLeaf                             */
75         .word   0                           /* FrameSize                          */
76         .word   0                           /* CodeinfoPointer                    */
77
78 asm_vm_call_method:
79 asm_vm_call_method_int:
80 asm_vm_call_method_long:
81 /* asm_vm_call_method_float:
82 asm_vm_call_method_double: */
83         SAVE_SCRATCH_REGISTERS            /* save our personal scratch regs   */
84         stmfd sp!, {v1}                   /* V1 is used to remember SP        */
85         str   a0, [sp, #-4]!              /* store methods entrypoint         */
86
87         mov   v1, sp                      /* remember SP                      */
88
89         mov   itmp1, a1                   /* address of data structure        */
90         mov   itmp3, a2                   /* stack argument count             */
91
92         ldr   a0, [itmp1], #8             /* load argument registers          */
93         ldr   a1, [itmp1], #8
94         ldr   a2, [itmp1], #8
95         ldr   a3, [itmp1], #8
96
97         cmp   itmp3, #0                   /* do we have stack arguments?      */
98         ble   asm_calljava_copyfinish     /* no -> do not care :-)            */
99
100         mov   itmp2, #0
101         sub   sp, sp, itmp3, lsl #3       /* create stackframe for arguments  */
102 asm_calljava_copyloop:                /* reorder stack arguments!         */
103         ldr   ip, [itmp1], #4             /* load argument                    */
104         str   ip, [sp, itmp2]             /* store argument on stack          */
105         add   itmp2, itmp2, #4            /* next stackslot                   */
106         ldr   ip, [itmp1], #4             /* load argument                    */
107         str   ip, [sp, itmp2]             /* store argument on stack          */
108         add   itmp2, itmp2, #4            /* next stackslot                   */
109         subs  itmp3, itmp3, #1            /* next argument                    */
110         bgt   asm_calljava_copyloop
111
112 asm_calljava_copyfinish:
113         mov   mptr, v1                    /* set method pointer               */
114
115         /* REMEMBER: do the method call just like in java! */
116         ldr   ip, [mptr]                  /* fake virtual function call       */
117         mov   lr, pc
118         mov   pc, ip
119 fake:
120         sub   ip, pc, #(fake - asm_vm_call_method)+8
121
122         mov   sp, v1                      /* restore SP                       */
123         add   sp, sp, #4                  /* free fake address                */
124         ldmfd sp!, {v1}
125         RESTORE_SCRATCH_REGS_AND_RETURN   /* return to caller, restore regs   */
126
127 asm_vm_call_method_exception_handler:
128         mov   a0, xptr                    /* exception pointer is arg1        */
129         bl    builtin_throw_exception     /* throw the exception              */
130         mov   res1, #0                    /* return NULL                      */
131         mov   res2, #0                    /* return NULL                      */
132         mov   sp, v1                      /* restore SP                       */
133         add   sp, sp, #4                  /* free fake address                */
134         ldmfd sp!, {v1}
135         RESTORE_SCRATCH_REGS_AND_RETURN   /* return to caller, restore regs   */
136
137 asm_vm_call_method_float:
138         mov a0,#0x51
139         b asm_debug
140 asm_vm_call_method_double:
141         mov a0,#0x52
142         b asm_debug
143
144 asm_vm_call_method_end:
145
146
147 /****************** function asm_call_jit_compiler *****************************
148 *                                                                              *
149 *   Invokes the compiler for untranslated JavaVM methods.                      *
150 *   What this method does:                                                     *
151 *    - save args and LR                                                        *
152 *    - fire up jit_compile (pass methodinfo pointer)                           *
153 *    - try to find out where to write back the new method pointer              *
154 *    - restore args and LR                                                     *
155 *    - check for exceptions                                                    *
156 *    - eventually write back new method pointer                                *
157 *    - call jit code (wich will then return to caller)                         *
158 *                                                                              *
159 *   These methods can call us: codegen_compilerstub & asm_calljavafunction     *
160 *   ATTENTION: use REG_ITMP1 to pass methodinfo pointer to me!                 *
161 *                                                                              *
162 *******************************************************************************/
163
164 #define MYSTACKSIZE (6*4)
165
166 asm_call_jit_compiler:
167         SAVE_ARGUMENT_REGISTERS             /* save our argument registers & LR   */
168         sub   sp, sp, #4                    /* keep stack 8-byte aligned          */
169
170         mov   a0, itmp1                     /* pass methodinfo pointer            */
171         mov   a1, mptr                      /* pass method pointer                */
172         add   a2, sp, #MYSTACKSIZE          /* pass Java sp                       */
173         mov   a3, lr                        /* pass Java RA (correct for leafs)   */
174         bl    jit_asm_compile
175         mov   itmp1, res1                   /* save pointer to new jit-code       */
176
177         tst   itmp1,itmp1                   /* check for exeption                 */
178         beq   L_asm_call_jit_compiler_exception
179
180         add   sp, sp, #4                    /* keep stack 8-byte aligned          */
181         RESTORE_ARGUMENT_REGISTERS          /* load our argument registers & LR   */
182
183         mov   ip, itmp1
184         mov   pc, ip                        /* call jit-code                      */
185
186 L_asm_call_jit_compiler_exception:
187         bl    exceptions_get_and_clear_exception
188         mov   xptr, res1                    /* get exception                      */
189
190         add   sp, sp, #4                    /* keep stack 8-byte aligned          */
191         RESTORE_ARGUMENT_REGISTERS          /* load LR                            */
192
193         sub   xpc, lr, #4                   /* xpc = instruction that called us   */
194         b     asm_handle_nat_exception
195
196
197 /********************* function asm_handle_exception ***************************
198 *                                                                              *
199 *   This function handles an exception. It does not use the usual calling      *
200 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
201 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
202 *   the local exception table for a handler. If no one is found, it unwinds    *
203 *   stacks and continues searching the callers.                                *
204 *                                                                              *
205 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
206 *                                                                              *
207 *******************************************************************************/
208
209 asm_handle_nat_exception:
210         /*TODO:maybe make a macro out of it!!!*/
211         SAVE_ARGUMENT_REGISTERS  
212         mov   a0, lr
213         bl    md_asm_codegen_get_pv_from_pc
214         mov   ip, res1
215         RESTORE_ARGUMENT_REGISTERS  
216         /* fall through */
217
218 asm_handle_exception:
219         stmfd sp!, {r0 - r3}               /* save possible used registers    */
220         mov   itmp3, #1                    /* set maybe-leaf flag             */
221         mov   a3, #(4*4)                   /* prepare a3 for handle_exception */
222
223 asm_handle_exception_loop:
224         stmfd sp!, {ip,lr}                 /* call exception helper here!     */
225         mov   a0, xptr                     /* pass exception pointer          */
226         mov   a1, xpc                      /* pass exception pointer          */
227         mov   a2, ip                       /* pass data segment pointer       */
228         add   a3, sp, a3                   /* calculate Java sp into a3...    */
229         add   a3, a3, #(2*4)
230         bl    exceptions_handle_exception
231         ldmfd sp!, {ip,lr}
232
233         tst   a0, a0
234         beq   asm_handle_exception_not_catched
235
236         mov   xpc, a0                      /* move handlerpc into xpc         */
237         tst   itmp3,itmp3                  /* if this is a lead method ...    */
238         ldmnefd sp!, {r0 - r3}             /* restore argument registers      */
239
240         mov   pc, xpc                      /* jump to handler                 */
241
242 asm_handle_exception_not_catched:
243         tst   itmp3,itmp3                  /* if this is a lead method ...    */
244         addne sp, sp, #(4*4)               /* remove maybe-leaf stackframe    */
245         movne itmp3, #0                    /* remove maybe-leaf flag          */
246
247         ldr   a2, [ip, #FrameSize]         /* t2 = frame size                 */
248         add   a0, sp, a2                   /* t0 = pointer to save area       */
249         ldr   a1, [ip, #IsLeaf]            /* t1 = is leaf procedure          */
250         tst   a1, a1                       /* if is leaf ...                  */
251         ldreq lr, [a0, #-4]!               /* ... restore RA                  */
252         mov   xpc, lr                      /* the new xpc is RA               */
253
254         ldr   a1, [ip, #IntSave]           /* t1 = saved int register count   */
255         rsb   a1, a1, #5                   /* t1 = count of unsaved registers */
256         sub   a1, a1, #1
257         add   pc, pc, a1, lsl #2           /* do not load unsaved registers   */
258         ldr   v1, [a0, #-20]               /* ... but restore the other ones  */
259         ldr   v2, [a0, #-16]
260         ldr   v3, [a0, #-12]
261         ldr   v4, [a0, #- 8]
262         ldr   v5, [a0, #- 4]
263
264         add   sp, sp, a2                   /* unwind stack (using t2)         */
265         mov   a3, #0                       /* prepare a3 for handle_exception */
266
267         /*TODO:maybe make a macro out of it!!!*/
268         SAVE_ARGUMENT_REGISTERS  
269         mov   a0, lr
270         bl    md_asm_codegen_get_pv_from_pc
271         mov   ip, res1
272         RESTORE_ARGUMENT_REGISTERS  
273
274         b     asm_handle_exception_loop
275
276
277 /* asm_abstractmethoderror *****************************************************
278
279    Creates and throws an AbstractMethodError.
280
281 *******************************************************************************/
282
283 asm_abstractmethoderror:
284         stmfd sp!, {lr}                     /* save return address                */
285         add   a0, sp, #(1*4)                /* pass java sp                       */
286         mov   a1, lr                        /* pass exception address             */
287         bl    exceptions_asm_new_abstractmethoderror
288         ldmfd sp!, {lr}                     /* restore return address             */
289
290         mov   xptr, res1                    /* get exception pointer              */
291         sub   xpc, lr, #4                   /* exception address is ra - 4        */
292         b     asm_handle_nat_exception
293
294                 
295 /********************* function asm_cacheflush *********************************
296 *                                                                              *
297 *   TODO: document me                                                          *
298 *                                                                              *
299 *   void asm_cacheflush(void *p, s4 size);                                     *
300 *                                                                              *
301 *******************************************************************************/
302
303 L___ARM_NR_cacheflush:
304         .align 2
305         .word __ARM_NR_cacheflush
306
307 asm_cacheflush:
308         add   a1, a0, a1
309         mov   a2, #0
310
311 #if defined(__ARM_EABI__)
312         /* According to EABI, the syscall number should be passed via R7,
313            see "http://wiki.debian.org/ArmEabiPort" for additional details. */
314
315         stmfd sp!, {r7}
316         ldr   r7, L___ARM_NR_cacheflush
317         swi   0x0
318         ldmfd sp!, {r7}
319 #else
320 # if 0
321         /* TWISTI: required on iyonix, maybe a linux-2.4 bug */
322         mov   a0, #0x0
323         mov   a1, #0xff000000
324 # endif
325
326         swi   __ARM_NR_cacheflush
327 #endif
328
329         mov   pc, lr
330
331
332 /* disable exec-stacks ********************************************************/
333
334 #if defined(__linux__) && defined(__ELF__)
335         .section .note.GNU-stack,"",%progbits
336 #endif
337
338
339 /*
340  * These are local overrides for various environment variables in Emacs.
341  * Please do not remove this and leave it at the end of the file, where
342  * Emacs will automagically detect them.
343  * ---------------------------------------------------------------------
344  * Local variables:
345  * mode: asm
346  * indent-tabs-mode: t
347  * c-basic-offset: 4
348  * tab-width: 4
349  * End:
350  * vim:noexpandtab:sw=4:ts=4:
351  */