comparison dyncall/dyncall_call_ppc32.S @ 0:3e629dc19168

initial from svn dyncall-1745
author Daniel Adler
date Thu, 19 Mar 2015 22:24:28 +0100
parents
children f5577f6bf97a
comparison
equal deleted inserted replaced
-1:000000000000 0:3e629dc19168
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
9 Copyright (c) 2007-2015 Daniel Adler <dadler@uni-goettingen.de>,
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