Mercurial > pub > dyncall > dyncall
diff dyncall/dyncall_call_ppc64.S @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children | 7ca57dbefed4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dyncall/dyncall_call_ppc64.S Thu Mar 19 22:24:28 2015 +0100 @@ -0,0 +1,197 @@ +/* + + Package: dyncall + Library: dyncall + File: dyncall/dyncall_call_ppc64.S + Description: Call Kernel for PowerPC 64-bit Architecture + License: + + Copyright (c) 2014-2015 Masanori Mitsugi <mitsugi@linux.vnet.ibm.com> + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +*/ + + +#include "../portasm/portasm-ppc.S" + +/* + Call Kernel Implementations for PowerPC64. +*/ + +/* ============================================================================ + DynCall Call Kernels for PPC64 Architecture + ------------------------------------------------------------------------- + C Interface: + struct DCRegData { int i[8]; double d[13]; }; + dcCall_ppc64(DCpointer target, struct DCRegData* pRegData, DCsize stacksize, DCptr stackdata); + + ChangeLog: + 2014-08-07: Initial Support + +*/ + +/* ---------------------------------------------------------------------------- + + Call Kernel for ppc64 + + Input: + r3 : target address ptr + r4 : register data ptr (8 x GPR 64 bytes, 13 x FPR 64 bytes) + r5 : stack data size + r6 : stack data ptr + + Details: + - Stack frames are always aligned on 16 byte + - Reserve GPR2 (System register) + - The GPR3 .. GPR10 are loaded + - The FPR1 .. FPR8 are loaded + - No support for Vector Parameters so far. + - Parameter Area (min. v1:64 Bytes v2:0 Byte) + - Frame Header Area (v1:48 Bytes v2:32 Bytes) + + + Frame structure: + + on entry, parent frame layout: + + offset + 16: LR save word (Callee stores LR in parent frame) + 0: parent stack frame (back-chain) + + after frame initialization: + + v1: stack size = ( (48+64+8+15) + stacksize ) & -(16) + v2: stack size = ( (32+0+8+15) + stacksize ) & -(16) + + ... locals and register spills + 48 or 32: parameter list area + 16: LR save word (Callee stores LR in parent frame) + 0: parent stack frame (back-chain) +*/ + +/* Constants */ +#if DC__ABI_PPC64_ELF_V != 2 +STACK_MIN = 120 /* v1 */ +TOC_SAVE = 40 +PARAM_SAVE = 48 +#else +STACK_MIN = 40 /* v2 */ +TOC_SAVE = 24 +PARAM_SAVE = 32 +#endif + +.text + .global dcCall_ppc64 + .type dcCall_ppc64, @function +#if DC__ABI_PPC64_ELF_V != 2 + .section .opd, "aw" + .align 3 +#endif + +dcCall_ppc64: +#if DC__ABI_PPC64_ELF_V != 2 + .quad .dcCall_ppc64, .TOC.@tocbase, 0 + .previous + .global .dcCall_ppc64 + +.dcCall_ppc64: +#else +0: addis r2, r12,.TOC.-0b@ha + addi r2, r2,.TOC.-0b@l + .localentry dcCall_ppc64,.-dcCall_ppc64 +#endif + mflr r0 /* r0 = return address */ + std r0,16(r1) /* store r0 to link-area */ + std r31,-8(r1) + + /* compute aligned stack-size */ + + /* add link area and align to 16 byte (+15) */ + + /* r0 = stacksize + frame parameter(back-chain link, this callee's call return address) */ + addi r0,r5,STACK_MIN+15 /* r0 = r5 + STACK_MIN + 15 */ + rlwinm r0,r0,0,0,27 /* r0 = r0 and -15 */ + neg r0,r0 /* r0 = -r0 */ + stdux r1,r1,r0 /* store r1 and decrement */ + + /* copy stack data */ + + subi r6,r6,8 /* r6 = 8 bytes before source stack ptr */ + addi r7,r1,PARAM_SAVE-8 /* r7 = 8 bytes before target stack parameter-block */ + + srwi r5,r5,3 /* r5 = size in double words */ + + cmpi cr0,r5,0 /* if stacksize != 0 .. */ + beq cr0,.copy_done + + mtctr r5 /* copy loop */ + +.copy_next: + ldu r0, 8(r6) + stdu r0, 8(r7) + bdnz .copy_next + +.copy_done: + + /* this call support using ctr branch register */ + + mr r12, r3 /* r12 = target function */ + std r2,TOC_SAVE(r1) +#if DC__ABI_PPC64_ELF_V != 2 + ld r2,8(r12) + ld r0,0(r12) + mtctr r0 +#else + mtctr r12 +#endif + mr r11, r4 /* r11 = reg data */ + + /* load 8 integer registers */ + + ld r3 , 0(r11) + ld r4 , 8(r11) + ld r5 ,16(r11) + ld r6 ,24(r11) + ld r7 ,32(r11) + ld r8 ,40(r11) + ld r9 ,48(r11) + ld r10,56(r11) + + /* load 13 float registers */ + + lfd f1 , 64(r11) + lfd f2 , 72(r11) + lfd f3 , 80(r11) + lfd f4 , 88(r11) + lfd f5 , 96(r11) + lfd f6 ,104(r11) + lfd f7 ,112(r11) + lfd f8 ,120(r11) + lfd f9 ,128(r11) + lfd f10,136(r11) + lfd f11,144(r11) + lfd f12,152(r11) + lfd f13,160(r11) + + bctrl /* branch with this call support */ + + /* epilog */ + + ld r2,TOC_SAVE(r1) + ld r1, 0(r1) /* restore stack */ + ld r31,-8(r1) + ld r0,16(r1) /* r0 = return address */ + mtlr r0 /* setup link register */ + blr /* return */ +