Merged with tip.
[cacao.git] / src / vm / jit / m68k / asmpart.S
1 /* src/vm/jit/m68k/asmpart.S - Java-C interface functions for m68k
2
3    Copyright (C) 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 "md-abi.h"
31
32 #include "vm/jit/methodheader.h"
33
34
35 .text
36
37 .globl asm_vm_call_method
38 .globl asm_vm_call_method_int
39 .globl asm_vm_call_method_long
40 .globl asm_vm_call_method_float
41 .globl asm_vm_call_method_double
42 .globl asm_vm_call_method_end
43 .globl asm_vm_call_method_exception_handler
44
45 .globl asm_abstractmethoderror
46
47 .globl asm_handle_exception
48 .globl asm_handle_nat_exception
49
50 /*
51  *      This functions implement the C prototyped funtion
52  *      java_objectheader *asm_vm_call_method(methodinfo *m, s4 vmargscount,vm_arg *vmargs);
53  *      the _int, _long, _float, _double are used for different return types
54  *
55  *      The function may still be uncompiled, so the jit compiler gets invoked.
56  *
57  *
58  */
59
60         /* this is the method header see src/vm/jit/methodheader.h */
61
62         .align  4
63
64         .long   0                           /* fltsave                            */
65         .long   0                           /* intsave                            */
66         .long   0                           /* isleaf                             */
67         .long   0                           /* frame size                         */
68         .long   0                           /* codeinfo pointer                   */
69
70
71 /*
72         This method gets called with 3 arguments:
73         1st arg: addres of method to call (fake invokevirtual here)
74         2nd arg: uint64_t array of argument registers followed by stack 
75         3rd arg: number of 8 byte stack slots to be copied.
76
77         coldifire does not use any argument registers, so just the stack has to be copied
78 */
79 asm_vm_call_method:
80 asm_vm_call_method_int:
81 asm_vm_call_method_long:
82 asm_vm_call_method_float:
83 asm_vm_call_method_double:
84
85 #if defined(ENABLE_SOFTFLOAT)
86         addal   #(-12*4),%sp                                            /* create stackframe to save registers, and 1 slot for method invocation */
87         moveml  %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@        /* save registers */
88
89         /* fetch arguments from vmargs data structure */
90         movel   %sp@(12*4+1*4),%a3                              /* method */
91         movel   %sp@(12*4+2*4),%a2                              /* arg array */
92         movel   %sp@(12*4+3*4),%d2                              /* arg count */
93
94         movel   %a3, %sp@(11*4)                                 /* copy method address to stackslot */
95         leal    %sp@(11*4), %a3                                 /* and store that address in %a3 */
96 #else
97         addal #(-12*4-6*8), %sp
98         moveml  %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp,%sp@        /* save registers */
99         fmovemd %fp2/%fp3/%fp4/%fp5/%fp6/%fp7,%sp@(11*4)                        /* save registers */
100
101         /* fetch arguments from vmargs data structure */
102         movel   %sp@(12*4+6*8+1*4),%a3                          /* method */
103         movel   %sp@(12*4+6*8+2*4),%a2                          /* arg array */
104         movel   %sp@(12*4+6*8+3*4),%d2                          /* arg count */
105
106         movel   %a3, %sp@(11*4+6*8)                                     /* copy method address to stackslot */
107         leal    %sp@(11*4+6*8), %a3                                     /* and store that address in %a3 */
108 #endif
109
110         moveal  %sp, %a5                                        /* memorize stack */
111
112         tstl    %d2                                                     /* do we have arguments ? */
113         beq     L_asm_vm_call_method_copy_done
114         movel   %d2, %d3                                                /* create stackframe */
115         asll    #3,  %d3                                                /* number args * 8 */
116         subal   %d3, %sp                        
117         moveal  %sp, %a4                                                /* %a4 is temp stack pointer */
118
119 L_asm_vm_call_method_copy_loop:
120         movel   %a2@(0), %d3
121         movel   %d3, %a4@(0)                                    /* copy 4 bytes */
122         movel   %a2@(4), %d3
123         movel   %d3, %a4@(4)                                    /* a whole stack slot has been copied */
124
125         addal   #8, %a2
126         addal   #8, %a4
127         addl    #-1, %d2
128         tstl    %d2                                                             /* do we have more arguments ? */
129         beq     L_asm_vm_call_method_copy_done
130         br      L_asm_vm_call_method_copy_loop
131
132
133 L_asm_vm_call_method_copy_done:
134         /* now we fake method invocation as it would happen from invokevirtual */
135         /* this is needed as we patch the caller site, so we need a writeable slot */
136         /* %a3 points to the address containing the method, %a3 == REG_METHODPTR */
137
138         moveal  %a3@(0), %a4
139         jsr     %a4@
140
141 L_asm_vm_call_method_return:
142         movel   %a5, %sp                                                /* pop arguments off stack */
143
144 #if defined(ENABLE_SOFTFLOAT)
145         moveml  %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp       /* restore registers */
146         addal   #(12*4),%sp                                             /* restore stack */
147 #else
148         fmovemd %sp@(12*4), %fp2/%fp3/%fp4/%fp5/%fp6/%fp7                       /* restore registers */
149         moveml  %sp@, %d2/%d3/%d4/%d5/%d6/%d7/%a2/%a3/%a4/%a5/%fp       /* restore registers */
150         addal   #(12*4+6*8),%sp                                         /* restore stack */
151 #endif
152         moveal  %d0, %a0                                                /* XXX return value in %a0, too, gcc sometimes expects addresses in %a0, wired */
153 asm_vm_call_method_end:                                         /* symbol needed to insert method into avl tree */
154         rts                                                                             /* return to c code */
155
156 /* asm_vm_call_method_exception_handler ********************************************************************
157  *
158  * calls void *builtin_throw_exception(java_objectheader *xptr) when no other handler is appropiate
159  * this functions gets called indirectly from asm_handle_exception, which back then moved xptr to %a2
160  * clear software design is in the eye of the beholder.
161  ************************************************************************************************************/
162 asm_vm_call_method_exception_handler:
163         movel   %a2, %sp@-                      /* push xptr argument */
164         jsr     builtin_throw_exception
165         lea     %sp@(4), %sp                    /* pop arg off stack */
166         jmp     L_asm_vm_call_method_return
167
168
169 asm_abstractmethoderror:
170
171 /* asm_handle_exception ********************************************************
172 *                                                                              *
173 *   This function handles an exception. It does not use the usual calling      *
174 *   conventions. The exception pointer is passed in REG_ATMP1 and the          *
175 *   pc from the exception raising position is passed in REG_ATMP2. It searches *
176 *   the local exception table for a handler. If no one is found, it unwinds    *
177 *   stacks and continues searching the callers.                                *
178 *                                                                              *
179 *   void asm_handle_exception (void);
180 *   exception object pointer...%a2   exception raising address...%a3           *
181 *                                                                              *
182 *******************************************************************************/
183 asm_handle_nat_exception:
184         lea     %sp@(4), %sp
185 asm_handle_exception:
186 L_asm_handle_exception_stack_loop:
187         /* save temporary registers */
188         movel   %d0, %sp@-
189         movel   %d1, %sp@-
190         movel   %a0, %sp@-
191         movel   %a1, %sp@-
192 #if !defined(ENABLE_SOFTFLOAT)
193         addal   #-8*2, %sp
194         fmovemd %fp0, %sp@(0)
195         fmovemd %fp1, %sp@(8)
196 #endif
197
198         /* we need the dseg, figure it out */
199         movel   %a3, %sp@-                              /* push ra argument */
200         jsr     md_asm_codegen_get_pv_from_pc   /* pv in %d0 now */
201         movel   %d0, %d2                                /* move to safe register */
202         lea     %sp@(4), %sp                            /* pop args off stack */
203
204         /* now call the following c function */
205         /* u1 *exceptions_handle_exception(java_objectheader *xptr, u1 *xpc, u1 *pv, u1 *sp) */
206 #if !defined(ENABLE_SOFTFLOAT)
207         pea             %sp@(4*4 + 8*2)
208 #else
209         pea             %sp@(4*4)
210 #endif
211         movel   %d2,%sp@-
212         movel   %a3,%sp@-
213         movel   %a2,%sp@-
214         jsr     exceptions_handle_exception             /* %d0 is address of handler or 0 when not catched */
215         lea     %sp@(4*4), %sp                          /* pop args off stack */
216         tstl    %d0
217         beq     L_asm_handle_exception_not_catched
218
219         /* %d0 contains address of exception handler */
220         moveal  %d0, %a3
221
222         /* restore temporary registers */
223         moveal  %sp@+, %a1
224         moveal  %sp@+, %a0
225         movel   %sp@+, %d1
226         movel   %sp@+, %d0
227 #if !defined(ENABLE_SOFTFLOAT)
228         fmovemd %fp0, %sp@(0)
229         fmovemd %fp1, %sp@(8)
230         addal   #8*2, %sp
231 #endif
232
233         jmp     %a3@
234
235 L_asm_handle_exception_not_catched:
236         /* we did not find an exception handler in this stackframe */
237         /* remove this frame and search in the one above */
238         /* %a2 containts exception object ptr, %d2 the actual pv */
239
240         /* remove temporary registers stored */
241 #if !defined(ENABLE_SOFTFLOAT)
242         addal   #4*4 + 8*2, %sp
243 #else
244         addal   #4*4, %sp
245 #endif
246
247         moveal  %d2, %a3
248         movel   %a3@(FrameSize), %d2
249
250         moveal  %sp, %a0
251         addal   %d2, %a0        /* %a0 now points to top of stackframe, where saved regs are */
252
253         /* the saved registers have to be restored */
254         /* XXX ugly hack: intsave and adrsave share one field */
255         movel   %a3@(IntSave), %d0
256         andil   #0x0000ffff, %d0        /* this is IntSave */
257         cmpb    #0,%d0
258         beq     L_asm_handle_ex_int_done
259         movel   -(%a0), %d7
260
261         cmpb    #1,%d0
262         beq     L_asm_handle_ex_int_done
263         movel   -(%a0), %d6
264
265         cmpb    #2,%d0 
266         beq     L_asm_handle_ex_int_done
267         movel   -(%a0), %d5
268
269 L_asm_handle_ex_int_done:
270
271         movel   %a3@(IntSave), %d0
272         andil   #0xffff0000, %d0        /* this is AdrSave */
273         lsrl    #8, %d0
274         lsrl    #8, %d0
275
276 #if 0
277         cmpb    #0, %d0
278         beq     L_asm_handle_ex_adr_done
279         moveal  -(%a0), %a5
280 #else
281         cmpb    #0, %d0
282         beq     L_asm_handle_ex_adr_done
283         moveal  -(%a0), %fp
284
285         cmpb    #1,%d0
286         beq     L_asm_handle_ex_adr_done
287         moveal  -(%a0), %a5
288 #endif
289
290 L_asm_handle_ex_adr_done:
291
292 #if !defined(ENABLE_SOFTFLOAT)
293         movel   %a3@(FltSave), %d0
294         cmpb    #0,%d0
295         beq     L_asm_handle_ex_flt_done
296         fmovemd %a0@(-8), %fp7
297
298         cmpb    #1,%d0
299         beq     L_asm_handle_ex_flt_done
300         fdmoved %a0@(-16), %fp6
301         
302         cmpb    #2,%d0
303         beq     L_asm_handle_ex_flt_done
304         fdmoved %a0@(-24), %fp5
305
306 L_asm_handle_ex_flt_done:
307 #else
308         /* nothing to do */
309 #endif
310         addal   %d2, %sp                /* remove old stackframe */
311         moveal  %sp@+, %a3              /* make return address, new exception rasing address */
312         subal   #2, %a3                 /* it was a jsr %aX, which is 4 bytes long */
313         jmp     L_asm_handle_exception_stack_loop
314
315
316 illegal
317 .long 0x23234242
318
319
320 /*
321  * These are local overrides for various environment variables in Emacs.
322  * Please do not remove this and leave it at the end of the file, where
323  * Emacs will automagically detect them.
324  * ---------------------------------------------------------------------
325  * Local variables:
326  * mode: c
327  * indent-tabs-mode: t
328  * c-basic-offset: 4
329  * tab-width: 4
330  * End:
331  * vim:noexpandtab:sw=4:ts=4:
332  */