xref: /aosp_15_r20/external/libffi/src/powerpc/sysv.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan   sysv.S - Copyright (c) 1998 Geoffrey Keating
3*1fd5a2e1SPrashanth Swaminathan   Copyright (C) 2007 Free Software Foundation, Inc
4*1fd5a2e1SPrashanth Swaminathan
5*1fd5a2e1SPrashanth Swaminathan   PowerPC Assembly glue.
6*1fd5a2e1SPrashanth Swaminathan
7*1fd5a2e1SPrashanth Swaminathan   Permission is hereby granted, free of charge, to any person obtaining
8*1fd5a2e1SPrashanth Swaminathan   a copy of this software and associated documentation files (the
9*1fd5a2e1SPrashanth Swaminathan   ``Software''), to deal in the Software without restriction, including
10*1fd5a2e1SPrashanth Swaminathan   without limitation the rights to use, copy, modify, merge, publish,
11*1fd5a2e1SPrashanth Swaminathan   distribute, sublicense, and/or sell copies of the Software, and to
12*1fd5a2e1SPrashanth Swaminathan   permit persons to whom the Software is furnished to do so, subject to
13*1fd5a2e1SPrashanth Swaminathan   the following conditions:
14*1fd5a2e1SPrashanth Swaminathan
15*1fd5a2e1SPrashanth Swaminathan   The above copyright notice and this permission notice shall be included
16*1fd5a2e1SPrashanth Swaminathan   in all copies or substantial portions of the Software.
17*1fd5a2e1SPrashanth Swaminathan
18*1fd5a2e1SPrashanth Swaminathan   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
19*1fd5a2e1SPrashanth Swaminathan   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*1fd5a2e1SPrashanth Swaminathan   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21*1fd5a2e1SPrashanth Swaminathan   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22*1fd5a2e1SPrashanth Swaminathan   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23*1fd5a2e1SPrashanth Swaminathan   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24*1fd5a2e1SPrashanth Swaminathan   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25*1fd5a2e1SPrashanth Swaminathan   DEALINGS IN THE SOFTWARE.
26*1fd5a2e1SPrashanth Swaminathan   ----------------------------------------------------------------------- */
27*1fd5a2e1SPrashanth Swaminathan
28*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM
29*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h>
30*1fd5a2e1SPrashanth Swaminathan#include <ffi.h>
31*1fd5a2e1SPrashanth Swaminathan#include <powerpc/asm.h>
32*1fd5a2e1SPrashanth Swaminathan
33*1fd5a2e1SPrashanth Swaminathan#ifndef POWERPC64
34*1fd5a2e1SPrashanth SwaminathanFFI_HIDDEN(ffi_call_SYSV)
35*1fd5a2e1SPrashanth SwaminathanENTRY(ffi_call_SYSV)
36*1fd5a2e1SPrashanth Swaminathan	.cfi_startproc
37*1fd5a2e1SPrashanth Swaminathan	/* Save the old stack pointer as AP.  */
38*1fd5a2e1SPrashanth Swaminathan	mr	%r10,%r1
39*1fd5a2e1SPrashanth Swaminathan	.cfi_def_cfa_register 10
40*1fd5a2e1SPrashanth Swaminathan
41*1fd5a2e1SPrashanth Swaminathan	/* Allocate the stack space we need.  */
42*1fd5a2e1SPrashanth Swaminathan	stwux	%r1,%r1,%r8
43*1fd5a2e1SPrashanth Swaminathan	/* Save registers we use.  */
44*1fd5a2e1SPrashanth Swaminathan	mflr	%r9
45*1fd5a2e1SPrashanth Swaminathan	stw	%r28,-16(%r10)
46*1fd5a2e1SPrashanth Swaminathan	stw	%r29,-12(%r10)
47*1fd5a2e1SPrashanth Swaminathan	stw	%r30, -8(%r10)
48*1fd5a2e1SPrashanth Swaminathan	stw	%r31, -4(%r10)
49*1fd5a2e1SPrashanth Swaminathan	stw	%r9,   4(%r10)
50*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 65, 4
51*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 31, -4
52*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 30, -8
53*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 29, -12
54*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 28, -16
55*1fd5a2e1SPrashanth Swaminathan
56*1fd5a2e1SPrashanth Swaminathan	/* Save arguments over call...  */
57*1fd5a2e1SPrashanth Swaminathan	stw	%r7,   -20(%r10)	/* closure, */
58*1fd5a2e1SPrashanth Swaminathan	mr	%r31,%r6		/* flags, */
59*1fd5a2e1SPrashanth Swaminathan	mr	%r30,%r5		/* rvalue, */
60*1fd5a2e1SPrashanth Swaminathan	mr	%r29,%r4		/* function address, */
61*1fd5a2e1SPrashanth Swaminathan	mr	%r28,%r10		/* our AP. */
62*1fd5a2e1SPrashanth Swaminathan	.cfi_def_cfa_register 28
63*1fd5a2e1SPrashanth Swaminathan
64*1fd5a2e1SPrashanth Swaminathan	/* Call ffi_prep_args_SYSV.  */
65*1fd5a2e1SPrashanth Swaminathan	mr	%r4,%r1
66*1fd5a2e1SPrashanth Swaminathan	bl	ffi_prep_args_SYSV@local
67*1fd5a2e1SPrashanth Swaminathan
68*1fd5a2e1SPrashanth Swaminathan	/* Now do the call.  */
69*1fd5a2e1SPrashanth Swaminathan	/* Set up cr1 with bits 4-7 of the flags.  */
70*1fd5a2e1SPrashanth Swaminathan	mtcrf	0x40,%r31
71*1fd5a2e1SPrashanth Swaminathan	/* Get the address to call into CTR.  */
72*1fd5a2e1SPrashanth Swaminathan	mtctr	%r29
73*1fd5a2e1SPrashanth Swaminathan	/* Load all those argument registers.  */
74*1fd5a2e1SPrashanth Swaminathan	lwz	%r3,-24-(8*4)(%r28)
75*1fd5a2e1SPrashanth Swaminathan	lwz	%r4,-24-(7*4)(%r28)
76*1fd5a2e1SPrashanth Swaminathan	lwz	%r5,-24-(6*4)(%r28)
77*1fd5a2e1SPrashanth Swaminathan	lwz	%r6,-24-(5*4)(%r28)
78*1fd5a2e1SPrashanth Swaminathan	bf-	5,1f
79*1fd5a2e1SPrashanth Swaminathan	nop
80*1fd5a2e1SPrashanth Swaminathan	lwz	%r7,-24-(4*4)(%r28)
81*1fd5a2e1SPrashanth Swaminathan	lwz	%r8,-24-(3*4)(%r28)
82*1fd5a2e1SPrashanth Swaminathan	lwz	%r9,-24-(2*4)(%r28)
83*1fd5a2e1SPrashanth Swaminathan	lwz	%r10,-24-(1*4)(%r28)
84*1fd5a2e1SPrashanth Swaminathan	nop
85*1fd5a2e1SPrashanth Swaminathan1:
86*1fd5a2e1SPrashanth Swaminathan
87*1fd5a2e1SPrashanth Swaminathan#ifndef __NO_FPRS__
88*1fd5a2e1SPrashanth Swaminathan	/* Load all the FP registers.  */
89*1fd5a2e1SPrashanth Swaminathan	bf-	6,2f
90*1fd5a2e1SPrashanth Swaminathan	lfd	%f1,-24-(8*4)-(8*8)(%r28)
91*1fd5a2e1SPrashanth Swaminathan	lfd	%f2,-24-(8*4)-(7*8)(%r28)
92*1fd5a2e1SPrashanth Swaminathan	lfd	%f3,-24-(8*4)-(6*8)(%r28)
93*1fd5a2e1SPrashanth Swaminathan	lfd	%f4,-24-(8*4)-(5*8)(%r28)
94*1fd5a2e1SPrashanth Swaminathan	nop
95*1fd5a2e1SPrashanth Swaminathan	lfd	%f5,-24-(8*4)-(4*8)(%r28)
96*1fd5a2e1SPrashanth Swaminathan	lfd	%f6,-24-(8*4)-(3*8)(%r28)
97*1fd5a2e1SPrashanth Swaminathan	lfd	%f7,-24-(8*4)-(2*8)(%r28)
98*1fd5a2e1SPrashanth Swaminathan	lfd	%f8,-24-(8*4)-(1*8)(%r28)
99*1fd5a2e1SPrashanth Swaminathan#endif
100*1fd5a2e1SPrashanth Swaminathan2:
101*1fd5a2e1SPrashanth Swaminathan
102*1fd5a2e1SPrashanth Swaminathan	/* Make the call.  */
103*1fd5a2e1SPrashanth Swaminathan	lwz	%r11, -20(%r28)
104*1fd5a2e1SPrashanth Swaminathan	bctrl
105*1fd5a2e1SPrashanth Swaminathan
106*1fd5a2e1SPrashanth Swaminathan	/* Now, deal with the return value.  */
107*1fd5a2e1SPrashanth Swaminathan	mtcrf	0x01,%r31 /* cr7  */
108*1fd5a2e1SPrashanth Swaminathan	bt-	31,L(small_struct_return_value)
109*1fd5a2e1SPrashanth Swaminathan	bt-	30,L(done_return_value)
110*1fd5a2e1SPrashanth Swaminathan#ifndef __NO_FPRS__
111*1fd5a2e1SPrashanth Swaminathan	bt-	29,L(fp_return_value)
112*1fd5a2e1SPrashanth Swaminathan#endif
113*1fd5a2e1SPrashanth Swaminathan	stw	%r3,0(%r30)
114*1fd5a2e1SPrashanth Swaminathan	bf+	28,L(done_return_value)
115*1fd5a2e1SPrashanth Swaminathan	stw	%r4,4(%r30)
116*1fd5a2e1SPrashanth Swaminathan	mtcrf	0x02,%r31 /* cr6  */
117*1fd5a2e1SPrashanth Swaminathan	bf	27,L(done_return_value)
118*1fd5a2e1SPrashanth Swaminathan	stw     %r5,8(%r30)
119*1fd5a2e1SPrashanth Swaminathan	stw	%r6,12(%r30)
120*1fd5a2e1SPrashanth Swaminathan	/* Fall through...  */
121*1fd5a2e1SPrashanth Swaminathan
122*1fd5a2e1SPrashanth SwaminathanL(done_return_value):
123*1fd5a2e1SPrashanth Swaminathan	/* Restore the registers we used and return.  */
124*1fd5a2e1SPrashanth Swaminathan	lwz	%r9,   4(%r28)
125*1fd5a2e1SPrashanth Swaminathan	lwz	%r31, -4(%r28)
126*1fd5a2e1SPrashanth Swaminathan	mtlr	%r9
127*1fd5a2e1SPrashanth Swaminathan	lwz	%r30, -8(%r28)
128*1fd5a2e1SPrashanth Swaminathan	lwz	%r29,-12(%r28)
129*1fd5a2e1SPrashanth Swaminathan	lwz	%r28,-16(%r28)
130*1fd5a2e1SPrashanth Swaminathan	.cfi_remember_state
131*1fd5a2e1SPrashanth Swaminathan	/* At this point we don't have a cfa register.  Say all our
132*1fd5a2e1SPrashanth Swaminathan	   saved regs have been restored.  */
133*1fd5a2e1SPrashanth Swaminathan	.cfi_same_value 65
134*1fd5a2e1SPrashanth Swaminathan	.cfi_same_value 31
135*1fd5a2e1SPrashanth Swaminathan	.cfi_same_value 30
136*1fd5a2e1SPrashanth Swaminathan	.cfi_same_value 29
137*1fd5a2e1SPrashanth Swaminathan	.cfi_same_value 28
138*1fd5a2e1SPrashanth Swaminathan	/* Hopefully this works..  */
139*1fd5a2e1SPrashanth Swaminathan	.cfi_def_cfa_register 1
140*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 1, 0
141*1fd5a2e1SPrashanth Swaminathan	lwz	%r1,0(%r1)
142*1fd5a2e1SPrashanth Swaminathan	.cfi_same_value 1
143*1fd5a2e1SPrashanth Swaminathan	blr
144*1fd5a2e1SPrashanth Swaminathan
145*1fd5a2e1SPrashanth Swaminathan#ifndef __NO_FPRS__
146*1fd5a2e1SPrashanth SwaminathanL(fp_return_value):
147*1fd5a2e1SPrashanth Swaminathan	.cfi_restore_state
148*1fd5a2e1SPrashanth Swaminathan	bf	28,L(float_return_value)
149*1fd5a2e1SPrashanth Swaminathan	stfd	%f1,0(%r30)
150*1fd5a2e1SPrashanth Swaminathan	mtcrf   0x02,%r31 /* cr6  */
151*1fd5a2e1SPrashanth Swaminathan	bf	27,L(done_return_value)
152*1fd5a2e1SPrashanth Swaminathan	stfd	%f2,8(%r30)
153*1fd5a2e1SPrashanth Swaminathan	b	L(done_return_value)
154*1fd5a2e1SPrashanth SwaminathanL(float_return_value):
155*1fd5a2e1SPrashanth Swaminathan	stfs	%f1,0(%r30)
156*1fd5a2e1SPrashanth Swaminathan	b	L(done_return_value)
157*1fd5a2e1SPrashanth Swaminathan#endif
158*1fd5a2e1SPrashanth Swaminathan
159*1fd5a2e1SPrashanth SwaminathanL(small_struct_return_value):
160*1fd5a2e1SPrashanth Swaminathan	/*
161*1fd5a2e1SPrashanth Swaminathan	 * The C code always allocates a properly-aligned 8-byte bounce
162*1fd5a2e1SPrashanth Swaminathan	 * buffer to make this assembly code very simple.  Just write out
163*1fd5a2e1SPrashanth Swaminathan	 * r3 and r4 to the buffer to allow the C code to handle the rest.
164*1fd5a2e1SPrashanth Swaminathan	 */
165*1fd5a2e1SPrashanth Swaminathan	stw %r3, 0(%r30)
166*1fd5a2e1SPrashanth Swaminathan	stw %r4, 4(%r30)
167*1fd5a2e1SPrashanth Swaminathan	b L(done_return_value)
168*1fd5a2e1SPrashanth Swaminathan	.cfi_endproc
169*1fd5a2e1SPrashanth Swaminathan
170*1fd5a2e1SPrashanth SwaminathanEND(ffi_call_SYSV)
171*1fd5a2e1SPrashanth Swaminathan
172*1fd5a2e1SPrashanth Swaminathan#if defined __ELF__ && defined __linux__
173*1fd5a2e1SPrashanth Swaminathan	.section	.note.GNU-stack,"",@progbits
174*1fd5a2e1SPrashanth Swaminathan#endif
175*1fd5a2e1SPrashanth Swaminathan#endif
176