0
|
1 /*
|
|
2
|
|
3 Package: dyncall
|
|
4 Library: dyncall
|
|
5 File: dyncall/dyncall_call_ppc32.S
|
|
6 Description: Call Kernel for PowerPC 32-bit Architecture
|
|
7 License:
|
|
8
|
281
|
9 Copyright (c) 2007-2018 Daniel Adler <dadler@uni-goettingen.de>,
|
0
|
10 Tassilo Philipp <tphilipp@potion-studios.com>
|
|
11
|
|
12 Permission to use, copy, modify, and distribute this software for any
|
|
13 purpose with or without fee is hereby granted, provided that the above
|
|
14 copyright notice and this permission notice appear in all copies.
|
|
15
|
|
16 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
17 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
18 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
19 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
20 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
21 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
22 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
23
|
|
24 */
|
|
25
|
|
26
|
|
27
|
|
28 #include "../portasm/portasm-ppc.S"
|
|
29
|
|
30 /*
|
|
31 Call Kernel Implementations for PowerPC.
|
|
32 Supported Calling Conventions: sysv, darwin, syscall
|
|
33
|
|
34 */
|
|
35
|
|
36 .machine ppc
|
|
37 .text
|
|
38
|
|
39 /* ============================================================================
|
|
40 DynCall Call Kernels for PPC32 Architecture
|
|
41 -------------------------------------------------------------------------
|
|
42 C Interface:
|
|
43 struct DCRegData { int i[8]; double d[13]; };
|
|
44 dcCall_ppc32_XXX(DCpointer target, struct DCRegData* pRegData, DCsize stacksize, DCptr stackdata);
|
|
45
|
|
46 Where XXX is one of the following Calling Conventions:
|
|
47 darwin, sysv
|
|
48
|
|
49 ChangeLog:
|
|
50 2015-01-15: Added support for system calls.
|
|
51 2011-04-03: Using portasm.
|
|
52 2009-01-09: Added Support for System V ABI.
|
|
53 2007-11-28: Initial Support for Darwin.
|
|
54
|
|
55 */
|
|
56
|
|
57 /*---------------------------------------------------------------------------
|
|
58
|
|
59 Call Kernel for ppc32 Darwin
|
|
60
|
|
61 Input:
|
|
62 r3 : target address ptr
|
|
63 r4 : register data ptr (8 x GPR 32 bytes, 13 x FPR 64 bytes)
|
|
64 r5 : stack data size
|
|
65 r6 : stack data ptr
|
|
66
|
|
67 Details:
|
|
68 - Stack frames are always aligned on 16 byte
|
|
69 - The GPR3 .. GPR10 are loaded
|
|
70 - The FPR1 .. FPR13 are loaded
|
|
71 - No support for Vector Parameters so far.
|
|
72 - Parameter Area (min. 32 Bytes)
|
|
73 - Linkage Area (24 Bytes)
|
|
74 */
|
|
75
|
|
76 .align 2
|
|
77 GLOBAL_C(dcCall_ppc32_darwin)
|
|
78 ENTRY_C(dcCall_ppc32_darwin)
|
|
79
|
|
80
|
|
81 mflr r0 /* r0 = return address */
|
|
82 stw r0,8(r1) /* store return address in caller link-area */
|
|
83
|
|
84 /* compute aligned stack-size */
|
|
85
|
|
86 /* add link area and align to 16 byte border */
|
|
87
|
|
88 addi r0,r5,24+15 /* r0 = stacksize + link area */
|
|
89
|
|
90 rlwinm r0,r0,0,0,27 /* r0 = r0 and -15 */
|
|
91 /* r0 = r0 and -15 */
|
|
92 neg r2,r0 /* r2 = -stacksize */
|
|
93
|
|
94 stwux r1,r1,r2 /* r1 = r1 - stacksize */
|
|
95
|
|
96 /* copy stack data */
|
|
97
|
|
98 subi r6,r6,4 /* r6 = 4 bytes before source stack ptr */
|
|
99 addi r7,r1,20 /* r7 = 4 bytes before target stack parameter-block */
|
|
100
|
|
101 srwi r5,r5,2 /* r5 = size in words */
|
|
102
|
|
103 cmpi cr0,r5,0 /* if stacksize != 0 .. */
|
|
104 beq cr0,.osx_done
|
|
105
|
|
106 mtctr r5 /* copy loop */
|
|
107
|
|
108 .osx_next:
|
|
109 lwzu r0, 4(r6)
|
|
110 stwu r0, 4(r7)
|
|
111 bdnz .osx_next
|
|
112
|
|
113 .osx_done:
|
|
114
|
|
115 mr r12, r3 /* r12 = target function */
|
|
116 mtctr r12 /* control register = target function */
|
|
117 mr r2, r4 /* r2 = reg data */
|
|
118
|
|
119 /* load 8 integer registers */
|
|
120
|
|
121 lwz r3 , 0(r2)
|
|
122 lwz r4 , 4(r2)
|
|
123 lwz r5 , 8(r2)
|
|
124 lwz r6 ,12(r2)
|
|
125 lwz r7 ,16(r2)
|
|
126 lwz r8 ,20(r2)
|
|
127 lwz r9 ,24(r2)
|
|
128 lwz r10,28(r2)
|
|
129
|
|
130 /* load 13 float registers */
|
|
131
|
|
132 lfd f1 ,32(r2)
|
|
133 lfd f2 ,40(r2)
|
|
134 lfd f3 ,48(r2)
|
|
135 lfd f4 ,56(r2)
|
|
136 lfd f5 ,64(r2)
|
|
137 lfd f6 ,72(r2)
|
|
138 lfd f7 ,80(r2)
|
|
139 lfd f8 ,88(r2)
|
|
140 lfd f9 ,96(r2)
|
|
141 lfd f10,104(r2)
|
|
142 lfd f11,112(r2)
|
|
143 lfd f12,120(r2)
|
|
144 lfd f13,128(r2)
|
|
145
|
|
146 /* branch */
|
|
147
|
|
148 bctrl
|
|
149
|
|
150 /* epilog */
|
|
151
|
|
152 lwz r1, 0(r1) /* restore stack */
|
|
153 lwz r0, 8(r1) /* r0 = return address */
|
|
154 mtlr r0 /* setup link register */
|
|
155 blr /* return */
|
|
156
|
|
157 /* ----------------------------------------------------------------------------
|
|
158
|
|
159 Call Kernel for ppc32 System
|
|
160
|
|
161 Input:
|
|
162 r3 : target address ptr
|
|
163 r4 : register data ptr (8 x GPR 32 bytes, 8 x FPR 64 bytes)
|
|
164 r5 : stack data size
|
|
165 r6 : stack data ptr
|
|
166
|
|
167 Details:
|
|
168 - Stack frames are always aligned on 16 byte
|
|
169 - Reserve GPR2 (System register)
|
|
170 - The GPR3 .. GPR10 are loaded
|
|
171 - The FPR1 .. FPR8 are loaded
|
|
172 - No support for Vector Parameters so far.
|
|
173
|
|
174 Frame structure:
|
|
175
|
|
176 on entry, parent frame layout:
|
|
177
|
|
178 offset
|
|
179 4: LR save word (Callee stores LR in parent frame)
|
|
180 0: parent stack frame (back-chain)
|
|
181
|
|
182 after frame initialization:
|
|
183
|
|
184 stack size = ( (8+15) + stacksize ) & -(16)
|
|
185
|
|
186 ... locals and register spills
|
|
187 8: parameter list area
|
|
188 4: LR save word (Callee stores LR in parent frame)
|
|
189 0: parent stack frame (back-chain)
|
|
190 */
|
|
191
|
|
192 .align 2
|
|
193 GLOBAL_C(dcCall_ppc32_sysv)
|
|
194 ENTRY_C(dcCall_ppc32_sysv)
|
|
195 mflr r0 /* r0 = return address */
|
|
196 stw r0,4(r1) /* store r0 to link-area */
|
|
197
|
|
198 /* compute aligned stack-size */
|
|
199
|
|
200 /* add link area (+8) and align to 16 byte (+15) */
|
|
201
|
|
202 /* r0 = stacksize + frame parameter(back-chain link, this callee's call return address) */
|
|
203 addi r0,r5,8+15 /* r0 = r5 + 8 + 15 */
|
|
204 rlwinm r0,r0,0,0,27 /* r0 = r0 and -15 */
|
|
205 neg r0,r0 /* r0 = -r0 */
|
|
206 stwux r1,r1,r0 /* store r1 and decrement */
|
|
207
|
|
208 /* copy stack data */
|
|
209
|
|
210 subi r6,r6,4 /* r6 = 4 bytes before source stack ptr */
|
|
211
|
|
212 /* 4 bytes before target stack parameter-block */
|
|
213 addi r7,r1,4 /* r7 = r1 + 8 offset - 4 displacement */
|
|
214
|
|
215 srwi r5,r5,2 /* r5 = size in words */
|
|
216
|
|
217 cmpi cr0,r5,0 /* if stacksize != 0 .. */
|
|
218 beq cr0,.sysv_done
|
|
219
|
|
220 mtctr r5 /* copy loop */
|
|
221
|
|
222 .sysv_next:
|
|
223 lwzu r0, 4(r6)
|
|
224 stwu r0, 4(r7)
|
|
225 bdnz .sysv_next
|
|
226
|
|
227 .sysv_done:
|
|
228
|
|
229 /* this call support using ctr branch register */
|
|
230
|
|
231 mr r12, r3 /* r12 = target function */
|
|
232 mtctr r12 /* control register = r12 */
|
|
233 mr r11, r4 /* r11 = reg data */
|
|
234
|
|
235 /* load 8 integer registers */
|
|
236
|
|
237 lwz r3 , 0(r11)
|
|
238 lwz r4 , 4(r11)
|
|
239 lwz r5 , 8(r11)
|
|
240 lwz r6 ,12(r11)
|
|
241 lwz r7 ,16(r11)
|
|
242 lwz r8 ,20(r11)
|
|
243 lwz r9 ,24(r11)
|
|
244 lwz r10,28(r11)
|
|
245
|
|
246 /* load 8 float registers */
|
|
247
|
|
248 lfd f1 ,32(r11)
|
|
249 lfd f2 ,40(r11)
|
|
250 lfd f3 ,48(r11)
|
|
251 lfd f4 ,56(r11)
|
|
252 lfd f5 ,64(r11)
|
|
253 lfd f6 ,72(r11)
|
|
254 lfd f7 ,80(r11)
|
|
255 lfd f8 ,88(r11)
|
|
256
|
|
257 creqv 6,6,6 /* used for ellipsis calls */
|
|
258
|
|
259 bctrl /* branch with this call support */
|
|
260
|
|
261 /* epilog */
|
|
262
|
|
263 lwz r1, 0(r1) /* restore stack */
|
|
264 lwz r0, 4(r1) /* r0 = return address */
|
|
265 mtlr r0 /* setup link register */
|
|
266 blr /* return */
|
|
267
|
|
268
|
|
269 .align 2
|
|
270
|
|
271 GLOBAL_C(dcCall_ppc32_syscall)
|
|
272 ENTRY_C(dcCall_ppc32_syscall)
|
|
273 mflr r0 /* r0 = return address */
|
|
274 stw r0,4(r1) /* store r0 to link-area */
|
|
275 li r0, -8
|
|
276 stwux r1,r1,r0 /* store r1 and decrement */
|
|
277
|
|
278 mr r0, r3 /* r0 = syscall number ( passed as 'target function' ) */
|
|
279 mr r11, r4 /* r11 = reg data */
|
|
280 lwz r3 , 0(r11)
|
|
281 lwz r4 , 4(r11)
|
|
282 lwz r5 , 8(r11)
|
|
283 lwz r6 ,12(r11)
|
|
284 lwz r7 ,16(r11)
|
|
285 sc
|
|
286
|
|
287 lwz r1, 0(r1) /* restore stack */
|
|
288 lwz r0, 4(r1) /* r0 = return address */
|
|
289 mtlr r0 /* setup link register */
|
|
290 blr
|
|
291
|