48c31fb8af2aa5c2b755954690f7e7c2232b27c7
[cacao.git] / src / vm / jit / s390 / asmpart.S
1 /* src/vm/jit/s390/asmpart.S - Java-C interface functions for s390
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 "vm/jit/s390/arch.h"
31 #include "vm/jit/s390/md-abi.h"
32 #include "vm/jit/s390/md-asm.h"
33
34 #include "vm/jit/abi-asm.h"
35 #include "vm/jit/methodheader.h"
36
37         .text
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_handle_exception
51         .globl asm_handle_nat_exception
52
53         .globl asm_abstractmethoderror
54
55         .globl asm_builtin_f2i
56         .globl asm_builtin_f2l
57         .globl asm_builtin_d2i
58         .globl asm_builtin_d2l
59
60
61 asm_abstractmethoderror:
62         .long 0
63 asm_builtin_f2i:
64         .long 0
65 asm_builtin_f2l:
66         .long 0
67 asm_builtin_d2i:
68         .long 0
69 asm_builtin_d2l:
70         .long 0
71
72 /* Generates a PIC call.
73  *
74  * func: function to call
75  * tag: tag unique for this call to generate a label
76  * tmp: one temporary register needed for calculation
77  *
78  * The offset table used is located at the bottom of this file.
79  *
80  * Note: destroys r12. r12 MUST contain GOT for PIC calls!
81  */
82 #define CALL_PIC(func, tag)                                                         \
83         bras   %r14, L_bras_##tag;                           /* get PC */               \
84 L_bras_##tag:                                                                       \
85         l      %r12, L_offsets - L_bras_##tag (%r14);        /* load offset to PLT */   \
86         la     %r12, L_offsets - L_bras_##tag (%r12, %r14);  /* load PLT address */     \
87         l      %r14, L_offset_##func - L_bras_##tag (%r14);  /* load offset to func */  \
88         bas    %r14, 0(%r14, %r12);
89
90 /********************* function asm_calljavafunction ***************************
91 *                                                                              *
92 *   This function calls a Java-method (which possibly needs compilation)       *
93 *   with up to 4 address parameters.                                           *
94 *                                                                              *
95 *   This functions calls the JIT-compiler which eventually translates the      *
96 *   method into machine code.                                                  *
97 *                                                                              *
98 *   C-prototype:                                                               *
99 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
100 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
101 *                                                                              *
102 *******************************************************************************/
103
104         .long   0                         /* fltsave                              */
105         .long   0                         /* intsave                              */
106         .long   0                         /* IsLeaf                               */
107         .long   0                         /* frame size                           */
108         .long   0                         /* codeinfo pointer                     */
109
110 asm_vm_call_method:
111 asm_vm_call_method_int:
112 asm_vm_call_method_long:
113 asm_vm_call_method_float:
114 asm_vm_call_method_double:
115
116         ahi sp, -8*4                /* allocate stack frame */
117
118         /* a0: PV */
119         /* a1: data structure */
120         /* a2: number of stack arguments */
121
122         st    s0, 0*4(sp)           /* store used calle saved registers */
123         st    s1, 1*4(sp)
124         st    a0, 2*4(sp)
125         st    %r12, 3*4(sp)         /* %r12 is callee saved, we'll need it as GOT */
126         st    pv, 4*4(sp)
127         st    a4, 5*4(sp)           /* a4 is callee saved in terms of C abi */
128         std   ftmp1, 6*4(sp)        /* ftmp1 and ftmp2 are callees saved in terms of C abi */
129         std   ftmp2, 8*4(sp)
130         st    ra, 10*4(sp)
131
132         lr    s0, a1                /* data structure */
133         lr    %r0, a2               /* number of stack arguments */
134
135         l     a0, 0*8+4(s0)         /* big endian */
136         l     a1, 1*8+4(s0)
137         l     a2, 2*8+4(s0)
138         l     a3, 3*8+4(s0)
139         l     a4, 4*8+4(s0)         
140
141         ld    fa0, 5*8(s0)
142         ld    fa1, 6*8(s0)
143
144         lr    s1, sp                /* backup stack pointer */
145
146         ltr   %r0, %r0              /* are there any stack arguments ? */
147         je    L_asm_vm_call_method_stack_copy_done
148         lr    %r1, %r0              /* copy number of stack arguments */
149         sll   %r1, 3                /* calculate stackframe size */ 
150         sr    sp, %r1               /* allocate stack frame */
151         lr    %r1, sp               /* temporary stack pointer */
152
153 L_asm_vm_call_method_stack_copy_loop:
154
155         mvc   0(8, %r1), 7*8(s0)    /* copy argument */
156         ahi   %r1, 8                /* increase sp */
157         ahi   s0, 8                 /* set address of next argument */
158         ahi   %r0, -1               /* substract 1 argument */
159         jh    L_asm_vm_call_method_stack_copy_loop
160
161 L_asm_vm_call_method_stack_copy_done:
162
163         la    mptr, 2*4(s1)         /* load method pointer */
164         l     pv, 0(mptr)           /* load procedure vector from method pointer */
165         basr  ra, pv                /* call method */
166         lr    sp, s1                /* restore stack pointer */
167
168 L_asm_vm_call_method_return:
169
170         l     s0, 0*4(sp)           /* restore used callee saved registers */
171         l     s1, 1*4(sp)
172         l     %r12, 3*4(sp)
173         l     pv, 4*4(sp)
174         l     a4, 5*4(sp)
175         ld    ftmp1, 6*4(sp)
176         ld    ftmp2, 8*4(sp)
177         l     ra, 10*4(sp)
178
179         ahi   sp, 8*4               /* remove stackframe */
180         br    ra                    /* return */
181
182
183 asm_vm_call_method_exception_handler:
184         lr    a0, xptr
185
186         ahi   sp, -96
187         CALL_PIC(builtin_throw_exception, avcmeh)
188         ahi   sp, 96
189
190         j     L_asm_vm_call_method_return
191
192 asm_vm_call_method_end:
193         brc   0,0       
194
195 /* asm_handle_exception ********************************************************
196 *                                                                              *
197 *   This function handles an exception. It does not use the usual calling      *
198 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
199 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
200 *   the local exception table for a handler. If no one is found, it unwinds    *
201 *   stacks and continues searching the callers.                                *
202 *                                                                              *
203 *******************************************************************************/
204
205 asm_handle_nat_exception:
206 L_asm_handle_nat_exception:
207         /* TODO really nothing here ? */
208 asm_handle_exception:
209 L_asm_handle_exception:
210
211         /* a wrapper for md_handle_exception */
212
213 #       define STACKFRAMESIZE (96 + (16 * 4) + (16 * 8) + (4 * 4))
214 #       define REGS 96
215 #       define FREGS (96 + (16 * 4))
216 #       define OUT (96 + (16 * 4) + (16 * 8))
217
218         ahi   sp, -STACKFRAMESIZE   /* allocate stack frame containing the arrays */
219
220         /* store special registers to array */
221
222         st    xptr, REGS+(0*4)(sp)
223         st    xpc, REGS+(1*4)(sp)
224         st    pv, REGS+(13*4)(sp)
225         la    itmp3, STACKFRAMESIZE(sp)
226         st    itmp3, REGS+(15*4)(sp)
227
228         /* store temporary and argument registers */
229
230         stm   a0, a4, REGS+(2*4)(sp)
231         std   %f0, FREGS+(0*8)(sp)
232         std   %f1, FREGS+(1*8)(sp)
233         std   %f2, FREGS+(2*8)(sp)
234         std   %f3, FREGS+(3*8)(sp)
235         std   %f5, FREGS+(5*8)(sp)
236         std   %f7, FREGS+(7*8)(sp)
237         std   %f8, FREGS+(8*8)(sp)
238         std   %f9, FREGS+(9*8)(sp)
239         std   %f10, FREGS+(10*8)(sp)
240         std   %f11, FREGS+(11*8)(sp)
241         std   %f12, FREGS+(12*8)(sp)
242         std   %f13, FREGS+(13*8)(sp)
243         std   %f14, FREGS+(14*8)(sp)
244         std   %f15, FREGS+(15*8)(sp)
245
246         /* store %r12 used as GOT */
247         
248         st    %r12, REGS+(12*4)(sp)
249
250         /* call md_handle_exception */
251
252         la    a0, REGS(sp)
253         la    a1, FREGS(sp)
254         la    a2, OUT(sp)
255
256         CALL_PIC(md_handle_exception, ahe)
257
258         /* restore %r12 */
259
260         l     %r12, REGS+(12*4)(sp)
261
262         l     itmp3, OUT+(2*4)(sp)  /* out[2] contains maybe leaf flag */
263         ltr   itmp3, itmp3           
264         je    L_restore_saved
265
266 L_restore_temporary_and_argument:
267
268         /* if we are maybe leaf,
269          * we have to restore argument and temporary registers
270          */
271
272         lm    a0, a4, REGS+(2*4)(sp)
273         ld    %f0, FREGS+(0*8)(sp)
274         ld    %f1, FREGS+(1*8)(sp)
275         ld    %f2, FREGS+(2*8)(sp)
276         ld    %f3, FREGS+(3*8)(sp)
277         ld    %f5, FREGS+(5*8)(sp)
278         ld    %f7, FREGS+(7*8)(sp)
279         ld    %f8, FREGS+(8*8)(sp)
280         ld    %f9, FREGS+(9*8)(sp)
281         ld    %f10, FREGS+(10*8)(sp)
282         ld    %f11, FREGS+(11*8)(sp)
283         ld    %f12, FREGS+(12*8)(sp)
284         ld    %f13, FREGS+(13*8)(sp)
285         ld    %f14, FREGS+(14*8)(sp)
286         ld    %f15, FREGS+(15*8)(sp)
287
288         j     L_restore_done
289
290 L_restore_saved:
291
292         /* if we are not a maybe leaf,
293          * we have to restore callee saved registers of the callee
294          */
295
296         l     itmp3, OUT+(0*4)(sp)  /* out[0] contains IntSav */
297
298         ahi   itmp3, -1
299         jl    L_int_done
300         l     s5, REGS+(12*4)(sp)
301
302         ahi   itmp3, -1
303         jl    L_int_done
304         l     s4, REGS+(11*4)(sp)
305
306         ahi   itmp3, -1
307         jl    L_int_done
308         l     s3, REGS+(10*4)(sp)
309
310         ahi   itmp3, -1
311         jl    L_int_done
312         l     s2, REGS+(9*4)(sp)
313
314         ahi   itmp3, -1
315         jl    L_int_done
316         l     s1, REGS+(8*4)(sp)
317
318         ahi   itmp3, -1
319         jl    L_int_done
320         l     s0, REGS+(7*4)(sp)
321
322 L_int_done:
323
324         /* restore callee saved float registers */
325
326         /* there are currently none */
327
328 L_flt_done:
329
330 L_restore_done:
331
332         /* write new values for special registers */
333
334         l     xptr, REGS+(0*4)(sp)
335         l     xpc, REGS+(1*4)(sp)
336         l     pv, REGS+(13*4)(sp)  
337         l     sp, REGS+(15*4)(sp)   
338
339         br    xpc                   /* jump to handler */
340
341 #       undef STACKFRAMESIZE
342 #       undef REGS
343 #       undef FREGS
344 #       undef OUT
345
346 #if 0
347
348 /* asm_abstractmethoderror *****************************************************
349
350    Creates and throws an AbstractMethodError.
351
352 *******************************************************************************/
353
354 asm_abstractmethoderror:
355         mov     sp,a0                       /* pass java sp                       */
356         add     $1*8,a0
357         mov     0*8(sp),a1                  /* pass exception address             */
358         sub     $3,a1
359         call    exceptions_asm_new_abstractmethoderror@PLT
360                                             /* exception pointer is return value  */
361         pop     xpc                         /* get exception address              */
362         sub     $3,xpc                      /* exception address is ra - 3        */
363         jmp     L_asm_handle_exception
364
365 #endif
366
367 /* Offset table for PIC calls, see CALL_PIC */
368
369 L_offsets:
370         .long  _GLOBAL_OFFSET_TABLE_ - L_offsets
371 L_offset_builtin_throw_exception:
372         .long  builtin_throw_exception@PLTOFF
373 L_offset_jit_asm_compile:
374         .long  jit_asm_compile@PLTOFF
375 L_offset_exceptions_get_and_clear_exception:
376         .long  exceptions_get_and_clear_exception@PLTOFF
377 L_offset_md_handle_exception:
378         .long  md_handle_exception@PLTOFF
379
380
381 /*
382  * These are local overrides for various environment variables in Emacs.
383  * Please do not remove this and leave it at the end of the file, where
384  * Emacs will automagically detect them.
385  * ---------------------------------------------------------------------
386  * Local variables:
387  * mode: asm
388  * indent-tabs-mode: t
389  * c-basic-offset: 4
390  * tab-width: 4
391  * End:
392  * vim:noexpandtab:sw=4:ts=4:
393  */