Mercurial > pub > dyncall > dyncall
annotate dyncall/dyncall_call_ppc64.S @ 663:127b569978cc default tip
- another tweak handling clang trying to be too smart (see last commit)
author | Tassilo Philipp |
---|---|
date | Sun, 24 Mar 2024 13:52:44 +0100 |
parents | d982a00c2177 |
children |
rev | line source |
---|---|
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 | |
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
|
119 cmpi cr0,0,r5,0 /* if stacksize != 0 .. */ |
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) | |
345
c607d67cd6b8
- doc: added syscall info to appendix, fixed broken literature link
Tassilo Philipp
parents:
7
diff
changeset
|
200 /* @@@ missing r8,r9,10 on some platforms? */ |
7 | 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 */ |