1457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique/* -----------------------------------------------------------------------
2457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   sysv.h - Copyright (c) 2003 Jakub Jelinek <jakub@redhat.com>
3457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	    Copyright (c) 2008 Red Hat, Inc.
4457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
5457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   PowerPC64 Assembly glue.
6457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
7457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   Permission is hereby granted, free of charge, to any person obtaining
8457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   a copy of this software and associated documentation files (the
9457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   ``Software''), to deal in the Software without restriction, including
10457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   without limitation the rights to use, copy, modify, merge, publish,
11457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   distribute, sublicense, and/or sell copies of the Software, and to
12457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   permit persons to whom the Software is furnished to do so, subject to
13457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   the following conditions:
14457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
15457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   The above copyright notice and this permission notice shall be included
16457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   in all copies or substantial portions of the Software.
17457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
18457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   DEALINGS IN THE SOFTWARE.
26457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique   ----------------------------------------------------------------------- */
27457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#define LIBFFI_ASM
28457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#include <fficonfig.h>
29457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#include <ffi.h>
30457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
31457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.file	"linux64_closure.S"
32457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
33457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#ifdef POWERPC64
34457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	FFI_HIDDEN (ffi_closure_LINUX64)
35457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.globl  ffi_closure_LINUX64
36457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# if _CALL_ELF == 2
37457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.text
38457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piqueffi_closure_LINUX64:
39457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addis	%r2, %r12, .TOC.-ffi_closure_LINUX64@ha
40457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi	%r2, %r2, .TOC.-ffi_closure_LINUX64@l
41457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.localentry ffi_closure_LINUX64, . - ffi_closure_LINUX64
42457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
43457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.section        ".opd","aw"
44457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.align  3
45457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Piqueffi_closure_LINUX64:
46457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  ifdef _CALL_LINUX
47457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.quad   .L.ffi_closure_LINUX64,.TOC.@tocbase,0
48457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.type   ffi_closure_LINUX64,@function
49457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.text
50457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.L.ffi_closure_LINUX64:
51457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  else
52457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	FFI_HIDDEN (.ffi_closure_LINUX64)
53457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.globl  .ffi_closure_LINUX64
54457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.quad   .ffi_closure_LINUX64,.TOC.@tocbase,0
55457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.size   ffi_closure_LINUX64,24
56457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.type   .ffi_closure_LINUX64,@function
57457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.text
58457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.ffi_closure_LINUX64:
59457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  endif
60457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
61457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
62457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# if _CALL_ELF == 2
63457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  32 byte special reg save area + 64 byte parm save area
64457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  + 64 byte retval area + 13*8 fpr save area + round to 16
65457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  define STACKFRAME 272
66457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  define PARMSAVE 32
67457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  define RETVAL PARMSAVE+64
68457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
69457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  48 bytes special reg save area + 64 bytes parm save area
70457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  + 16 bytes retval area + 13*8 bytes fpr save area + round to 16
71457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  define STACKFRAME 240
72457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  define PARMSAVE 48
73457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  define RETVAL PARMSAVE+64
74457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
75457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
76457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LFB1:
77457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# if _CALL_ELF == 2
78457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld	%r12, FFI_TRAMPOLINE_SIZE(%r11)		# closure->cif
79457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mflr	%r0
80457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lwz	%r12, 28(%r12)				# cif->flags
81457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtcrf	0x40, %r12
82457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi	%r12, %r1, PARMSAVE
83457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	bt	7, .Lparmsave
84457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# Our caller has not allocated a parameter save area.
85457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# We need to allocate one here and use it to pass gprs to
86457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# ffi_closure_helper_LINUX64.
87457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi	%r12, %r1, -STACKFRAME+PARMSAVE
88457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lparmsave:
89457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r0, 16(%r1)
90457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# Save general regs into parm save area
91457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r3, 0(%r12)
92457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r4, 8(%r12)
93457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r5, 16(%r12)
94457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r6, 24(%r12)
95457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r7, 32(%r12)
96457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r8, 40(%r12)
97457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r9, 48(%r12)
98457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r10, 56(%r12)
99457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
100457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# load up the pointer to the parm save area
101457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mr	%r5, %r12
102457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
103457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# copy r2 to r11 and load TOC into r2
104457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mr	%r11, %r2
105457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld	%r2, 16(%r11)
106457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
107457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mflr	%r0
108457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# Save general regs into parm save area
109457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# This is the parameter save area set up by our caller.
110457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r3, PARMSAVE+0(%r1)
111457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r4, PARMSAVE+8(%r1)
112457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r5, PARMSAVE+16(%r1)
113457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r6, PARMSAVE+24(%r1)
114457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r7, PARMSAVE+32(%r1)
115457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r8, PARMSAVE+40(%r1)
116457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r9, PARMSAVE+48(%r1)
117457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r10, PARMSAVE+56(%r1)
118457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
119457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	std	%r0, 16(%r1)
120457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
121457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# load up the pointer to the parm save area
122457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi	%r5, %r1, PARMSAVE
123457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
124457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
125457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# next save fpr 1 to fpr 13
126457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f1, -104+(0*8)(%r1)
127457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f2, -104+(1*8)(%r1)
128457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f3, -104+(2*8)(%r1)
129457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f4, -104+(3*8)(%r1)
130457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f5, -104+(4*8)(%r1)
131457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f6, -104+(5*8)(%r1)
132457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f7, -104+(6*8)(%r1)
133457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f8, -104+(7*8)(%r1)
134457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f9, -104+(8*8)(%r1)
135457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f10, -104+(9*8)(%r1)
136457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f11, -104+(10*8)(%r1)
137457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f12, -104+(11*8)(%r1)
138457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stfd	%f13, -104+(12*8)(%r1)
139457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
140457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# load up the pointer to the saved fpr registers */
141457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi	%r6, %r1, -104
142457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
143457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# load up the pointer to the result storage
144457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi	%r4, %r1, -STACKFRAME+RETVAL
145457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
146457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	stdu	%r1, -STACKFRAME(%r1)
147457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LCFI0:
148457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
149457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# get the context pointer from the trampoline
150457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mr	%r3, %r11
151457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
152457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# make the call
153457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# if defined _CALL_LINUX || _CALL_ELF == 2
154457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	bl ffi_closure_helper_LINUX64
155457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
156457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	bl .ffi_closure_helper_LINUX64
157457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
158457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lret:
159457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
160457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# now r3 contains the return type
161457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# so use it to look up in a table
162457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# so we know how to deal with each type
163457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
164457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# look up the proper starting point in table
165457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# by using return type as offset
166457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r0, STACKFRAME+16(%r1)
167457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT
168457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	bge .Lsmall
169457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mflr %r4		# move address of .Lret to r4
170457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	sldi %r3, %r3, 4	# now multiply return type by 16
171457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r4, %r4, .Lret_type0 - .Lret
172457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	add %r3, %r3, %r4	# add contents of table to table address
173457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtctr %r3
174457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	bctr			# jump to it
175457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
176457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# Each of the ret_typeX code fragments has to be exactly 16 bytes long
177457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# (4 instructions). For cache effectiveness we align to a 16 byte boundary
178457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# first.
179457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.align 4
180457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
181457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lret_type0:
182457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_VOID
183457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
184457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
185457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
186457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	nop
187457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_INT
188457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
189457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lwa %r3, RETVAL+0(%r1)
190457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
191457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lwa %r3, RETVAL+4(%r1)
192457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
193457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
194457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
195457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
196457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_FLOAT
197457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f1, RETVAL+0(%r1)
198457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
199457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
200457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
201457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_DOUBLE
202457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f1, RETVAL+0(%r1)
203457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
204457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
205457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
206457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_LONGDOUBLE
207457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f1, RETVAL+0(%r1)
208457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
209457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f2, RETVAL+8(%r1)
210457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	b .Lfinish
211457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_UINT8
212457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
213457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lbz %r3, RETVAL+0(%r1)
214457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
215457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lbz %r3, RETVAL+7(%r1)
216457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
217457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
218457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
219457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
220457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_SINT8
221457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
222457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lbz %r3, RETVAL+0(%r1)
223457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
224457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lbz %r3, RETVAL+7(%r1)
225457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
226457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	extsb %r3,%r3
227457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
228457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	b .Lfinish
229457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_UINT16
230457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
231457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lhz %r3, RETVAL+0(%r1)
232457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
233457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lhz %r3, RETVAL+6(%r1)
234457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
235457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
236457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lfinish:
237457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
238457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
239457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_SINT16
240457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
241457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lha %r3, RETVAL+0(%r1)
242457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
243457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lha %r3, RETVAL+6(%r1)
244457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
245457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
246457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
247457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
248457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_UINT32
249457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
250457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lwz %r3, RETVAL+0(%r1)
251457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
252457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lwz %r3, RETVAL+4(%r1)
253457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
254457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
255457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
256457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
257457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_SINT32
258457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
259457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lwa %r3, RETVAL+0(%r1)
260457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
261457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lwa %r3, RETVAL+4(%r1)
262457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
263457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
264457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
265457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
266457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_UINT64
267457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r3, RETVAL+0(%r1)
268457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
269457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
270457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
271457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_SINT64
272457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r3, RETVAL+0(%r1)
273457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
274457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
275457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
276457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_STRUCT
277457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
278457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
279457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
280457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	nop
281457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_TYPE_POINTER
282457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r3, RETVAL+0(%r1)
283457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
284457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
285457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
286457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_V2_TYPE_FLOAT_HOMOG
287457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f1, RETVAL+0(%r1)
288457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f2, RETVAL+4(%r1)
289457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f3, RETVAL+8(%r1)
290457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	b .Lmorefloat
291457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# case FFI_V2_TYPE_DOUBLE_HOMOG
292457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f1, RETVAL+0(%r1)
293457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f2, RETVAL+8(%r1)
294457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f3, RETVAL+16(%r1)
295457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f4, RETVAL+24(%r1)
296457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
297457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f5, RETVAL+32(%r1)
298457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f6, RETVAL+40(%r1)
299457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f7, RETVAL+48(%r1)
300457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfd %f8, RETVAL+56(%r1)
301457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
302457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
303457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lmorefloat:
304457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f4, RETVAL+12(%r1)
305457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
306457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f5, RETVAL+16(%r1)
307457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f6, RETVAL+20(%r1)
308457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f7, RETVAL+24(%r1)
309457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	lfs %f8, RETVAL+28(%r1)
310457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
311457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
312457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lsmall:
313457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# ifdef __LITTLE_ENDIAN__
314457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r3,RETVAL+0(%r1)
315457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
316457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r4,RETVAL+8(%r1)
317457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
318457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
319457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
320457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# A struct smaller than a dword is returned in the low bits of r3
321457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# ie. right justified.  Larger structs are passed left justified
322457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# in r3 and r4.  The return value area on the stack will have
323457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	# the structs as they are usually stored in memory.
324457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	cmpldi %r3, FFI_V2_TYPE_SMALL_STRUCT + 7 # size 8 bytes?
325457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	neg %r5, %r3
326457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r3,RETVAL+0(%r1)
327457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blt .Lsmalldown
328457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
329457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	ld %r4,RETVAL+8(%r1)
330457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
331457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
332457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lsmalldown:
333457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r5, %r5, FFI_V2_TYPE_SMALL_STRUCT + 7
334457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	mtlr %r0
335457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	sldi %r5, %r5, 3
336457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	addi %r1, %r1, STACKFRAME
337457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	srd %r3, %r3, %r5
338457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	blr
339457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
340457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
341457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LFE1:
342457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.long	0
343457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0,12,0,1,128,0,0,0
344457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# if _CALL_ELF == 2
345457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.size	ffi_closure_LINUX64,.-ffi_closure_LINUX64
346457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# else
347457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  ifdef _CALL_LINUX
348457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.size	ffi_closure_LINUX64,.-.L.ffi_closure_LINUX64
349457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  else
350457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.size	.ffi_closure_LINUX64,.-.ffi_closure_LINUX64
351457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#  endif
352457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
353457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
354457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
355457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.Lframe1:
356457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.4byte	.LECIE1-.LSCIE1	 # Length of Common Information Entry
357457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LSCIE1:
358457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.4byte	0x0	 # CIE Identifier Tag
359457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0x1	 # CIE Version
360457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.ascii "zR\0"	 # CIE Augmentation
361457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.uleb128 0x1	 # CIE Code Alignment Factor
362457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.sleb128 -8	 # CIE Data Alignment Factor
363457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0x41	 # CIE RA Column
364457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.uleb128 0x1	 # Augmentation size
365457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0x14	 # FDE Encoding (pcrel udata8)
366457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0xc	 # DW_CFA_def_cfa
367457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.uleb128 0x1
368457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.uleb128 0x0
369457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.align 3
370457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LECIE1:
371457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LSFDE1:
372457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.4byte	.LEFDE1-.LASFDE1	 # FDE Length
373457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LASFDE1:
374457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.4byte	.LASFDE1-.Lframe1	 # FDE CIE offset
375457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.8byte	.LFB1-.	 # FDE initial location
376457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.8byte	.LFE1-.LFB1	 # FDE address range
377457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.uleb128 0x0	 # Augmentation size
378457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0x2	 # DW_CFA_advance_loc1
379457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	.LCFI0-.LFB1
380457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0xe	 # DW_CFA_def_cfa_offset
381457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.uleb128 STACKFRAME
382457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.byte	0x11	 # DW_CFA_offset_extended_sf
383457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.uleb128 0x41
384457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.sleb128 -2
385457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.align 3
386457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique.LEFDE1:
387457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique
388457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# if defined __ELF__ && defined __linux__
389457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique	.section	.note.GNU-stack,"",@progbits
390457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique# endif
391457ba79995d512b9e8c07061fe10d4cd88273b2Lloyd Pique#endif
392