xref: /aosp_15_r20/external/libffi/src/cris/sysv.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan   sysv.S - Copyright (c) 2004 Simon Posnjak
3*1fd5a2e1SPrashanth Swaminathan	    Copyright (c) 2005 Axis Communications AB
4*1fd5a2e1SPrashanth Swaminathan
5*1fd5a2e1SPrashanth Swaminathan   CRIS Foreign Function Interface
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, EXPRESS
19*1fd5a2e1SPrashanth Swaminathan   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20*1fd5a2e1SPrashanth Swaminathan   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21*1fd5a2e1SPrashanth Swaminathan   IN NO EVENT SHALL SIMON POSNJAK BE LIABLE FOR ANY CLAIM, DAMAGES OR
22*1fd5a2e1SPrashanth Swaminathan   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23*1fd5a2e1SPrashanth Swaminathan   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24*1fd5a2e1SPrashanth Swaminathan   OTHER DEALINGS IN THE SOFTWARE.
25*1fd5a2e1SPrashanth Swaminathan   ----------------------------------------------------------------------- */
26*1fd5a2e1SPrashanth Swaminathan
27*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM
28*1fd5a2e1SPrashanth Swaminathan#include <ffi.h>
29*1fd5a2e1SPrashanth Swaminathan#define CONCAT(x,y) x ## y
30*1fd5a2e1SPrashanth Swaminathan#define XCONCAT(x,y) CONCAT (x, y)
31*1fd5a2e1SPrashanth Swaminathan#define L(x) XCONCAT (__USER_LABEL_PREFIX__, x)
32*1fd5a2e1SPrashanth Swaminathan
33*1fd5a2e1SPrashanth Swaminathan	.text
34*1fd5a2e1SPrashanth Swaminathan
35*1fd5a2e1SPrashanth Swaminathan	;; OK, when we get called we should have this (according to
36*1fd5a2e1SPrashanth Swaminathan	;; AXIS ETRAX 100LX Programmer's Manual chapter 6.3).
37*1fd5a2e1SPrashanth Swaminathan	;;
38*1fd5a2e1SPrashanth Swaminathan	;; R10:	 ffi_prep_args (func. pointer)
39*1fd5a2e1SPrashanth Swaminathan	;; R11:  &ecif
40*1fd5a2e1SPrashanth Swaminathan	;; R12:  cif->bytes
41*1fd5a2e1SPrashanth Swaminathan	;; R13:  fig->flags
42*1fd5a2e1SPrashanth Swaminathan	;; sp+0: ecif.rvalue
43*1fd5a2e1SPrashanth Swaminathan	;; sp+4: fn (function pointer to the function that we need to call)
44*1fd5a2e1SPrashanth Swaminathan
45*1fd5a2e1SPrashanth Swaminathan	.globl  L(ffi_call_SYSV)
46*1fd5a2e1SPrashanth Swaminathan	.type   L(ffi_call_SYSV),@function
47*1fd5a2e1SPrashanth Swaminathan	.hidden	L(ffi_call_SYSV)
48*1fd5a2e1SPrashanth Swaminathan
49*1fd5a2e1SPrashanth SwaminathanL(ffi_call_SYSV):
50*1fd5a2e1SPrashanth Swaminathan	;; Save the regs to the stack.
51*1fd5a2e1SPrashanth Swaminathan	push $srp
52*1fd5a2e1SPrashanth Swaminathan	;; Used for stack pointer saving.
53*1fd5a2e1SPrashanth Swaminathan	push $r6
54*1fd5a2e1SPrashanth Swaminathan	;; Used for function address pointer.
55*1fd5a2e1SPrashanth Swaminathan	push $r7
56*1fd5a2e1SPrashanth Swaminathan	;; Used for stack pointer saving.
57*1fd5a2e1SPrashanth Swaminathan	push $r8
58*1fd5a2e1SPrashanth Swaminathan	;; We save fig->flags to stack we will need them after we
59*1fd5a2e1SPrashanth Swaminathan	;; call The Function.
60*1fd5a2e1SPrashanth Swaminathan	push $r13
61*1fd5a2e1SPrashanth Swaminathan
62*1fd5a2e1SPrashanth Swaminathan	;; Saving current stack pointer.
63*1fd5a2e1SPrashanth Swaminathan	move.d $sp,$r8
64*1fd5a2e1SPrashanth Swaminathan	move.d $sp,$r6
65*1fd5a2e1SPrashanth Swaminathan
66*1fd5a2e1SPrashanth Swaminathan	;; Move address of ffi_prep_args to r13.
67*1fd5a2e1SPrashanth Swaminathan	move.d $r10,$r13
68*1fd5a2e1SPrashanth Swaminathan
69*1fd5a2e1SPrashanth Swaminathan	;; Make room on the stack for the args of fn.
70*1fd5a2e1SPrashanth Swaminathan	sub.d  $r12,$sp
71*1fd5a2e1SPrashanth Swaminathan
72*1fd5a2e1SPrashanth Swaminathan	;; Function void ffi_prep_args(char *stack, extended_cif *ecif) parameters are:
73*1fd5a2e1SPrashanth Swaminathan	;; 	r10 <-- stack pointer
74*1fd5a2e1SPrashanth Swaminathan	;; 	r11 <-- &ecif (already there)
75*1fd5a2e1SPrashanth Swaminathan	move.d $sp,$r10
76*1fd5a2e1SPrashanth Swaminathan
77*1fd5a2e1SPrashanth Swaminathan	;; Call the function.
78*1fd5a2e1SPrashanth Swaminathan	jsr $r13
79*1fd5a2e1SPrashanth Swaminathan
80*1fd5a2e1SPrashanth Swaminathan	;; Save the size of the structures which are passed on stack.
81*1fd5a2e1SPrashanth Swaminathan	move.d $r10,$r7
82*1fd5a2e1SPrashanth Swaminathan
83*1fd5a2e1SPrashanth Swaminathan	;; Move first four args in to r10..r13.
84*1fd5a2e1SPrashanth Swaminathan	move.d [$sp+0],$r10
85*1fd5a2e1SPrashanth Swaminathan	move.d [$sp+4],$r11
86*1fd5a2e1SPrashanth Swaminathan	move.d [$sp+8],$r12
87*1fd5a2e1SPrashanth Swaminathan	move.d [$sp+12],$r13
88*1fd5a2e1SPrashanth Swaminathan
89*1fd5a2e1SPrashanth Swaminathan	;; Adjust the stack and check if any parameters are given on stack.
90*1fd5a2e1SPrashanth Swaminathan	addq 16,$sp
91*1fd5a2e1SPrashanth Swaminathan	sub.d $r7,$r6
92*1fd5a2e1SPrashanth Swaminathan	cmp.d $sp,$r6
93*1fd5a2e1SPrashanth Swaminathan
94*1fd5a2e1SPrashanth Swaminathan	bpl go_on
95*1fd5a2e1SPrashanth Swaminathan	nop
96*1fd5a2e1SPrashanth Swaminathan
97*1fd5a2e1SPrashanth Swaminathango_on_no_params_on_stack:
98*1fd5a2e1SPrashanth Swaminathan	move.d $r6,$sp
99*1fd5a2e1SPrashanth Swaminathan
100*1fd5a2e1SPrashanth Swaminathango_on:
101*1fd5a2e1SPrashanth Swaminathan	;; Discover if we need to put rval address in to r9.
102*1fd5a2e1SPrashanth Swaminathan	move.d [$r8+0],$r7
103*1fd5a2e1SPrashanth Swaminathan	cmpq FFI_TYPE_STRUCT,$r7
104*1fd5a2e1SPrashanth Swaminathan	bne call_now
105*1fd5a2e1SPrashanth Swaminathan	nop
106*1fd5a2e1SPrashanth Swaminathan
107*1fd5a2e1SPrashanth Swaminathan	;; Move rval address to $r9.
108*1fd5a2e1SPrashanth Swaminathan	move.d [$r8+20],$r9
109*1fd5a2e1SPrashanth Swaminathan
110*1fd5a2e1SPrashanth Swaminathancall_now:
111*1fd5a2e1SPrashanth Swaminathan	;; Move address of The Function in to r7.
112*1fd5a2e1SPrashanth Swaminathan	move.d [$r8+24],$r7
113*1fd5a2e1SPrashanth Swaminathan
114*1fd5a2e1SPrashanth Swaminathan	;; Call The Function.
115*1fd5a2e1SPrashanth Swaminathan	jsr $r7
116*1fd5a2e1SPrashanth Swaminathan
117*1fd5a2e1SPrashanth Swaminathan	;; Reset stack.
118*1fd5a2e1SPrashanth Swaminathan	move.d $r8,$sp
119*1fd5a2e1SPrashanth Swaminathan
120*1fd5a2e1SPrashanth Swaminathan	;; Load rval type (fig->flags) in to r13.
121*1fd5a2e1SPrashanth Swaminathan	pop $r13
122*1fd5a2e1SPrashanth Swaminathan
123*1fd5a2e1SPrashanth Swaminathan	;; Detect rval type.
124*1fd5a2e1SPrashanth Swaminathan	cmpq FFI_TYPE_VOID,$r13
125*1fd5a2e1SPrashanth Swaminathan	beq epilogue
126*1fd5a2e1SPrashanth Swaminathan
127*1fd5a2e1SPrashanth Swaminathan	cmpq FFI_TYPE_STRUCT,$r13
128*1fd5a2e1SPrashanth Swaminathan	beq epilogue
129*1fd5a2e1SPrashanth Swaminathan
130*1fd5a2e1SPrashanth Swaminathan	cmpq FFI_TYPE_DOUBLE,$r13
131*1fd5a2e1SPrashanth Swaminathan	beq return_double_or_longlong
132*1fd5a2e1SPrashanth Swaminathan
133*1fd5a2e1SPrashanth Swaminathan	cmpq FFI_TYPE_UINT64,$r13
134*1fd5a2e1SPrashanth Swaminathan	beq return_double_or_longlong
135*1fd5a2e1SPrashanth Swaminathan
136*1fd5a2e1SPrashanth Swaminathan	cmpq FFI_TYPE_SINT64,$r13
137*1fd5a2e1SPrashanth Swaminathan	beq return_double_or_longlong
138*1fd5a2e1SPrashanth Swaminathan	nop
139*1fd5a2e1SPrashanth Swaminathan
140*1fd5a2e1SPrashanth Swaminathan	;; Just return the 32 bit value.
141*1fd5a2e1SPrashanth Swaminathan	ba return
142*1fd5a2e1SPrashanth Swaminathan	nop
143*1fd5a2e1SPrashanth Swaminathan
144*1fd5a2e1SPrashanth Swaminathanreturn_double_or_longlong:
145*1fd5a2e1SPrashanth Swaminathan	;; Load half of the rval to r10 and the other half to r11.
146*1fd5a2e1SPrashanth Swaminathan	move.d [$sp+16],$r13
147*1fd5a2e1SPrashanth Swaminathan	move.d $r10,[$r13]
148*1fd5a2e1SPrashanth Swaminathan	addq 4,$r13
149*1fd5a2e1SPrashanth Swaminathan	move.d $r11,[$r13]
150*1fd5a2e1SPrashanth Swaminathan	ba epilogue
151*1fd5a2e1SPrashanth Swaminathan	nop
152*1fd5a2e1SPrashanth Swaminathan
153*1fd5a2e1SPrashanth Swaminathanreturn:
154*1fd5a2e1SPrashanth Swaminathan	;; Load the rval to r10.
155*1fd5a2e1SPrashanth Swaminathan	move.d [$sp+16],$r13
156*1fd5a2e1SPrashanth Swaminathan	move.d $r10,[$r13]
157*1fd5a2e1SPrashanth Swaminathan
158*1fd5a2e1SPrashanth Swaminathanepilogue:
159*1fd5a2e1SPrashanth Swaminathan	pop $r8
160*1fd5a2e1SPrashanth Swaminathan	pop $r7
161*1fd5a2e1SPrashanth Swaminathan	pop $r6
162*1fd5a2e1SPrashanth Swaminathan	Jump [$sp+]
163*1fd5a2e1SPrashanth Swaminathan
164*1fd5a2e1SPrashanth Swaminathan	.size   ffi_call_SYSV,.-ffi_call_SYSV
165*1fd5a2e1SPrashanth Swaminathan
166*1fd5a2e1SPrashanth Swaminathan/* Save R10..R13 into an array, somewhat like varargs.  Copy the next
167*1fd5a2e1SPrashanth Swaminathan   argument too, to simplify handling of any straddling parameter.
168*1fd5a2e1SPrashanth Swaminathan   Save R9 and SP after those.  Jump to function handling the rest.
169*1fd5a2e1SPrashanth Swaminathan   Since this is a template, copied and the main function filled in by
170*1fd5a2e1SPrashanth Swaminathan   the user.  */
171*1fd5a2e1SPrashanth Swaminathan
172*1fd5a2e1SPrashanth Swaminathan	.globl	L(ffi_cris_trampoline_template)
173*1fd5a2e1SPrashanth Swaminathan	.type	L(ffi_cris_trampoline_template),@function
174*1fd5a2e1SPrashanth Swaminathan	.hidden	L(ffi_cris_trampoline_template)
175*1fd5a2e1SPrashanth Swaminathan
176*1fd5a2e1SPrashanth SwaminathanL(ffi_cris_trampoline_template):
177*1fd5a2e1SPrashanth Swaminathan0:
178*1fd5a2e1SPrashanth Swaminathan	/* The value we get for "PC" is right after the prefix instruction,
179*1fd5a2e1SPrashanth Swaminathan	   two bytes from the beginning, i.e. 0b+2. */
180*1fd5a2e1SPrashanth Swaminathan	move.d $r10,[$pc+2f-(0b+2)]
181*1fd5a2e1SPrashanth Swaminathan	move.d $pc,$r10
182*1fd5a2e1SPrashanth Swaminathan1:
183*1fd5a2e1SPrashanth Swaminathan	addq 2f-1b+4,$r10
184*1fd5a2e1SPrashanth Swaminathan	move.d $r11,[$r10+]
185*1fd5a2e1SPrashanth Swaminathan	move.d $r12,[$r10+]
186*1fd5a2e1SPrashanth Swaminathan	move.d $r13,[$r10+]
187*1fd5a2e1SPrashanth Swaminathan	move.d [$sp],$r11
188*1fd5a2e1SPrashanth Swaminathan	move.d $r11,[$r10+]
189*1fd5a2e1SPrashanth Swaminathan	move.d $r9,[$r10+]
190*1fd5a2e1SPrashanth Swaminathan	move.d $sp,[$r10+]
191*1fd5a2e1SPrashanth Swaminathan	subq FFI_CRIS_TRAMPOLINE_DATA_PART_SIZE,$r10
192*1fd5a2e1SPrashanth Swaminathan	move.d 0,$r11
193*1fd5a2e1SPrashanth Swaminathan3:
194*1fd5a2e1SPrashanth Swaminathan        jump 0
195*1fd5a2e1SPrashanth Swaminathan2:
196*1fd5a2e1SPrashanth Swaminathan	.size	ffi_cris_trampoline_template,.-0b
197*1fd5a2e1SPrashanth Swaminathan
198*1fd5a2e1SPrashanth Swaminathan/* This macro create a constant usable as "extern const int \name" in
199*1fd5a2e1SPrashanth Swaminathan   C from within libffi, when \name has no prefix decoration.  */
200*1fd5a2e1SPrashanth Swaminathan
201*1fd5a2e1SPrashanth Swaminathan	.macro const name,value
202*1fd5a2e1SPrashanth Swaminathan	.globl	\name
203*1fd5a2e1SPrashanth Swaminathan	.type	\name,@object
204*1fd5a2e1SPrashanth Swaminathan	.hidden	\name
205*1fd5a2e1SPrashanth Swaminathan\name:
206*1fd5a2e1SPrashanth Swaminathan	.dword  \value
207*1fd5a2e1SPrashanth Swaminathan	.size	\name,4
208*1fd5a2e1SPrashanth Swaminathan	.endm
209*1fd5a2e1SPrashanth Swaminathan
210*1fd5a2e1SPrashanth Swaminathan/* Constants for offsets within the trampoline.  We could do this with
211*1fd5a2e1SPrashanth Swaminathan   just symbols, avoiding memory contents and memory accesses, but the
212*1fd5a2e1SPrashanth Swaminathan   C usage code would look a bit stranger.  */
213*1fd5a2e1SPrashanth Swaminathan
214*1fd5a2e1SPrashanth Swaminathan	const L(ffi_cris_trampoline_fn_offset),2b-4-0b
215*1fd5a2e1SPrashanth Swaminathan	const L(ffi_cris_trampoline_closure_offset),3b-4-0b
216