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