blob: 41fb8851b6242642603b131714afc3ed793c0c6c [file] [log] [blame]
Christian Heimes78644762008-03-04 23:39:23 +00001/* -----------------------------------------------------------------------
2 sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
3 Copyright (c) 2008 Red Hat, Inc.
4
5 PowerPC Assembly glue.
6
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 ``Software''), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
14
15 The above copyright notice and this permission notice shall be included
16 in all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 DEALINGS IN THE SOFTWARE.
26 ----------------------------------------------------------------------- */
Thomas Hellerd4c93202006-03-08 19:35:11 +000027#define LIBFFI_ASM
28#include <fficonfig.h>
29#include <ffi.h>
30#include <powerpc/asm.h>
31
32 .file "ppc_closure.S"
33
34#ifndef __powerpc64__
35
36ENTRY(ffi_closure_SYSV)
37.LFB1:
38 stwu %r1,-144(%r1)
39.LCFI0:
40 mflr %r0
41.LCFI1:
42 stw %r0,148(%r1)
43
44# we want to build up an areas for the parameters passed
45# in registers (both floating point and integer)
46
47 # so first save gpr 3 to gpr 10 (aligned to 4)
48 stw %r3, 16(%r1)
49 stw %r4, 20(%r1)
50 stw %r5, 24(%r1)
51 stw %r6, 28(%r1)
52 stw %r7, 32(%r1)
53 stw %r8, 36(%r1)
54 stw %r9, 40(%r1)
55 stw %r10,44(%r1)
56
Christian Heimes78644762008-03-04 23:39:23 +000057#ifndef __NO_FPRS__
Thomas Hellerd4c93202006-03-08 19:35:11 +000058 # next save fpr 1 to fpr 8 (aligned to 8)
59 stfd %f1, 48(%r1)
60 stfd %f2, 56(%r1)
61 stfd %f3, 64(%r1)
62 stfd %f4, 72(%r1)
63 stfd %f5, 80(%r1)
64 stfd %f6, 88(%r1)
65 stfd %f7, 96(%r1)
66 stfd %f8, 104(%r1)
Christian Heimes78644762008-03-04 23:39:23 +000067#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +000068
69 # set up registers for the routine that actually does the work
70 # get the context pointer from the trampoline
71 mr %r3,%r11
72
73 # now load up the pointer to the result storage
74 addi %r4,%r1,112
75
76 # now load up the pointer to the saved gpr registers
77 addi %r5,%r1,16
78
79 # now load up the pointer to the saved fpr registers */
80 addi %r6,%r1,48
81
82 # now load up the pointer to the outgoing parameter
83 # stack in the previous frame
84 # i.e. the previous frame pointer + 8
85 addi %r7,%r1,152
86
87 # make the call
88 bl ffi_closure_helper_SYSV@local
Christian Heimes78644762008-03-04 23:39:23 +000089.Lret:
Thomas Hellerd4c93202006-03-08 19:35:11 +000090 # now r3 contains the return type
91 # so use it to look up in a table
92 # so we know how to deal with each type
93
94 # look up the proper starting point in table
95 # by using return type as offset
Christian Heimes78644762008-03-04 23:39:23 +000096
97 mflr %r4 # move address of .Lret to r4
98 slwi %r3,%r3,4 # now multiply return type by 16
99 addi %r4, %r4, .Lret_type0 - .Lret
100 lwz %r0,148(%r1)
101 add %r3,%r3,%r4 # add contents of table to table address
Thomas Hellerd4c93202006-03-08 19:35:11 +0000102 mtctr %r3
Christian Heimes78644762008-03-04 23:39:23 +0000103 bctr # jump to it
Thomas Hellerd4c93202006-03-08 19:35:11 +0000104.LFE1:
105
106# Each of the ret_typeX code fragments has to be exactly 16 bytes long
107# (4 instructions). For cache effectiveness we align to a 16 byte boundary
108# first.
109 .align 4
Thomas Hellerd4c93202006-03-08 19:35:11 +0000110# case FFI_TYPE_VOID
111.Lret_type0:
Christian Heimes78644762008-03-04 23:39:23 +0000112 mtlr %r0
113 addi %r1,%r1,144
114 blr
Thomas Hellerd4c93202006-03-08 19:35:11 +0000115 nop
116
117# case FFI_TYPE_INT
Christian Heimes78644762008-03-04 23:39:23 +0000118 lwz %r3,112+0(%r1)
119 mtlr %r0
120.Lfinish:
121 addi %r1,%r1,144
122 blr
Thomas Hellerd4c93202006-03-08 19:35:11 +0000123
124# case FFI_TYPE_FLOAT
doko@ubuntu.com2a918762012-06-26 17:56:44 +0200125#ifndef __NO_FPRS__
Christian Heimes78644762008-03-04 23:39:23 +0000126 lfs %f1,112+0(%r1)
Thomas Hellerd4c93202006-03-08 19:35:11 +0000127 mtlr %r0
128 addi %r1,%r1,144
doko@ubuntu.com2a918762012-06-26 17:56:44 +0200129#else
130 nop
131 nop
132 nop
133#endif
Thomas Hellerd4c93202006-03-08 19:35:11 +0000134 blr
135
Christian Heimes78644762008-03-04 23:39:23 +0000136# case FFI_TYPE_DOUBLE
doko@ubuntu.com2a918762012-06-26 17:56:44 +0200137#ifndef __NO_FPRS__
Christian Heimes78644762008-03-04 23:39:23 +0000138 lfd %f1,112+0(%r1)
139 mtlr %r0
140 addi %r1,%r1,144
doko@ubuntu.com2a918762012-06-26 17:56:44 +0200141#else
142 nop
143 nop
144 nop
145#endif
Christian Heimes78644762008-03-04 23:39:23 +0000146 blr
147
148# case FFI_TYPE_LONGDOUBLE
doko@ubuntu.com2a918762012-06-26 17:56:44 +0200149#ifndef __NO_FPRS__
Christian Heimes78644762008-03-04 23:39:23 +0000150 lfd %f1,112+0(%r1)
151 lfd %f2,112+8(%r1)
152 mtlr %r0
Thomas Hellerd4c93202006-03-08 19:35:11 +0000153 b .Lfinish
doko@ubuntu.com2a918762012-06-26 17:56:44 +0200154#else
155 nop
156 nop
157 nop
158 blr
159#endif
Christian Heimes78644762008-03-04 23:39:23 +0000160
161# case FFI_TYPE_UINT8
162 lbz %r3,112+3(%r1)
163 mtlr %r0
164 addi %r1,%r1,144
165 blr
166
167# case FFI_TYPE_SINT8
168 lbz %r3,112+3(%r1)
169 extsb %r3,%r3
170 mtlr %r0
171 b .Lfinish
172
173# case FFI_TYPE_UINT16
174 lhz %r3,112+2(%r1)
175 mtlr %r0
176 addi %r1,%r1,144
177 blr
178
179# case FFI_TYPE_SINT16
180 lha %r3,112+2(%r1)
181 mtlr %r0
182 addi %r1,%r1,144
183 blr
184
185# case FFI_TYPE_UINT32
186 lwz %r3,112+0(%r1)
187 mtlr %r0
188 addi %r1,%r1,144
189 blr
190
191# case FFI_TYPE_SINT32
192 lwz %r3,112+0(%r1)
193 mtlr %r0
194 addi %r1,%r1,144
195 blr
196
197# case FFI_TYPE_UINT64
198 lwz %r3,112+0(%r1)
199 lwz %r4,112+4(%r1)
200 mtlr %r0
201 b .Lfinish
202
203# case FFI_TYPE_SINT64
204 lwz %r3,112+0(%r1)
205 lwz %r4,112+4(%r1)
206 mtlr %r0
207 b .Lfinish
208
209# case FFI_TYPE_STRUCT
210 mtlr %r0
211 addi %r1,%r1,144
212 blr
213 nop
214
215# case FFI_TYPE_POINTER
216 lwz %r3,112+0(%r1)
217 mtlr %r0
218 addi %r1,%r1,144
219 blr
220
221# case FFI_TYPE_UINT128
222 lwz %r3,112+0(%r1)
223 lwz %r4,112+4(%r1)
224 lwz %r5,112+8(%r1)
225 bl .Luint128
226
227# The return types below are only used when the ABI type is FFI_SYSV.
228# case FFI_SYSV_TYPE_SMALL_STRUCT + 1. One byte struct.
229 lbz %r3,112+0(%r1)
230 mtlr %r0
231 addi %r1,%r1,144
232 blr
233
234# case FFI_SYSV_TYPE_SMALL_STRUCT + 2. Two byte struct.
235 lhz %r3,112+0(%r1)
236 mtlr %r0
237 addi %r1,%r1,144
238 blr
239
240# case FFI_SYSV_TYPE_SMALL_STRUCT + 3. Three byte struct.
241 lwz %r3,112+0(%r1)
242 srwi %r3,%r3,8
243 mtlr %r0
244 b .Lfinish
245
246# case FFI_SYSV_TYPE_SMALL_STRUCT + 4. Four byte struct.
247 lwz %r3,112+0(%r1)
248 mtlr %r0
249 addi %r1,%r1,144
250 blr
251
252# case FFI_SYSV_TYPE_SMALL_STRUCT + 5. Five byte struct.
253 lwz %r3,112+0(%r1)
254 lwz %r4,112+4(%r1)
255 li %r5,24
256 b .Lstruct567
257
258# case FFI_SYSV_TYPE_SMALL_STRUCT + 6. Six byte struct.
259 lwz %r3,112+0(%r1)
260 lwz %r4,112+4(%r1)
261 li %r5,16
262 b .Lstruct567
263
264# case FFI_SYSV_TYPE_SMALL_STRUCT + 7. Seven byte struct.
265 lwz %r3,112+0(%r1)
266 lwz %r4,112+4(%r1)
267 li %r5,8
268 b .Lstruct567
269
270# case FFI_SYSV_TYPE_SMALL_STRUCT + 8. Eight byte struct.
271 lwz %r3,112+0(%r1)
272 lwz %r4,112+4(%r1)
273 mtlr %r0
274 b .Lfinish
275
276.Lstruct567:
277 subfic %r6,%r5,32
278 srw %r4,%r4,%r5
279 slw %r6,%r3,%r6
280 srw %r3,%r3,%r5
281 or %r4,%r6,%r4
282 mtlr %r0
283 addi %r1,%r1,144
284 blr
285
286.Luint128:
287 lwz %r6,112+12(%r1)
288 mtlr %r0
289 addi %r1,%r1,144
290 blr
291
Thomas Hellerd4c93202006-03-08 19:35:11 +0000292END(ffi_closure_SYSV)
293
294 .section ".eh_frame",EH_FRAME_FLAGS,@progbits
295.Lframe1:
296 .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
297.LSCIE1:
298 .4byte 0x0 # CIE Identifier Tag
299 .byte 0x1 # CIE Version
300#if defined _RELOCATABLE || defined __PIC__
301 .ascii "zR\0" # CIE Augmentation
302#else
303 .ascii "\0" # CIE Augmentation
304#endif
305 .uleb128 0x1 # CIE Code Alignment Factor
306 .sleb128 -4 # CIE Data Alignment Factor
307 .byte 0x41 # CIE RA Column
308#if defined _RELOCATABLE || defined __PIC__
309 .uleb128 0x1 # Augmentation size
310 .byte 0x1b # FDE Encoding (pcrel sdata4)
311#endif
312 .byte 0xc # DW_CFA_def_cfa
313 .uleb128 0x1
314 .uleb128 0x0
315 .align 2
316.LECIE1:
317.LSFDE1:
318 .4byte .LEFDE1-.LASFDE1 # FDE Length
319.LASFDE1:
320 .4byte .LASFDE1-.Lframe1 # FDE CIE offset
321#if defined _RELOCATABLE || defined __PIC__
322 .4byte .LFB1-. # FDE initial location
323#else
324 .4byte .LFB1 # FDE initial location
325#endif
326 .4byte .LFE1-.LFB1 # FDE address range
327#if defined _RELOCATABLE || defined __PIC__
328 .uleb128 0x0 # Augmentation size
329#endif
330 .byte 0x4 # DW_CFA_advance_loc4
331 .4byte .LCFI0-.LFB1
332 .byte 0xe # DW_CFA_def_cfa_offset
333 .uleb128 144
334 .byte 0x4 # DW_CFA_advance_loc4
335 .4byte .LCFI1-.LCFI0
336 .byte 0x11 # DW_CFA_offset_extended_sf
337 .uleb128 0x41
338 .sleb128 -1
339 .align 2
340.LEFDE1:
341
342#endif
Christian Heimes78644762008-03-04 23:39:23 +0000343
344#if defined __ELF__ && defined __linux__
345 .section .note.GNU-stack,"",@progbits
346#endif