Fixes build for newer gcc (at least 4.4), breaks older gcc. We don't care.
[cacao.git] / src / vm / jit / powerpc64 / asmpart.S
1 /* src/vm/jit/powerpc64/asmpart.S - Java-C interface functions for PowerPC64
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.text;  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 #define __ASSEMBLY__
31
32 #include "md-abi.h"
33 #include "md-asm.h"
34
35 #include "vm/jit/abi-asm.h"
36 #include "vm/jit/methodheader.h"
37
38
39 /* export functions ***********************************************************/
40
41         .globl asm_vm_call_method_exception_handler
42         .globl asm_vm_call_method_end
43
44         .globl asm_handle_nat_exception
45         .globl asm_handle_exception
46
47         .globl asm_abstractmethoderror
48
49         .globl asm_cacheflush
50
51
52 /* asm_vm_call_method **********************************************************
53 *                                                                              *
54 *   This function calls a Java-method (which possibly needs compilation)       *
55 *   with up to 4 address parameters.                                           *
56 *                                                                              *
57 *   This functions calls the JIT-compiler which eventually translates the      *
58 *   method into machine code.                                                  *
59 *                                                                              *
60 *   C-prototype:                                                               *
61 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
62 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
63 *                                                                              *
64 *******************************************************************************/
65         /* this is the method header see src/vm/jit/methodheader.h */
66
67         .align  3
68
69         .long   0                           /* fltsave                            */
70         .long   0                           /* intsave                            */
71         .long   0                           /* isleaf                             */
72         .long   0                           /* frame size                         */
73         .quad   0                           /* codeinfo pointer                   */
74
75 #ifdef ENABLE_LIBJVM
76         
77         .globl asm_vm_call_method
78         .globl asm_vm_call_method_int
79         .globl asm_vm_call_method_long
80         .globl asm_vm_call_method_float
81         .globl asm_vm_call_method_double
82         .section ".opd","aw"
83         .align 3
84
85         asm_vm_call_method:
86         asm_vm_call_method_int:
87         asm_vm_call_method_long:
88         asm_vm_call_method_float:
89         asm_vm_call_method_double:
90                 .quad   .asm_vm_call_method,.TOC.@tocbase,0
91                 .previous
92                 .size asm_vm_call_method, 24
93                 .type .asm_vm_call_method,@function
94                 .globl .asm_vm_call_method
95 #else
96         asm_vm_call_method:
97         .globl asm_vm_call_method
98         asm_vm_call_method_int:
99         .globl asm_vm_call_method_int
100         asm_vm_call_method_long:
101         .globl asm_vm_call_method_long
102         asm_vm_call_method_float:
103         .globl asm_vm_call_method_float
104         asm_vm_call_method_double:
105         .globl asm_vm_call_method_double
106 #endif
107
108 .asm_vm_call_method:
109 .asm_vm_call_method_int:
110 .asm_vm_call_method_long:
111 .asm_vm_call_method_float:
112 .asm_vm_call_method_double:
113         mflr    r0
114         std     r0,LA_LR_OFFSET(sp)
115         stdu    sp,-40*8(sp)
116         
117         std     s0,8*8(sp)                /* save used callee saved registers     */
118         std     a0,9*8(sp)                /* save method pointer for compiler     */
119
120         std     pv,11*8(sp)               /* save PV register                     */
121
122         std     itmp3,12*8(sp)            /* registers r14-r31 are callee saved   */
123         stfd    ftmp1,13*8(sp)            /* registers f14-f31 are callee saved   */
124         stfd    ftmp2,14*8(sp)
125
126
127         SAVE_TEMPORARY_REGISTERS(15)     
128         mr      s0, sp                  /* save stack pointer */
129
130         /* a1 contains a pointer to a unit64_t structure filled with all INT_ARG_REG,
131         followed by ADR_ARG_CNT and FLT_ARG_CNT, afterwards what else needs to be copied onto
132         the stack 
133         a2 contains the number of additional stack slots to be copied
134         */
135
136 L_register_copy:
137         mr      t1, a1
138         mr      t2, a2
139
140         ld      a0 ,  0*8(t1)
141         ld      a1 ,  1*8(t1)
142         ld      a2 ,  2*8(t1)
143         ld      a3 ,  3*8(t1)
144         ld      a4 ,  4*8(t1)
145         ld      a5 ,  5*8(t1)
146         ld      a6 ,  6*8(t1)
147         ld      a7 ,  7*8(t1)
148
149         lfd     fa0 , 8*8(t1)
150         lfd     fa1 , 9*8(t1)
151         lfd     fa2 ,10*8(t1)
152         lfd     fa3 ,11*8(t1)
153         lfd     fa4 ,12*8(t1)
154         lfd     fa5 ,13*8(t1)
155         lfd     fa6 ,14*8(t1)
156         lfd     fa7 ,15*8(t1)
157         lfd     fa8 ,16*8(t1)
158         lfd     fa9 ,17*8(t1)
159         lfd     fa10,18*8(t1)
160         lfd     fa11,19*8(t1)
161         lfd     fa12,20*8(t1)
162
163         mr.     t2,t2
164         beq L_stack_copy_done
165
166 L_stack_copy:
167         addi    t1,t1,20*8              /* before first possible stack slot arg */
168         mr      t3,t2                   /* argument counter */
169         sldi    t2,t2,8                 /* calculate size of stack */
170         sub     sp,sp,t2                /* increase the stack */
171         mr      t2,sp                   /* t2 points to bottom of stack now */
172
173 L_stack_copy_loop:
174         addi    t1,t1,8                 /* next possible stack slot to copy */
175         mr.     t3,t3                   /* more stack slots to copy ? */
176         beq     L_stack_copy_done
177         ld      itmp3, 0(t1)
178         std     itmp3, 0(t2)
179         addi    t2,t2,8
180         addi    t3,t3,-1
181         b L_stack_copy_loop
182
183 L_stack_copy_done:
184         mr      itmp1, s0               /* fake invokevirtual invocation */
185         addi    itmp1, itmp1, 9*8       /* address of methods pv */
186         ld      pv,0*8(itmp1)
187         mtctr   pv
188         bctrl
189 1:
190         mflr    itmp1
191         addi    pv,itmp1,(.asm_vm_call_method - 1b)@l
192
193 L_asm_vm_call_method_return:
194         mr      sp,s0                     /* restore the function's sp            */
195
196         ld      s0,8*8(sp)                /* restore used callee saved registers  */
197
198         ld      pv,11*8(sp)               /* save PV register                     */
199
200         ld      itmp3,12*8(sp)
201         lfd     ftmp1,13*8(sp)            /* registers f14-f31 are callee saved   */
202         lfd     ftmp2,14*8(sp)
203
204         RESTORE_TEMPORARY_REGISTERS(15) 
205
206         ld     r0,40*8+LA_LR_OFFSET(sp)
207         mtlr   r0
208         addi   sp,sp,40*8
209         blr
210
211 asm_vm_call_method_exception_handler:
212         mr      r3,itmp1
213         bl      builtin_throw_exception
214         b       L_asm_vm_call_method_return
215
216 asm_vm_call_method_end:
217         nop
218
219
220 /********************* function asm_handle_exception ***************************
221 *                                                                              *
222 *   This function handles an exception. It does not use the usual calling      *
223 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
224 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
225 *   the local exception table for a handler. If no one is found, it unwinds    *
226 *   stacks and continues searching the callers.                                *
227 *                                                                              *
228 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
229 *                                                                              *
230 *******************************************************************************/
231                 
232 asm_handle_nat_exception:
233 L_asm_handle_nat_exception:             /* required for PIC code              */
234 L_asm_handle_exception_stack_loop:
235         mflr    r0
236         addi    sp,sp,-(LA_SIZE+PA_SIZE+((4+6)*8))  /* allocate stack (+4 for darwin)     */
237         std     xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)    /* save exception pointer             */
238         std     xpc,LA_SIZE+PA_SIZE+(4+1)*8(sp)     /* save exception pc                  */
239         std     r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)      /* save return address                */
240         li      itmp3,0
241         std     itmp3,LA_SIZE+PA_SIZE+(4+4)*8(sp)   /* save maybe-leaf flag (cleared)     */
242
243         mr      a0,r0                       /* pass return address                */
244         bl      md_asm_codegen_get_pv_from_pc   /* get PV from RA                 */
245         std     v0,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* save data segment pointer          */
246
247         ld      a0,LA_SIZE+PA_SIZE+(4+0)*8(sp)      /* pass xptr                          */
248         ld      a1,LA_SIZE+PA_SIZE+(4+1)*8(sp)      /* pass xpc                           */
249         ld      a2,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* pass PV (v0 == a0)                 */
250         addi    a3,sp,LA_SIZE+PA_SIZE+((4+6)*8)     /* pass Java SP                       */
251
252         b       L_asm_handle_exception_continue
253
254
255 asm_handle_exception:
256 L_asm_handle_exception:                 /* required for PIC code              */
257         addi    sp,sp,-(ARG_CNT+TMP_CNT)*8  /* create maybe-leaf stackframe       */
258
259         SAVE_ARGUMENT_REGISTERS(0)          /* we save arg and temp registers in  */
260         SAVE_TEMPORARY_REGISTERS(ARG_CNT)   /* case this is a leaf method         */
261
262         addi    sp,sp,-(LA_SIZE+PA_SIZE+(4+6)*8)        /* allocate stack                     */
263         std     xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)        /* save exception pointer             */
264         std     pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)          /* save data segment pointer          */
265         mflr    r0                                      /* save return address                */
266         std     r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)          
267         li      t0, 1
268         std     t0, LA_SIZE+PA_SIZE+(4+4)*8(sp)         /* maybe-leaf flag */
269         
270         mr      a0,xptr                     /* pass exception pointer             */
271         mr      a1,xpc                      /* pass exception pc                  */
272         mr      a2,pv                       /* pass data segment pointer          */
273         addi    a3,sp,LA_SIZE+PA_SIZE+(ARG_CNT+TMP_CNT)*8+(4+6)*8
274
275
276 L_asm_handle_exception_continue:
277         bl      exceptions_handle_exception
278
279         mr.     v0,v0
280         beq     L_asm_handle_exception_not_catched
281
282         mr      xpc,v0                              /* move handlerpc into xpc            */
283         ld      xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)    /* restore exception pointer          */
284         ld      pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)      /* restore data segment pointer       */
285         ld      r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)      /* restore return address             */
286         mtlr    r0
287         ld      t0,LA_SIZE+PA_SIZE+(4+4)*8(sp)      /* get maybe-leaf flag                */
288         addi    sp,sp,LA_SIZE+PA_SIZE+(4+6)*8       /* free stack frame                   */
289
290         mr.     t0,t0
291         beq     L_asm_handle_exception_no_leaf
292
293         RESTORE_ARGUMENT_REGISTERS(0)       /* if this is a leaf method, we have  */
294         RESTORE_TEMPORARY_REGISTERS(ARG_CNT)/* to restore arg and temp registers  */
295
296         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
297
298 L_asm_handle_exception_no_leaf:
299         mtctr   xpc                         /* jump to the handler                */
300         bctr
301
302 L_asm_handle_exception_not_catched:
303         ld      xptr,LA_SIZE+PA_SIZE+(4+0)*8(sp)        /* restore exception pointer          */
304         ld      pv,LA_SIZE+PA_SIZE+(4+2)*8(sp)          /* restore data segment pointer       */
305         ld      r0,LA_SIZE+PA_SIZE+(4+3)*8(sp)          /* restore return address             */
306         mtlr    r0
307         ld      t0,LA_SIZE+PA_SIZE+(4+4)*8(sp)          /* get maybe-leaf flag                */
308         addi    sp,sp,LA_SIZE+PA_SIZE+(4+6)*8           /* free stack frame                   */
309
310         mr.     t0,t0
311         beq     L_asm_handle_exception_no_leaf_stack
312
313         addi    sp,sp,(ARG_CNT+TMP_CNT)*8   /* remove maybe-leaf stackframe       */
314         li      t0,0                        /* clear the maybe-leaf flag          */
315
316 L_asm_handle_exception_no_leaf_stack:
317         lwz     t1,FrameSize(pv)            /* get frame size                     */
318         add     t1,sp,t1                    /* pointer to save area               */
319
320         lwz     t2,IsLeaf(pv)               /* is leaf procedure                  */
321         mr.     t2,t2
322         bne     L_asm_handle_exception_no_ra_restore
323
324         ld      r0,LA_LR_OFFSET(t1)         /* restore ra                         */
325         mtlr    r0
326
327 L_asm_handle_exception_no_ra_restore:
328         mflr    xpc                         /* the new xpc is ra                  */
329         mr      t4,xpc                      /* save RA */
330         lwz     t2,IntSave(pv)              /* t1 = saved int register count      */
331         bl      ex_int1
332 ex_int1:
333         mflr    t3                          /* t3 = current pc                    */
334         addi    t3,t3,(ex_int2-ex_int1)@l
335         slwi    t2,t2,2                     /* t2 = register count * 4            */
336         subf    t3,t2,t3                    /* t3 = IntSave - t2                  */
337         mtctr   t3
338         bctr
339
340         ld      s0,-9*8(t1)
341         ld      s1,-8*8(t1)
342         ld      s2,-7*8(t1)
343         ld      s3,-6*8(t1)
344         ld      s4,-5*8(t1)
345         ld      s5,-4*8(t1)
346         ld      s6,-3*8(t1)
347         ld      s7,-2*8(t1)
348         ld      s8,-1*8(t1)
349
350 ex_int2:
351         subf    t1,t2,t1                    /* t1 = t1 - register count * 4       */
352         lwz     t2,FltSave(pv)
353         bl      ex_flt1
354 ex_flt1:
355         mflr    t3
356         addi    t3,t3,(ex_flt2-ex_flt1)@l
357         slwi    t2,t2,2                     /* t2 = register count * 4            */
358         subf    t3,t2,t3                    /* t3 = FltSave - t2                  */
359         mtctr   t3
360         bctr
361
362         lfd     fs0,-10*8(t1)
363         lfd     fs1,-9*8(t1)
364         lfd     fs2,-8*8(t1)
365         lfd     fs3,-7*8(t1)
366         lfd     fs4,-6*8(t1)
367         lfd     fs5,-5*8(t1)
368         lfd     fs6,-4*8(t1)
369         lfd     fs7,-3*8(t1)
370         lfd     fs8,-2*8(t1)
371         lfd     fs9,-1*8(t1)
372
373 ex_flt2:
374         mtlr    t4                                   /* restore RA */
375         lwz     t1,FrameSize(pv)                     
376         add     sp,sp,t1                             /* unwind stack */
377         b       L_asm_handle_exception_stack_loop
378
379
380 /* asm_abstractmethoderror *****************************************************
381
382    Creates and throws an AbstractMethodError.
383
384 *******************************************************************************/
385
386 asm_abstractmethoderror:
387         mflr    r0
388         std     r0,LA_LR_OFFSET(sp)
389         stdu    sp,-LA_SIZE_ALIGNED(sp)     /* preserve linkage area              */
390         addi    a0,sp,LA_SIZE_ALIGNED       /* pass java sp                       */
391         mr      a1,r0                       /* pass exception address             */
392         bl      exceptions_asm_new_abstractmethoderror
393         ld      r0,LA_SIZE_ALIGNED+LA_LR_OFFSET(sp)
394         mtlr    r0                          /* restore return address             */
395         addi    sp,sp,LA_SIZE_ALIGNED
396
397         mr      xptr,v0                     /* get exception pointer              */
398         mr      xpc,r0                      /* we can't use r0 directly in addi   */
399         addi    xpc,xpc,-4                  /* exception address is ra - 4        */
400         b       L_asm_handle_nat_exception
401
402
403 /* asm_cacheflush **************************************************************
404         assumes 128 byte cache line size.
405         All registers used may be trashed for fun and profit.
406 *******************************************************************************/
407
408         .section ".opd","aw"
409         .align 3
410 asm_cacheflush:
411                 .quad   .asm_cacheflush,.TOC.@tocbase,0
412                 .previous
413                 .size asm_cacheflush, 24
414                 .type .asm_cacheflush,@function
415                 .globl .asm_cacheflush 
416 .asm_cacheflush:
417         /* construct the AND mask */
418         li      r6,   0xffffffffffff8000
419         ori     r6,r6,0x000000000000ff80
420
421         add     r4,r3,r4
422         and.    r3,r3,r6
423         addi    r4,r4,127
424         and.    r4,r4,r6
425         mr      r5,r3
426 1:
427         cmpld   r3,r4
428         bge     0f
429         dcbst   0,r3
430         addi    r3,r3,128
431         b       1b
432 0:
433         sync
434 1:
435         cmpld   r5,r4
436         bge     0f
437         icbi    0,r5
438         addi    r5,r5,128
439         b       1b
440 0:
441         sync
442         isync
443         blr
444
445
446 /* disable exec-stacks ********************************************************/
447
448 #if defined(__linux__) && defined(__ELF__)
449         .section .note.GNU-stack,"",%progbits
450 #endif
451
452
453 /*
454  * These are local overrides for various environment variables in Emacs.
455  * Please do not remove this and leave it at the end of the file, where
456  * Emacs will automagically detect them.
457  * ---------------------------------------------------------------------
458  * Local variables:
459  * mode: asm
460  * indent-tabs-mode: t
461  * c-basic-offset: 4
462  * tab-width: 4
463  * End:
464  * vim:noexpandtab:sw=4:ts=4:
465  */