Mercurial > pub > dyncall > dyncall
comparison dyncall/dyncall_call_ppc64.S @ 0:3e629dc19168
initial from svn dyncall-1745
author | Daniel Adler |
---|---|
date | Thu, 19 Mar 2015 22:24:28 +0100 |
parents | |
children | 7ca57dbefed4 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:3e629dc19168 |
---|---|
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 | |
26 #include "../portasm/portasm-ppc.S" | |
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: | |
40 2014-08-07: Initial Support | |
41 | |
42 */ | |
43 | |
44 /* ---------------------------------------------------------------------------- | |
45 | |
46 Call Kernel for ppc64 | |
47 | |
48 Input: | |
49 r3 : target address ptr | |
50 r4 : register data ptr (8 x GPR 64 bytes, 13 x FPR 64 bytes) | |
51 r5 : stack data size | |
52 r6 : stack data ptr | |
53 | |
54 Details: | |
55 - Stack frames are always aligned on 16 byte | |
56 - Reserve GPR2 (System register) | |
57 - The GPR3 .. GPR10 are loaded | |
58 - The FPR1 .. FPR8 are loaded | |
59 - No support for Vector Parameters so far. | |
60 - Parameter Area (min. v1:64 Bytes v2:0 Byte) | |
61 - Frame Header Area (v1:48 Bytes v2:32 Bytes) | |
62 | |
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 | |
95 .global dcCall_ppc64 | |
96 .type dcCall_ppc64, @function | |
97 #if DC__ABI_PPC64_ELF_V != 2 | |
98 .section .opd, "aw" | |
99 .align 3 | |
100 #endif | |
101 | |
102 dcCall_ppc64: | |
103 #if DC__ABI_PPC64_ELF_V != 2 | |
104 .quad .dcCall_ppc64, .TOC.@tocbase, 0 | |
105 .previous | |
106 .global .dcCall_ppc64 | |
107 | |
108 .dcCall_ppc64: | |
109 #else | |
110 0: addis r2, r12,.TOC.-0b@ha | |
111 addi r2, r2,.TOC.-0b@l | |
112 .localentry dcCall_ppc64,.-dcCall_ppc64 | |
113 #endif | |
114 mflr r0 /* r0 = return address */ | |
115 std r0,16(r1) /* store r0 to link-area */ | |
116 std r31,-8(r1) | |
117 | |
118 /* compute aligned stack-size */ | |
119 | |
120 /* add link area and align to 16 byte (+15) */ | |
121 | |
122 /* r0 = stacksize + frame parameter(back-chain link, this callee's call return address) */ | |
123 addi r0,r5,STACK_MIN+15 /* r0 = r5 + STACK_MIN + 15 */ | |
124 rlwinm r0,r0,0,0,27 /* r0 = r0 and -15 */ | |
125 neg r0,r0 /* r0 = -r0 */ | |
126 stdux r1,r1,r0 /* store r1 and decrement */ | |
127 | |
128 /* copy stack data */ | |
129 | |
130 subi r6,r6,8 /* r6 = 8 bytes before source stack ptr */ | |
131 addi r7,r1,PARAM_SAVE-8 /* r7 = 8 bytes before target stack parameter-block */ | |
132 | |
133 srwi r5,r5,3 /* r5 = size in double words */ | |
134 | |
135 cmpi cr0,r5,0 /* if stacksize != 0 .. */ | |
136 beq cr0,.copy_done | |
137 | |
138 mtctr r5 /* copy loop */ | |
139 | |
140 .copy_next: | |
141 ldu r0, 8(r6) | |
142 stdu r0, 8(r7) | |
143 bdnz .copy_next | |
144 | |
145 .copy_done: | |
146 | |
147 /* this call support using ctr branch register */ | |
148 | |
149 mr r12, r3 /* r12 = target function */ | |
150 std r2,TOC_SAVE(r1) | |
151 #if DC__ABI_PPC64_ELF_V != 2 | |
152 ld r2,8(r12) | |
153 ld r0,0(r12) | |
154 mtctr r0 | |
155 #else | |
156 mtctr r12 | |
157 #endif | |
158 mr r11, r4 /* r11 = reg data */ | |
159 | |
160 /* load 8 integer registers */ | |
161 | |
162 ld r3 , 0(r11) | |
163 ld r4 , 8(r11) | |
164 ld r5 ,16(r11) | |
165 ld r6 ,24(r11) | |
166 ld r7 ,32(r11) | |
167 ld r8 ,40(r11) | |
168 ld r9 ,48(r11) | |
169 ld r10,56(r11) | |
170 | |
171 /* load 13 float registers */ | |
172 | |
173 lfd f1 , 64(r11) | |
174 lfd f2 , 72(r11) | |
175 lfd f3 , 80(r11) | |
176 lfd f4 , 88(r11) | |
177 lfd f5 , 96(r11) | |
178 lfd f6 ,104(r11) | |
179 lfd f7 ,112(r11) | |
180 lfd f8 ,120(r11) | |
181 lfd f9 ,128(r11) | |
182 lfd f10,136(r11) | |
183 lfd f11,144(r11) | |
184 lfd f12,152(r11) | |
185 lfd f13,160(r11) | |
186 | |
187 bctrl /* branch with this call support */ | |
188 | |
189 /* epilog */ | |
190 | |
191 ld r2,TOC_SAVE(r1) | |
192 ld r1, 0(r1) /* restore stack */ | |
193 ld r31,-8(r1) | |
194 ld r0,16(r1) /* r0 = return address */ | |
195 mtlr r0 /* setup link register */ | |
196 blr /* return */ | |
197 |