0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncall
|
|
5 File: dyncall/dyncall_call_ppc64.S
|
|
6 Description: Call Kernel for PowerPC 64-bit Architecture
|
|
7 License:
|
|
8
|
|
9 Copyright (c) 2014-2015 Masanori Mitsugi <mitsugi@linux.vnet.ibm.com>
|
|
10
|
|
11 Permission to use, copy, modify, and distribute this software for any
|
|
12 purpose with or without fee is hereby granted, provided that the above
|
|
13 copyright notice and this permission notice appear in all copies.
|
|
14
|
|
15 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
16 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
17 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
18 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
21 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
22
|
|
23 */
|
|
24
|
|
25
|
7
|
26 #include "../portasm/portasm-ppc64.S"
|
0
|
27
|
|
28 /*
|
|
29 Call Kernel Implementations for PowerPC64.
|
|
30 */
|
|
31
|
|
32 /* ============================================================================
|
|
33 DynCall Call Kernels for PPC64 Architecture
|
|
34 -------------------------------------------------------------------------
|
|
35 C Interface:
|
|
36 struct DCRegData { int i[8]; double d[13]; };
|
|
37 dcCall_ppc64(DCpointer target, struct DCRegData* pRegData, DCsize stacksize, DCptr stackdata);
|
|
38
|
|
39 ChangeLog:
|
7
|
40 2015-07-08: Added support for system calls
|
0
|
41 2014-08-07: Initial Support
|
|
42
|
|
43 */
|
|
44
|
|
45 /* ----------------------------------------------------------------------------
|
|
46
|
|
47 Call Kernel for ppc64
|
|
48
|
|
49 Input:
|
|
50 r3 : target address ptr
|
|
51 r4 : register data ptr (8 x GPR 64 bytes, 13 x FPR 64 bytes)
|
|
52 r5 : stack data size
|
|
53 r6 : stack data ptr
|
|
54
|
|
55 Details:
|
|
56 - Stack frames are always aligned on 16 byte
|
|
57 - Reserve GPR2 (System register)
|
|
58 - The GPR3 .. GPR10 are loaded
|
|
59 - The FPR1 .. FPR8 are loaded
|
|
60 - No support for Vector Parameters so far.
|
|
61 - Parameter Area (min. v1:64 Bytes v2:0 Byte)
|
|
62 - Frame Header Area (v1:48 Bytes v2:32 Bytes)
|
|
63
|
|
64 Frame structure:
|
|
65
|
|
66 on entry, parent frame layout:
|
|
67
|
|
68 offset
|
|
69 16: LR save word (Callee stores LR in parent frame)
|
|
70 0: parent stack frame (back-chain)
|
|
71
|
|
72 after frame initialization:
|
|
73
|
|
74 v1: stack size = ( (48+64+8+15) + stacksize ) & -(16)
|
|
75 v2: stack size = ( (32+0+8+15) + stacksize ) & -(16)
|
|
76
|
|
77 ... locals and register spills
|
|
78 48 or 32: parameter list area
|
|
79 16: LR save word (Callee stores LR in parent frame)
|
|
80 0: parent stack frame (back-chain)
|
|
81 */
|
|
82
|
|
83 /* Constants */
|
|
84 #if DC__ABI_PPC64_ELF_V != 2
|
|
85 STACK_MIN = 120 /* v1 */
|
|
86 TOC_SAVE = 40
|
|
87 PARAM_SAVE = 48
|
|
88 #else
|
|
89 STACK_MIN = 40 /* v2 */
|
|
90 TOC_SAVE = 24
|
|
91 PARAM_SAVE = 32
|
|
92 #endif
|
|
93
|
|
94 .text
|
7
|
95 .align 2
|
|
96 GLOBAL_C(dcCall_ppc64)
|
|
97 ENTRY_C(dcCall_ppc64)
|
0
|
98 mflr r0 /* r0 = return address */
|
|
99 std r0,16(r1) /* store r0 to link-area */
|
|
100 std r31,-8(r1)
|
|
101
|
|
102 /* compute aligned stack-size */
|
|
103
|
|
104 /* add link area and align to 16 byte (+15) */
|
|
105
|
|
106 /* r0 = stacksize + frame parameter(back-chain link, this callee's call return address) */
|
|
107 addi r0,r5,STACK_MIN+15 /* r0 = r5 + STACK_MIN + 15 */
|
|
108 rlwinm r0,r0,0,0,27 /* r0 = r0 and -15 */
|
|
109 neg r0,r0 /* r0 = -r0 */
|
|
110 stdux r1,r1,r0 /* store r1 and decrement */
|
|
111
|
|
112 /* copy stack data */
|
|
113
|
|
114 subi r6,r6,8 /* r6 = 8 bytes before source stack ptr */
|
|
115 addi r7,r1,PARAM_SAVE-8 /* r7 = 8 bytes before target stack parameter-block */
|
|
116
|
|
117 srwi r5,r5,3 /* r5 = size in double words */
|
|
118
|
|
119 cmpi cr0,r5,0 /* if stacksize != 0 .. */
|
|
120 beq cr0,.copy_done
|
|
121
|
|
122 mtctr r5 /* copy loop */
|
|
123
|
|
124 .copy_next:
|
|
125 ldu r0, 8(r6)
|
|
126 stdu r0, 8(r7)
|
|
127 bdnz .copy_next
|
|
128
|
|
129 .copy_done:
|
|
130
|
|
131 /* this call support using ctr branch register */
|
|
132
|
|
133 mr r12, r3 /* r12 = target function */
|
|
134 std r2,TOC_SAVE(r1)
|
|
135 #if DC__ABI_PPC64_ELF_V != 2
|
|
136 ld r2,8(r12)
|
|
137 ld r0,0(r12)
|
|
138 mtctr r0
|
|
139 #else
|
|
140 mtctr r12
|
|
141 #endif
|
|
142 mr r11, r4 /* r11 = reg data */
|
|
143
|
|
144 /* load 8 integer registers */
|
|
145
|
|
146 ld r3 , 0(r11)
|
|
147 ld r4 , 8(r11)
|
|
148 ld r5 ,16(r11)
|
|
149 ld r6 ,24(r11)
|
|
150 ld r7 ,32(r11)
|
|
151 ld r8 ,40(r11)
|
|
152 ld r9 ,48(r11)
|
|
153 ld r10,56(r11)
|
|
154
|
|
155 /* load 13 float registers */
|
|
156
|
|
157 lfd f1 , 64(r11)
|
|
158 lfd f2 , 72(r11)
|
|
159 lfd f3 , 80(r11)
|
|
160 lfd f4 , 88(r11)
|
|
161 lfd f5 , 96(r11)
|
|
162 lfd f6 ,104(r11)
|
|
163 lfd f7 ,112(r11)
|
|
164 lfd f8 ,120(r11)
|
|
165 lfd f9 ,128(r11)
|
|
166 lfd f10,136(r11)
|
|
167 lfd f11,144(r11)
|
|
168 lfd f12,152(r11)
|
|
169 lfd f13,160(r11)
|
|
170
|
|
171 bctrl /* branch with this call support */
|
|
172
|
|
173 /* epilog */
|
|
174
|
|
175 ld r2,TOC_SAVE(r1)
|
|
176 ld r1, 0(r1) /* restore stack */
|
|
177 ld r31,-8(r1)
|
|
178 ld r0,16(r1) /* r0 = return address */
|
|
179 mtlr r0 /* setup link register */
|
|
180 blr /* return */
|
|
181
|
7
|
182 .align 2
|
|
183 GLOBAL_C(dcCall_ppc64_syscall)
|
|
184 ENTRY_C(dcCall_ppc64_syscall)
|
|
185 mflr r0 /* r0 = return address */
|
|
186 std r0,16(r1) /* store r0 to link-area */
|
|
187 std r31,-8(r1)
|
|
188 li r0, -STACK_MIN
|
|
189 stdux r1,r1,r0 /* store r1 and decrement */
|
|
190
|
|
191 mr r0, r3 /* r0 = syscall number ( passed as 'target function' ) */
|
|
192 mr r11, r4 /* r11 = reg data */
|
|
193
|
|
194 /* load 5 integer registers */
|
|
195 ld r3 , 0(r11)
|
|
196 ld r4 , 8(r11)
|
|
197 ld r5 ,16(r11)
|
|
198 ld r6 ,24(r11)
|
|
199 ld r7 ,32(r11)
|
|
200
|
|
201 sc /* system call */
|
|
202
|
|
203 /* epilog */
|
|
204
|
|
205 ld r2,TOC_SAVE(r1)
|
|
206 ld r1, 0(r1) /* restore stack */
|
|
207 ld r31,-8(r1)
|
|
208 ld r0,16(r1) /* r0 = return address */
|
|
209 mtlr r0 /* setup link register */
|
|
210 blr /* return */
|