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
|
|
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
|