* src/vm/jit/arm/asmpart.S: Designate function labels as such; required for
[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         .type  asm_vm_call_method, %function
44         .globl asm_vm_call_method_int
45         .type  asm_vm_call_method_int, %function
46         .globl asm_vm_call_method_long
47         .type  asm_vm_call_method_long, %function
48         .globl asm_vm_call_method_float
49         .type  asm_vm_call_method_float, %function
50         .globl asm_vm_call_method_double
51         .type  asm_vm_call_method_double, %function
52         .globl asm_vm_call_method_exception_handler
53         .globl asm_vm_call_method_end
54
55         .globl asm_handle_exception
56         .globl asm_handle_nat_exception
57
58         .globl asm_abstractmethoderror
59
60         .globl asm_cacheflush
61         .type  asm_cacheflush, %function
62
63
64 /* asm_vm_call_method **********************************************************
65
66    This function calls a Java-method (which possibly needs compilation)
67    with up to 4 address parameters.
68
69    This functions calls the JIT-compiler which eventually translates the
70    method into machine code.
71
72 *******************************************************************************/
73
74         .align  2
75
76         .word   0                           /* FltSave                            */
77         .word   0                           /* IntSave                            */
78         .word   0                           /* IsLeaf                             */
79         .word   0                           /* FrameSize                          */
80         .word   0                           /* CodeinfoPointer                    */
81
82 asm_vm_call_method:
83 asm_vm_call_method_int:
84 asm_vm_call_method_long:
85 asm_vm_call_method_float:
86 asm_vm_call_method_double:
87         SAVE_SCRATCH_REGISTERS            /* save our personal scratch regs   */
88         stmfd sp!, {v1}                   /* V1 is used to remember SP        */
89         str   a0, [sp, #-4]!              /* store methods entrypoint         */
90
91         mov   v1, sp                      /* remember SP                      */
92
93         mov   itmp1, a1                   /* address of data structure        */
94         mov   itmp3, a2                   /* stack argument count             */
95
96         ldr   a0, [itmp1], #8             /* load argument registers          */
97         ldr   a1, [itmp1], #8
98         ldr   a2, [itmp1], #8
99         ldr   a3, [itmp1], #8
100
101         cmp   itmp3, #0                   /* do we have stack arguments?      */
102         ble   asm_calljava_copyfinish     /* no -> do not care :-)            */
103
104         mov   itmp2, #0
105         sub   sp, sp, itmp3, lsl #3       /* create stackframe for arguments  */
106 asm_calljava_copyloop:                /* reorder stack arguments!         */
107         ldr   ip, [itmp1], #4             /* load argument                    */
108         str   ip, [sp, itmp2]             /* store argument on stack          */
109         add   itmp2, itmp2, #4            /* next stackslot                   */
110         ldr   ip, [itmp1], #4             /* load argument                    */
111         str   ip, [sp, itmp2]             /* store argument on stack          */
112         add   itmp2, itmp2, #4            /* next stackslot                   */
113         subs  itmp3, itmp3, #1            /* next argument                    */
114         bgt   asm_calljava_copyloop
115
116 asm_calljava_copyfinish:
117         mov   mptr, v1                    /* set method pointer               */
118
119         /* REMEMBER: do the method call just like in java! */
120         ldr   ip, [mptr]                  /* fake virtual function call       */
121         mov   lr, pc
122         mov   pc, ip
123 fake:
124         sub   ip, pc, #(fake - asm_vm_call_method)+8
125
126         mov   sp, v1                      /* restore SP                       */
127         add   sp, sp, #4                  /* free fake address                */
128         ldmfd sp!, {v1}
129         RESTORE_SCRATCH_REGS_AND_RETURN   /* return to caller, restore regs   */
130
131 asm_vm_call_method_exception_handler:
132         mov   a0, xptr                    /* exception pointer is arg1        */
133         bl    builtin_throw_exception     /* throw the exception              */
134         mov   res1, #0                    /* return NULL                      */
135         mov   res2, #0                    /* return NULL                      */
136         mov   sp, v1                      /* restore SP                       */
137         add   sp, sp, #4                  /* free fake address                */
138         ldmfd sp!, {v1}
139         RESTORE_SCRATCH_REGS_AND_RETURN   /* return to caller, restore regs   */
140
141 asm_vm_call_method_end:
142
143
144 /********************* function asm_handle_exception ***************************
145 *                                                                              *
146 *   This function handles an exception. It does not use the usual calling      *
147 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
148 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
149 *   the local exception table for a handler. If no one is found, it unwinds    *
150 *   stacks and continues searching the callers.                                *
151 *                                                                              *
152 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
153 *                                                                              *
154 *******************************************************************************/
155
156 asm_handle_nat_exception:
157         /*TODO:maybe make a macro out of it!!!*/
158         SAVE_ARGUMENT_REGISTERS  
159         mov   a0, lr
160         bl    md_asm_codegen_get_pv_from_pc
161         mov   ip, res1
162         RESTORE_ARGUMENT_REGISTERS  
163         /* fall through */
164
165 asm_handle_exception:
166         stmfd sp!, {r0 - r3}               /* save possible used registers    */
167         mov   itmp3, #1                    /* set maybe-leaf flag             */
168         mov   a3, #(4*4)                   /* prepare a3 for handle_exception */
169
170 asm_handle_exception_loop:
171         stmfd sp!, {ip,lr}                 /* call exception helper here!     */
172         mov   a0, xptr                     /* pass exception pointer          */
173         mov   a1, xpc                      /* pass exception pointer          */
174         mov   a2, ip                       /* pass data segment pointer       */
175         add   a3, sp, a3                   /* calculate Java sp into a3...    */
176         add   a3, a3, #(2*4)
177         bl    exceptions_handle_exception
178         ldmfd sp!, {ip,lr}
179
180         tst   a0, a0
181         beq   asm_handle_exception_not_catched
182
183         mov   xpc, a0                      /* move handlerpc into xpc         */
184         tst   itmp3,itmp3                  /* if this is a lead method ...    */
185         ldmnefd sp!, {r0 - r3}             /* restore argument registers      */
186
187         mov   pc, xpc                      /* jump to handler                 */
188
189 asm_handle_exception_not_catched:
190         tst   itmp3,itmp3                  /* if this is a lead method ...    */
191         addne sp, sp, #(4*4)               /* remove maybe-leaf stackframe    */
192         movne itmp3, #0                    /* remove maybe-leaf flag          */
193
194         ldr   a2, [ip, #FrameSize]         /* t2 = frame size                 */
195         add   a0, sp, a2                   /* t0 = pointer to save area       */
196         ldr   a1, [ip, #IsLeaf]            /* t1 = is leaf procedure          */
197         tst   a1, a1                       /* if is leaf ...                  */
198         ldreq lr, [a0, #-4]!               /* ... restore RA                  */
199         mov   xpc, lr                      /* the new xpc is RA               */
200
201         ldr   a1, [ip, #IntSave]           /* t1 = saved int register count   */
202         rsb   a1, a1, #5                   /* t1 = count of unsaved registers */
203         sub   a1, a1, #1
204         add   pc, pc, a1, lsl #2           /* do not load unsaved registers   */
205         ldr   v1, [a0, #-20]               /* ... but restore the other ones  */
206         ldr   v2, [a0, #-16]
207         ldr   v3, [a0, #-12]
208         ldr   v4, [a0, #- 8]
209         ldr   v5, [a0, #- 4]
210
211         add   sp, sp, a2                   /* unwind stack (using t2)         */
212         mov   a3, #0                       /* prepare a3 for handle_exception */
213
214         /*TODO:maybe make a macro out of it!!!*/
215         SAVE_ARGUMENT_REGISTERS  
216         mov   a0, lr
217         bl    md_asm_codegen_get_pv_from_pc
218         mov   ip, res1
219         RESTORE_ARGUMENT_REGISTERS  
220
221         b     asm_handle_exception_loop
222
223
224 /* asm_abstractmethoderror *****************************************************
225
226    Creates and throws an AbstractMethodError.
227
228 *******************************************************************************/
229
230 asm_abstractmethoderror:
231         stmfd sp!, {lr}                     /* save return address                */
232         add   a0, sp, #(1*4)                /* pass java sp                       */
233         mov   a1, lr                        /* pass exception address             */
234         bl    exceptions_asm_new_abstractmethoderror
235         ldmfd sp!, {lr}                     /* restore return address             */
236
237         mov   xptr, res1                    /* get exception pointer              */
238         sub   xpc, lr, #4                   /* exception address is ra - 4        */
239         b     asm_handle_nat_exception
240
241                 
242 /********************* function asm_cacheflush *********************************
243 *                                                                              *
244 *   TODO: document me                                                          *
245 *                                                                              *
246 *   void asm_cacheflush(void *p, s4 size);                                     *
247 *                                                                              *
248 *******************************************************************************/
249
250 L___ARM_NR_cacheflush:
251         .align 2
252         .word __ARM_NR_cacheflush
253
254 asm_cacheflush:
255         add   a1, a0, a1
256         mov   a2, #0
257
258 #if defined(__ARM_EABI__)
259         /* According to EABI, the syscall number should be passed via R7,
260            see "http://wiki.debian.org/ArmEabiPort" for additional details. */
261
262         stmfd sp!, {r7}
263         ldr   r7, L___ARM_NR_cacheflush
264         swi   0x0
265         ldmfd sp!, {r7}
266 #else
267 # if 0
268         /* TWISTI: required on iyonix, maybe a linux-2.4 bug */
269         mov   a0, #0x0
270         mov   a1, #0xff000000
271 # endif
272
273         swi   __ARM_NR_cacheflush
274 #endif
275
276         mov   pc, lr
277
278
279 /* disable exec-stacks ********************************************************/
280
281 #if defined(__linux__) && defined(__ELF__)
282         .section .note.GNU-stack,"",%progbits
283 #endif
284
285
286 /*
287  * These are local overrides for various environment variables in Emacs.
288  * Please do not remove this and leave it at the end of the file, where
289  * Emacs will automagically detect them.
290  * ---------------------------------------------------------------------
291  * Local variables:
292  * mode: asm
293  * indent-tabs-mode: t
294  * c-basic-offset: 4
295  * tab-width: 4
296  * End:
297  * vim:noexpandtab:sw=4:ts=4:
298  */