1d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* -----------------------------------------------------------------------
2817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose   aix_closure.S - Copyright (c) 2002, 2003, 2009 Free Software Foundation, Inc.
3d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   based on darwin_closure.S
4d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
5d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   PowerPC Assembly glue.
6d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
7d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   Permission is hereby granted, free of charge, to any person obtaining
8d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   a copy of this software and associated documentation files (the
9d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   ``Software''), to deal in the Software without restriction, including
10d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   without limitation the rights to use, copy, modify, merge, publish,
11d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   distribute, sublicense, and/or sell copies of the Software, and to
12d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   permit persons to whom the Software is furnished to do so, subject to
13d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   the following conditions:
14d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
15d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   The above copyright notice and this permission notice shall be included
16d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   in all copies or substantial portions of the Software.
17d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
18d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
22d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   OTHER DEALINGS IN THE SOFTWARE.
25d4c9320412177895f598a93d73a0e654db27c351Thomas Heller   ----------------------------------------------------------------------- */
26d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
27d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r0,0
28d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r1,1
29d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r2,2
30d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r3,3
31d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r4,4
32d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r5,5
33d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r6,6
34d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r7,7
35d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r8,8
36d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r9,9
37d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r10,10
38d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r11,11
39d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r12,12
40d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r13,13
41d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r14,14
42d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r15,15
43d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r16,16
44d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r17,17
45d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r18,18
46d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r19,19
47d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r20,20
48d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r21,21
49d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r22,22
50d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r23,23
51d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r24,24
52d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r25,25
53d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r26,26
54d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r27,27
55d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r28,28
56d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r29,29
57d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r30,30
58d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set r31,31
59d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f0,0
60d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f1,1
61d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f2,2
62d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f3,3
63d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f4,4
64d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f5,5
65d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f6,6
66d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f7,7
67d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f8,8
68d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f9,9
69d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f10,10
70d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f11,11
71d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f12,12
72d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f13,13
73d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f14,14
74d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f15,15
75d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f16,16
76d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f17,17
77d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f18,18
78d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f19,19
79d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f20,20
80d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.set f21,21
81d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
8246ce27ab1e22ca98957e0900c6a2415b86578b2eGregory P. Smith	.extern .ffi_closure_helper_DARWIN
8346ce27ab1e22ca98957e0900c6a2415b86578b2eGregory P. Smith
84d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#define LIBFFI_ASM
85d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#define JUMPTARGET(name) name
86d4c9320412177895f598a93d73a0e654db27c351Thomas Heller#define L(x) x
87d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.file "aix_closure.S"
88d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.toc
89d4c9320412177895f598a93d73a0e654db27c351Thomas HellerLC..60:
90d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.tc L..60[TC],L..60
91d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.csect .text[PR]
92d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.align 2
93d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
94d4c9320412177895f598a93d73a0e654db27c351Thomas Heller.csect .text[PR]
95d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.align 2
96d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.globl ffi_closure_ASM
97d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.globl .ffi_closure_ASM
98d4c9320412177895f598a93d73a0e654db27c351Thomas Heller.csect ffi_closure_ASM[DS]
99d4c9320412177895f598a93d73a0e654db27c351Thomas Hellerffi_closure_ASM:
100817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose#ifdef __64BIT__
101817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	.llong .ffi_closure_ASM, TOC[tc0], 0
102d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	.csect .text[PR]
103d4c9320412177895f598a93d73a0e654db27c351Thomas Heller.ffi_closure_ASM:
104817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* we want to build up an area for the parameters passed */
105817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* in registers (both floating point and integer) */
106d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
107817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* we store gpr 3 to gpr 10 (aligned to 4)
108817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	in the parents outgoing area  */
109817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r3, 48+(0*8)(r1)
110817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r4, 48+(1*8)(r1)
111817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r5, 48+(2*8)(r1)
112817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r6, 48+(3*8)(r1)
113817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mflr  r0
114817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
115817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r7, 48+(4*8)(r1)
116817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r8, 48+(5*8)(r1)
117817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r9, 48+(6*8)(r1)
118817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r10, 48+(7*8)(r1)
119817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	std   r0, 16(r1)	/* save the return address */
120817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
121817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
122817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 48  Bytes (Linkage Area) */
123817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 64  Bytes (params) */
124817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 16  Bytes (result) */
125d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* 104 Bytes (13*8 from FPR) */
126817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 8   Bytes (alignment) */
127817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 240 Bytes */
128817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
129817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stdu  r1, -240(r1)	/* skip over caller save area
130817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose				   keep stack aligned to 16  */
131817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
132817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* next save fpr 1 to fpr 13 (aligned to 8) */
133817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f1, 128+(0*8)(r1)
134817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f2, 128+(1*8)(r1)
135817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f3, 128+(2*8)(r1)
136817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f4, 128+(3*8)(r1)
137817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f5, 128+(4*8)(r1)
138817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f6, 128+(5*8)(r1)
139817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f7, 128+(6*8)(r1)
140817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f8, 128+(7*8)(r1)
141817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f9, 128+(8*8)(r1)
142817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f10, 128+(9*8)(r1)
143817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f11, 128+(10*8)(r1)
144817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f12, 128+(11*8)(r1)
145817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f13, 128+(12*8)(r1)
146817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
147817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* set up registers for the routine that actually does the work */
148817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* get the context pointer from the trampoline */
149817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mr r3, r11
150817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
151817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* now load up the pointer to the result storage */
152817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r4, r1, 112
153817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
154817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* now load up the pointer to the saved gpr registers */
155817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r5, r1, 288
156817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
157817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* now load up the pointer to the saved fpr registers */
158817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r6, r1, 128
159817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
160817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* make the call */
161817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	bl .ffi_closure_helper_DARWIN
162817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	nop
163817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
164817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* now r3 contains the return type */
165817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* so use it to look up in a table */
166817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* so we know how to deal with each type */
167817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
168817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* look up the proper starting point in table  */
169817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* by using return type as offset */
17046ce27ab1e22ca98957e0900c6a2415b86578b2eGregory P. Smith	lhz	r3, 10(r3)	/* load type from return type */
171817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	ld	r4, LC..60(2)	/* get address of jump table */
172817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	sldi	r3, r3, 4	/* now multiply return type by 16 */
173817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	ld	r0, 240+16(r1)	/* load return address */
174817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	add	r3, r3, r4	/* add contents of table to table address */
175817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtctr	r3
176817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	bctr			/* jump to it */
177817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
178817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* Each fragment must be exactly 16 bytes long (4 instructions).
179817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose   Align to 16 byte boundary for cache and dispatch efficiency.  */
180817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	.align 4
181817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
182817acef0e6c6b33ade68132b090ea745badbbeceMatthias KloseL..60:
183817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_VOID */
184817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
185817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
186817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
187817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	nop
188817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
189817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_INT */
190817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwa r3, 112+4(r1)
191817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
192817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
193817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
194817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
195817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_FLOAT */
196817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfs f1, 112+0(r1)
197817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
198817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
199817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
200d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
201817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_DOUBLE */
202817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfd f1, 112+0(r1)
203817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
204817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
205817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
206817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
207817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_LONGDOUBLE */
208817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfd f1, 112+0(r1)
209817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
210817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfd f2, 112+8(r1)
211817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	b L..finish
212817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
213817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT8 */
214817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lbz r3, 112+7(r1)
215817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
216817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
217817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
218817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
219817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT8 */
220817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lbz r3, 112+7(r1)
221817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
222817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	extsb r3, r3
223817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	b L..finish
224817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
225817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT16 */
226817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lhz r3, 112+6(r1)
227817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
228817acef0e6c6b33ade68132b090ea745badbbeceMatthias KloseL..finish:
229817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
230817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
231d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
232817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT16 */
233817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lha r3, 112+6(r1)
234817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
235817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
236817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
237817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
238817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT32 */
239817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r3, 112+4(r1)
240817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
241817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
242817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
243817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
244817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT32 */
245817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwa r3, 112+4(r1)
246817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
247817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
248817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
249817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
250817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT64 */
251817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	ld r3, 112+0(r1)
252817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
253817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
254817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
255817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
256817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT64 */
257817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	ld r3, 112+0(r1)
258817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
259817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
260817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
261817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
262817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_STRUCT */
263817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
264817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
265817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
266817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	nop
267817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
268817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_POINTER */
269817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	ld r3, 112+0(r1)
270817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
271817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 240
272817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
273817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
274817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose#else /* ! __64BIT__ */
275817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
276817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	.long .ffi_closure_ASM, TOC[tc0], 0
277817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	.csect .text[PR]
278817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose.ffi_closure_ASM:
279d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* we want to build up an area for the parameters passed */
280d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* in registers (both floating point and integer) */
281d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
282d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* we store gpr 3 to gpr 10 (aligned to 4)
283d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	in the parents outgoing area  */
284817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r3, 24+(0*4)(r1)
285817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r4, 24+(1*4)(r1)
286817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r5, 24+(2*4)(r1)
287817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r6, 24+(3*4)(r1)
288817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mflr  r0
289817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
290817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r7, 24+(4*4)(r1)
291817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r8, 24+(5*4)(r1)
292817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r9, 24+(6*4)(r1)
293817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r10, 24+(7*4)(r1)
294817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stw   r0, 8(r1)
295817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
296817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 24 Bytes (Linkage Area) */
297817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 32 Bytes (params) */
298817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 16  Bytes (result) */
299817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 104 Bytes (13*8 from FPR) */
300817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	/* 176 Bytes */
301817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
302817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stwu  r1, -176(r1)	/* skip over caller save area
303817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose				   keep stack aligned to 16  */
304d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
305d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* next save fpr 1 to fpr 13 (aligned to 8) */
306817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f1, 72+(0*8)(r1)
307817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f2, 72+(1*8)(r1)
308817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f3, 72+(2*8)(r1)
309817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f4, 72+(3*8)(r1)
310817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f5, 72+(4*8)(r1)
311817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f6, 72+(5*8)(r1)
312817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f7, 72+(6*8)(r1)
313817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f8, 72+(7*8)(r1)
314817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f9, 72+(8*8)(r1)
315817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f10, 72+(9*8)(r1)
316817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f11, 72+(10*8)(r1)
317817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f12, 72+(11*8)(r1)
318817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	stfd  f13, 72+(12*8)(r1)
319d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
320d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* set up registers for the routine that actually does the work */
321d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* get the context pointer from the trampoline */
322817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mr r3, r11
323d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
324d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* now load up the pointer to the result storage */
325817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r4, r1, 56
326d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
327d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* now load up the pointer to the saved gpr registers */
328817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r5, r1, 200
329d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
330d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* now load up the pointer to the saved fpr registers */
331817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r6, r1, 72
332d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
333d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* make the call */
334d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	bl .ffi_closure_helper_DARWIN
335d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	nop
336d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
337d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* now r3 contains the return type */
338d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* so use it to look up in a table */
339d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* so we know how to deal with each type */
340d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
341d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* look up the proper starting point in table  */
342d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	/* by using return type as offset */
34346ce27ab1e22ca98957e0900c6a2415b86578b2eGregory P. Smith	lhz	r3, 6(r3)	/* load type from return type */
344817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz	r4, LC..60(2)	/* get address of jump table */
34546ce27ab1e22ca98957e0900c6a2415b86578b2eGregory P. Smith	slwi	r3, r3, 4	/* now multiply return type by 16 */
346817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz	r0, 176+8(r1)	/* load return address */
347817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	add	r3, r3, r4	/* add contents of table to table address */
348817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtctr	r3
349d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	bctr			/* jump to it */
350d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
351817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* Each fragment must be exactly 16 bytes long (4 instructions).
352817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose   Align to 16 byte boundary for cache and dispatch efficiency.  */
353817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	.align 4
354817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
355d4c9320412177895f598a93d73a0e654db27c351Thomas HellerL..60:
356817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_VOID */
357817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
358817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
359d4c9320412177895f598a93d73a0e654db27c351Thomas Heller	blr
360817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	nop
361817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
362817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_INT */
363817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r3, 56+0(r1)
364817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
365817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
366817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
367817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
368817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_FLOAT */
369817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfs f1, 56+0(r1)
370817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
371817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
372817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
373817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
374817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_DOUBLE */
375817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfd f1, 56+0(r1)
376817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
377817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
378817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
379817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
380817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_LONGDOUBLE */
381817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfd f1, 56+0(r1)
382817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
383817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lfd f2, 56+8(r1)
384817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	b L..finish
385817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
386817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT8 */
387817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lbz r3, 56+3(r1)
388817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
389817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
390817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
391817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
392817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT8 */
393817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lbz r3, 56+3(r1)
394817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
395817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	extsb r3, r3
396817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	b L..finish
397d4c9320412177895f598a93d73a0e654db27c351Thomas Heller
398817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT16 */
399817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lhz r3, 56+2(r1)
400817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
401817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
402817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
403817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
404817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT16 */
405817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lha r3, 56+2(r1)
406817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
407817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
408817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
409817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
410817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT32 */
411817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r3, 56+0(r1)
412817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
413817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
414817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
415817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
416817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT32 */
417817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r3, 56+0(r1)
418817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
419817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
420817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
421817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
422817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_UINT64 */
423817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r3, 56+0(r1)
424817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
425817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r4, 56+4(r1)
426817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	b L..finish
427817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
428817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_SINT64 */
429817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r3, 56+0(r1)
430817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
431817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r4, 56+4(r1)
432817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	b L..finish
433817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
434817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_STRUCT */
435817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
436817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
437817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
438817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	nop
439817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose
440817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose/* case FFI_TYPE_POINTER */
441817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	lwz r3, 56+0(r1)
442817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	mtlr r0
443817acef0e6c6b33ade68132b090ea745badbbeceMatthias KloseL..finish:
444817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	addi r1, r1, 176
445817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose	blr
446817acef0e6c6b33ade68132b090ea745badbbeceMatthias Klose#endif
447d4c9320412177895f598a93d73a0e654db27c351Thomas Heller/* END(ffi_closure_ASM) */
448