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 */
+