comparison dyncallback/dyncall_callback_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: dyncallback
5 File: dyncallback/dyncall_callback_ppc64.S
6 Description: Callback Thunk - Implementation for PowerPC 64-bit
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 #include "../portasm/portasm-ppc.S"
26
27 /* Callback Thunk Entry code for PowerPC 64-bit. */
28
29 /* Stack Frame Layout:
30
31 296 DCValue ( 8 )
32 112 DCArgs ( 64+104+8+4+4 = 184 )
33 48 Parameter area ( 8*8 = 64 )
34 0 Linkage area ( 48 )
35
36
37 */
38
39 /* Constants. */
40 INT_REGS = 8
41 FLOAT_REGS = 13
42 SIZEOF_GPR = 8
43 SIZEOF_FPR = 8
44
45 /* Linkage area. */
46 LINK_SP = 0
47 LINK_CR = 8
48 LINK_LR = 16
49 LINK_OFFSET = 0
50 #if DC__ABI_PPC64_ELF_V == 2
51 LINK_TOC = 24
52 LINK_SIZE = 32
53 #else
54 LINK_TOC = 40
55 LINK_SIZE = 48
56 #endif
57 /* Parameter area. */
58 PAR_OFFSET = LINK_SIZE
59 #if DC__ABI_PPC64_ELF_V == 2
60 PAR_SIZE = 0
61 #else
62 PAR_SIZE = 64
63 #endif
64 /* local struct DCArgs */
65 ARGS_OFFSET = (PAR_OFFSET+PAR_SIZE)
66 ARGS_SIZE = (SIZEOF_GPR*INT_REGS)+(SIZEOF_FPR*FLOAT_REGS) + 8 + 4 * 4
67 /* local struct DCValue */
68 RESULT_OFFSET = (ARGS_OFFSET+ARGS_SIZE)
69 RESULT_SIZE = 8
70 /* additional locals (reg 30/31) */
71 LOCALS_OFFSET = (RESULT_OFFSET+RESULT_SIZE)
72 LOCALS_SIZE = 2*SIZEOF_GPR
73 /* total */
74 FRAME_SIZE = ( (LOCALS_OFFSET+LOCALS_SIZE)+15 & (-16) )
75
76 /* struct DCCallback */
77 #if DC__ABI_PPC64_ELF_V == 2
78 DCB_THUNK = 0
79 DCB_HANDLER = 48
80 DCB_STACKCLEAN = 56
81 DCB_USERDATA = 64
82 #else
83 DCB_THUNK = 0
84 DCB_HANDLER = 64
85 DCB_STACKCLEAN = 72
86 DCB_USERDATA = 80
87 #endif
88
89 /* struct DCArgs */
90 DCA_IARRAY = 0
91 DCA_FARRAY = SIZEOF_GPR*INT_REGS
92 DCA_SP = DCA_FARRAY + SIZEOF_FPR*FLOAT_REGS
93 DCA_ICOUNT = DCA_SP + 8
94 DCA_FCOUNT = DCA_ICOUNT + 4
95
96 /* struct DCValue */
97 DCV_INT = 0
98 DCV_FLOAT = 0
99 DCV_SIZE = 8
100
101 iregfile = ARGS_OFFSET+DCA_IARRAY
102 fregfile = ARGS_OFFSET+DCA_FARRAY
103 save_sp = ARGS_OFFSET+DCA_SP
104 icount = ARGS_OFFSET+DCA_ICOUNT
105 fcount = ARGS_OFFSET+DCA_FCOUNT
106
107 /*
108 Thunk entry:
109 R2 = DCCallback*
110 */
111 .text
112 .global dcCallbackThunkEntry
113 .type dcCallbackThunkEntry, @function
114 #if DC__ABI_PPC64_ELF_V != 2
115 .section .opd, "aw"
116 .align 3
117 #endif
118
119 dcCallbackThunkEntry:
120 #if DC__ABI_PPC64_ELF_V != 2
121 .quad .dcCallbackThunkEntry, .TOC.@tocbase, 0
122 .previous
123 .global .dcCallbackThunkEntry
124
125 .dcCallbackThunkEntry:
126 #endif
127 mflr r0
128 std r0, 16(r1) /* store return address */
129 std r31, -8(r1) /* store preserved registers (r31) */
130 addi r12, r1, PAR_OFFSET /* temporary r12 = parameter area on callers stack frame */
131 stdu r1, -FRAME_SIZE(r1) /* save callers stack pointer and make new stack frame. */
132
133 std r3, iregfile+0*8(r1) /* spill 8 integer parameter registers */
134 std r4, iregfile+1*8(r1)
135 std r5, iregfile+2*8(r1)
136 std r6, iregfile+3*8(r1)
137 std r7, iregfile+4*8(r1)
138 std r8, iregfile+5*8(r1)
139 std r9, iregfile+6*8(r1)
140 std r10,iregfile+7*8(r1)
141 stfd f1, fregfile+ 0*8(r1) /* spill 13 float parameter registers */
142 stfd f2, fregfile+ 1*8(r1)
143 stfd f3, fregfile+ 2*8(r1)
144 stfd f4, fregfile+ 3*8(r1)
145 stfd f5, fregfile+ 4*8(r1)
146 stfd f6, fregfile+ 5*8(r1)
147 stfd f7, fregfile+ 6*8(r1)
148 stfd f8, fregfile+ 7*8(r1)
149 stfd f9, fregfile+ 8*8(r1)
150 stfd f10,fregfile+ 9*8(r1)
151 stfd f11,fregfile+10*8(r1)
152 stfd f12,fregfile+11*8(r1)
153 stfd f13,fregfile+12*8(r1)
154 /* initialize struct DCCallback */
155 std r12,save_sp(r1) /* init stack pointer */
156 xor r0, r0, r0 /* init register counters */
157 std r0, icount(r1)
158 std r0, fcount(r1)
159 std r0, RESULT_OFFSET(r1)
160 /* invoke callback handler */
161 mr r3, r11 /* arg 1: DCCallback* pcb */
162 addi r4, r1, ARGS_OFFSET /* arg 2: DCArgs* args */
163 addi r5, r1, RESULT_OFFSET /* arg 3: DCValue* result */
164 ld r6, DCB_USERDATA(r11) /* arg 4: void* userdata */
165
166 /* branch-and-link to DCCallback.handler */
167 ld r12, DCB_HANDLER(r11)
168 std r2, LINK_TOC(r1)
169 #if DC__ABI_PPC64_ELF_V != 2
170 ld r2, 8(r12)
171 ld r0, 0(r12)
172 mtctr r0
173 #else
174 mtctr r12
175 #endif
176 bctrl
177
178 addi r0, r1, RESULT_OFFSET /* r0 = DCValue* */
179 /* switch on base result type */
180 cmpi cr0, r3, 'B
181 beq .i64
182 cmpi cr0, r3, 'i
183 beq .i64
184 cmpi cr0, r3, 'c
185 beq .i64
186 cmpi cr0, r3, 's
187 beq .i64
188 cmpi cr0, r3, 'l
189 beq .i64
190 cmpi cr0, r3, 'f
191 beq .f32
192 cmpi cr0, r3, 'd
193 beq .f64
194 cmpi cr0, r3, 'p
195 beq .i64
196 .void: /* ignore result (void call) */
197 b .end
198 .i64: /* result is 64-bit long long result */
199 ld r3, RESULT_OFFSET + DCV_INT(r1)
200 b .end
201 .f32: /* result is C float result */
202 lfs f1, RESULT_OFFSET + DCV_FLOAT(r1)
203 b .end
204 .f64: /* result is C double result */
205 lfd f1, RESULT_OFFSET + DCV_FLOAT(r1)
206 b .end
207 .end:
208
209 ld r2, LINK_TOC(r1)
210 ld r1, 0(r1) /* restore stack pointer */
211 ld r31, -8(r1) /* restore preserved registers */
212 ld r0, 16(r1) /* load link register with return address */
213 mtlr r0
214 blr /* branch back to link register */
215