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