]> git.ipfire.org Git - thirdparty/gcc.git/blame - libffi/src/powerpc/linux64_closure.S
ffi.c (ffi_prep_args_SYSV): Move var declaration before statements.
[thirdparty/gcc.git] / libffi / src / powerpc / linux64_closure.S
CommitLineData
7446546a
AH
1/* -----------------------------------------------------------------------
2 sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
3 Copyright (c) 2008 Red Hat, Inc.
4
5 PowerPC64 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 ----------------------------------------------------------------------- */
a733b15e 27#define LIBFFI_ASM
1450eb7a 28#include <fficonfig.h>
a733b15e
JJ
29#include <ffi.h>
30
e9b84181
JJ
31 .file "linux64_closure.S"
32
33#ifdef __powerpc64__
8a42356f 34 FFI_HIDDEN (ffi_closure_LINUX64)
7054d980 35 .globl ffi_closure_LINUX64
16070e45
AT
36 .section ".opd","aw"
37 .align 3
e9b84181 38ffi_closure_LINUX64:
7054d980
AM
39#ifdef _CALL_LINUX
40 .quad .L.ffi_closure_LINUX64,.TOC.@tocbase,0
41 .type ffi_closure_LINUX64,@function
42 .text
43.L.ffi_closure_LINUX64:
44#else
45 FFI_HIDDEN (.ffi_closure_LINUX64)
46 .globl .ffi_closure_LINUX64
16070e45
AT
47 .quad .ffi_closure_LINUX64,.TOC.@tocbase,0
48 .size ffi_closure_LINUX64,24
49 .type .ffi_closure_LINUX64,@function
50 .text
e9b84181 51.ffi_closure_LINUX64:
7054d980 52#endif
e9b84181
JJ
53.LFB1:
54 # save general regs into parm save area
55 std %r3, 48(%r1)
56 std %r4, 56(%r1)
57 std %r5, 64(%r1)
58 std %r6, 72(%r1)
59 mflr %r0
60
61 std %r7, 80(%r1)
62 std %r8, 88(%r1)
63 std %r9, 96(%r1)
64 std %r10, 104(%r1)
65 std %r0, 16(%r1)
66
67 # mandatory 48 bytes special reg save area + 64 bytes parm save area
bf310028
AM
68 # + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
69 stdu %r1, -240(%r1)
e9b84181
JJ
70.LCFI0:
71
72 # next save fpr 1 to fpr 13
bf310028
AM
73 stfd %f1, 128+(0*8)(%r1)
74 stfd %f2, 128+(1*8)(%r1)
75 stfd %f3, 128+(2*8)(%r1)
76 stfd %f4, 128+(3*8)(%r1)
77 stfd %f5, 128+(4*8)(%r1)
78 stfd %f6, 128+(5*8)(%r1)
79 stfd %f7, 128+(6*8)(%r1)
80 stfd %f8, 128+(7*8)(%r1)
81 stfd %f9, 128+(8*8)(%r1)
82 stfd %f10, 128+(9*8)(%r1)
83 stfd %f11, 128+(10*8)(%r1)
84 stfd %f12, 128+(11*8)(%r1)
85 stfd %f13, 128+(12*8)(%r1)
e9b84181
JJ
86
87 # set up registers for the routine that actually does the work
88 # get the context pointer from the trampoline
89 mr %r3, %r11
90
91 # now load up the pointer to the result storage
92 addi %r4, %r1, 112
93
94 # now load up the pointer to the parameter save area
95 # in the previous frame
bf310028 96 addi %r5, %r1, 240 + 48
e9b84181
JJ
97
98 # now load up the pointer to the saved fpr registers */
bf310028 99 addi %r6, %r1, 128
e9b84181
JJ
100
101 # make the call
7054d980
AM
102#ifdef _CALL_LINUX
103 bl ffi_closure_helper_LINUX64
104#else
e9b84181 105 bl .ffi_closure_helper_LINUX64
7054d980 106#endif
b00badcd 107.Lret:
e9b84181
JJ
108
109 # now r3 contains the return type
110 # so use it to look up in a table
111 # so we know how to deal with each type
112
16070e45 113 # look up the proper starting point in table
e9b84181 114 # by using return type as offset
b00badcd 115 mflr %r4 # move address of .Lret to r4
e9b84181 116 sldi %r3, %r3, 4 # now multiply return type by 16
b00badcd 117 addi %r4, %r4, .Lret_type0 - .Lret
bf310028 118 ld %r0, 240+16(%r1)
e9b84181
JJ
119 add %r3, %r3, %r4 # add contents of table to table address
120 mtctr %r3
121 bctr # jump to it
122
123# Each of the ret_typeX code fragments has to be exactly 16 bytes long
124# (4 instructions). For cache effectiveness we align to a 16 byte boundary
125# first.
126 .align 4
127
e9b84181
JJ
128.Lret_type0:
129# case FFI_TYPE_VOID
b00badcd 130 mtlr %r0
bf310028 131 addi %r1, %r1, 240
b00badcd 132 blr
e9b84181
JJ
133 nop
134# case FFI_TYPE_INT
40b45a6d
AM
135#ifdef __LITTLE_ENDIAN__
136 lwa %r3, 112+0(%r1)
137#else
b00badcd 138 lwa %r3, 112+4(%r1)
40b45a6d 139#endif
b00badcd 140 mtlr %r0
bf310028 141 addi %r1, %r1, 240
b00badcd 142 blr
e9b84181 143# case FFI_TYPE_FLOAT
6350c02c 144 lfs %f1, 112+0(%r1)
b00badcd 145 mtlr %r0
bf310028 146 addi %r1, %r1, 240
b00badcd 147 blr
e9b84181 148# case FFI_TYPE_DOUBLE
b00badcd
AM
149 lfd %f1, 112+0(%r1)
150 mtlr %r0
bf310028 151 addi %r1, %r1, 240
b00badcd 152 blr
e9b84181 153# case FFI_TYPE_LONGDOUBLE
b00badcd
AM
154 lfd %f1, 112+0(%r1)
155 mtlr %r0
bf310028
AM
156 lfd %f2, 112+8(%r1)
157 b .Lfinish
e9b84181 158# case FFI_TYPE_UINT8
40b45a6d
AM
159#ifdef __LITTLE_ENDIAN__
160 lbz %r3, 112+0(%r1)
161#else
b00badcd 162 lbz %r3, 112+7(%r1)
40b45a6d 163#endif
b00badcd 164 mtlr %r0
bf310028 165 addi %r1, %r1, 240
b00badcd 166 blr
e9b84181 167# case FFI_TYPE_SINT8
40b45a6d
AM
168#ifdef __LITTLE_ENDIAN__
169 lbz %r3, 112+0(%r1)
170#else
b00badcd 171 lbz %r3, 112+7(%r1)
40b45a6d 172#endif
e9b84181 173 extsb %r3,%r3
b00badcd 174 mtlr %r0
e9b84181 175 b .Lfinish
e9b84181 176# case FFI_TYPE_UINT16
40b45a6d
AM
177#ifdef __LITTLE_ENDIAN__
178 lhz %r3, 112+0(%r1)
179#else
b00badcd 180 lhz %r3, 112+6(%r1)
40b45a6d 181#endif
b00badcd
AM
182 mtlr %r0
183.Lfinish:
bf310028 184 addi %r1, %r1, 240
b00badcd 185 blr
e9b84181 186# case FFI_TYPE_SINT16
40b45a6d
AM
187#ifdef __LITTLE_ENDIAN__
188 lha %r3, 112+0(%r1)
189#else
b00badcd 190 lha %r3, 112+6(%r1)
40b45a6d 191#endif
b00badcd 192 mtlr %r0
bf310028 193 addi %r1, %r1, 240
b00badcd 194 blr
e9b84181 195# case FFI_TYPE_UINT32
40b45a6d
AM
196#ifdef __LITTLE_ENDIAN__
197 lwz %r3, 112+0(%r1)
198#else
b00badcd 199 lwz %r3, 112+4(%r1)
40b45a6d 200#endif
b00badcd 201 mtlr %r0
bf310028 202 addi %r1, %r1, 240
b00badcd 203 blr
e9b84181 204# case FFI_TYPE_SINT32
40b45a6d
AM
205#ifdef __LITTLE_ENDIAN__
206 lwa %r3, 112+0(%r1)
207#else
b00badcd 208 lwa %r3, 112+4(%r1)
40b45a6d 209#endif
b00badcd 210 mtlr %r0
bf310028 211 addi %r1, %r1, 240
b00badcd 212 blr
e9b84181 213# case FFI_TYPE_UINT64
b00badcd
AM
214 ld %r3, 112+0(%r1)
215 mtlr %r0
bf310028 216 addi %r1, %r1, 240
b00badcd 217 blr
e9b84181 218# case FFI_TYPE_SINT64
b00badcd
AM
219 ld %r3, 112+0(%r1)
220 mtlr %r0
bf310028 221 addi %r1, %r1, 240
b00badcd 222 blr
e9b84181 223# case FFI_TYPE_STRUCT
b00badcd 224 mtlr %r0
bf310028 225 addi %r1, %r1, 240
b00badcd 226 blr
e9b84181
JJ
227 nop
228# case FFI_TYPE_POINTER
b00badcd 229 ld %r3, 112+0(%r1)
e9b84181 230 mtlr %r0
bf310028 231 addi %r1, %r1, 240
e9b84181 232 blr
b00badcd 233# esac
e9b84181
JJ
234.LFE1:
235 .long 0
236 .byte 0,12,0,1,128,0,0,0
7054d980
AM
237#ifdef _CALL_LINUX
238 .size ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
239#else
e9b84181 240 .size .ffi_closure_LINUX64,.-.ffi_closure_LINUX64
7054d980 241#endif
e9b84181 242
a733b15e 243 .section .eh_frame,EH_FRAME_FLAGS,@progbits
e9b84181
JJ
244.Lframe1:
245 .4byte .LECIE1-.LSCIE1 # Length of Common Information Entry
246.LSCIE1:
247 .4byte 0x0 # CIE Identifier Tag
248 .byte 0x1 # CIE Version
249 .ascii "zR\0" # CIE Augmentation
250 .uleb128 0x1 # CIE Code Alignment Factor
251 .sleb128 -8 # CIE Data Alignment Factor
252 .byte 0x41 # CIE RA Column
253 .uleb128 0x1 # Augmentation size
254 .byte 0x14 # FDE Encoding (pcrel udata8)
255 .byte 0xc # DW_CFA_def_cfa
256 .uleb128 0x1
257 .uleb128 0x0
258 .align 3
259.LECIE1:
260.LSFDE1:
261 .4byte .LEFDE1-.LASFDE1 # FDE Length
262.LASFDE1:
263 .4byte .LASFDE1-.Lframe1 # FDE CIE offset
264 .8byte .LFB1-. # FDE initial location
265 .8byte .LFE1-.LFB1 # FDE address range
266 .uleb128 0x0 # Augmentation size
267 .byte 0x2 # DW_CFA_advance_loc1
268 .byte .LCFI0-.LFB1
269 .byte 0xe # DW_CFA_def_cfa_offset
bf310028 270 .uleb128 240
e9b84181
JJ
271 .byte 0x11 # DW_CFA_offset_extended_sf
272 .uleb128 0x41
273 .sleb128 -2
274 .align 3
275.LEFDE1:
276#endif
7446546a
AH
277
278#if defined __ELF__ && defined __linux__
279 .section .note.GNU-stack,"",@progbits
280#endif