Mercurial > pub > dyncall > dyncall
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 |