Mercurial > pub > dyncall > dyncall
annotate dyncall/dyncall_call_ppc32.S @ 368:f28b7f4f5749
- removed some pseudo-op on non-darwin platforms to make clang's integrated assembler happy
author | Tassilo Philipp |
---|---|
date | Wed, 05 Aug 2020 15:50:49 +0200 |
parents | d982a00c2177 |
children | 26aa936d4841 |
rev | line source |
---|---|
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 | |
368
f28b7f4f5749
- removed some pseudo-op on non-darwin platforms to make clang's integrated assembler happy
Tassilo Philipp
parents:
357
diff
changeset
|
36 #.machine ppc # clang's integrated as doesn't handle this on anything but Darwin (at least for clang <= 9) |
0 | 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 | |
357
d982a00c2177
- PPC64 asm syntax fix, specifying explicitly comparison mode for cmpi (newer toolchains complain, older ones took optional field of instruction which happened to be same value)
Tassilo Philipp
parents:
345
diff
changeset
|
103 cmpi cr0,0,r5,0 /* if stacksize != 0 .. */ |
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 | |
357
d982a00c2177
- PPC64 asm syntax fix, specifying explicitly comparison mode for cmpi (newer toolchains complain, older ones took optional field of instruction which happened to be same value)
Tassilo Philipp
parents:
345
diff
changeset
|
217 cmpi cr0,0,r5,0 /* if stacksize != 0 .. */ |
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 | |
345
c607d67cd6b8
- doc: added syscall info to appendix, fixed broken literature link
Tassilo Philipp
parents:
281
diff
changeset
|
271 /* @@@ Bus Error on Darwin */ |
0 | 272 GLOBAL_C(dcCall_ppc32_syscall) |
273 ENTRY_C(dcCall_ppc32_syscall) | |
274 mflr r0 /* r0 = return address */ | |
275 stw r0,4(r1) /* store r0 to link-area */ | |
276 li r0, -8 | |
277 stwux r1,r1,r0 /* store r1 and decrement */ | |
278 | |
279 mr r0, r3 /* r0 = syscall number ( passed as 'target function' ) */ | |
280 mr r11, r4 /* r11 = reg data */ | |
281 lwz r3 , 0(r11) | |
282 lwz r4 , 4(r11) | |
283 lwz r5 , 8(r11) | |
284 lwz r6 ,12(r11) | |
285 lwz r7 ,16(r11) | |
345
c607d67cd6b8
- doc: added syscall info to appendix, fixed broken literature link
Tassilo Philipp
parents:
281
diff
changeset
|
286 /* @@@ missing r8,r9,10 on some platforms? */ |
0 | 287 sc |
288 | |
289 lwz r1, 0(r1) /* restore stack */ | |
290 lwz r0, 4(r1) /* r0 = return address */ | |
291 mtlr r0 /* setup link register */ | |
292 blr | |
345
c607d67cd6b8
- doc: added syscall info to appendix, fixed broken literature link
Tassilo Philipp
parents:
281
diff
changeset
|
293 |