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