xref: /aosp_15_r20/external/libffi/src/nios2/sysv.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* Low-level libffi support for Altera Nios II.
2*1fd5a2e1SPrashanth Swaminathan
3*1fd5a2e1SPrashanth Swaminathan   Copyright (c) 2013 Mentor Graphics.
4*1fd5a2e1SPrashanth Swaminathan
5*1fd5a2e1SPrashanth Swaminathan   Permission is hereby granted, free of charge, to any person obtaining
6*1fd5a2e1SPrashanth Swaminathan   a copy of this software and associated documentation files (the
7*1fd5a2e1SPrashanth Swaminathan   ``Software''), to deal in the Software without restriction, including
8*1fd5a2e1SPrashanth Swaminathan   without limitation the rights to use, copy, modify, merge, publish,
9*1fd5a2e1SPrashanth Swaminathan   distribute, sublicense, and/or sell copies of the Software, and to
10*1fd5a2e1SPrashanth Swaminathan   permit persons to whom the Software is furnished to do so, subject to
11*1fd5a2e1SPrashanth Swaminathan   the following conditions:
12*1fd5a2e1SPrashanth Swaminathan
13*1fd5a2e1SPrashanth Swaminathan   The above copyright notice and this permission notice shall be
14*1fd5a2e1SPrashanth Swaminathan   included in all copies or substantial portions of the Software.
15*1fd5a2e1SPrashanth Swaminathan
16*1fd5a2e1SPrashanth Swaminathan   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
17*1fd5a2e1SPrashanth Swaminathan   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*1fd5a2e1SPrashanth Swaminathan   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19*1fd5a2e1SPrashanth Swaminathan   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20*1fd5a2e1SPrashanth Swaminathan   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21*1fd5a2e1SPrashanth Swaminathan   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22*1fd5a2e1SPrashanth Swaminathan   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.  */
23*1fd5a2e1SPrashanth Swaminathan
24*1fd5a2e1SPrashanth Swaminathan/* This function is declared on the C side as
25*1fd5a2e1SPrashanth Swaminathan
26*1fd5a2e1SPrashanth Swaminathan   extern UINT64 ffi_call_sysv (void (*arghook) (char *, extended_cif *),
27*1fd5a2e1SPrashanth Swaminathan	  		        extended_cif *ecif,
28*1fd5a2e1SPrashanth Swaminathan				unsigned nbytes,
29*1fd5a2e1SPrashanth Swaminathan				void (*fn) (void));
30*1fd5a2e1SPrashanth Swaminathan
31*1fd5a2e1SPrashanth Swaminathan   On input, the arguments appear as
32*1fd5a2e1SPrashanth Swaminathan	r4 = arghook
33*1fd5a2e1SPrashanth Swaminathan	r5 = ecif
34*1fd5a2e1SPrashanth Swaminathan	r6 = nbytes
35*1fd5a2e1SPrashanth Swaminathan	r7 = fn
36*1fd5a2e1SPrashanth Swaminathan*/
37*1fd5a2e1SPrashanth Swaminathan
38*1fd5a2e1SPrashanth Swaminathan	.section	.text
39*1fd5a2e1SPrashanth Swaminathan	.align	2
40*1fd5a2e1SPrashanth Swaminathan	.global	ffi_call_sysv
41*1fd5a2e1SPrashanth Swaminathan	.type	ffi_call_sysv, @function
42*1fd5a2e1SPrashanth Swaminathan
43*1fd5a2e1SPrashanth Swaminathanffi_call_sysv:
44*1fd5a2e1SPrashanth Swaminathan	.cfi_startproc
45*1fd5a2e1SPrashanth Swaminathan
46*1fd5a2e1SPrashanth Swaminathan	/* Create the stack frame, saving r16 so we can use it locally.  */
47*1fd5a2e1SPrashanth Swaminathan	addi	sp, sp, -12
48*1fd5a2e1SPrashanth Swaminathan	.cfi_def_cfa_offset 12
49*1fd5a2e1SPrashanth Swaminathan	stw	ra, 8(sp)
50*1fd5a2e1SPrashanth Swaminathan	stw	fp, 4(sp)
51*1fd5a2e1SPrashanth Swaminathan	stw	r16, 0(sp)
52*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 31, -4
53*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 28, -8
54*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 16, -12
55*1fd5a2e1SPrashanth Swaminathan	mov	fp, sp
56*1fd5a2e1SPrashanth Swaminathan	.cfi_def_cfa_register 28
57*1fd5a2e1SPrashanth Swaminathan	mov	r16, r7
58*1fd5a2e1SPrashanth Swaminathan
59*1fd5a2e1SPrashanth Swaminathan	/* Adjust the stack pointer to create the argument buffer
60*1fd5a2e1SPrashanth Swaminathan	   nbytes long.  */
61*1fd5a2e1SPrashanth Swaminathan	sub	sp, sp, r6
62*1fd5a2e1SPrashanth Swaminathan
63*1fd5a2e1SPrashanth Swaminathan	/* Call the arghook function.  */
64*1fd5a2e1SPrashanth Swaminathan	mov	r2, r4		/* fn */
65*1fd5a2e1SPrashanth Swaminathan	mov	r4, sp		/* argbuffer */
66*1fd5a2e1SPrashanth Swaminathan	callr	r2		/* r5 already contains ecif */
67*1fd5a2e1SPrashanth Swaminathan
68*1fd5a2e1SPrashanth Swaminathan	/* Pop off the first 16 bytes of the argument buffer on the stack,
69*1fd5a2e1SPrashanth Swaminathan	   transferring the contents to the argument registers.  */
70*1fd5a2e1SPrashanth Swaminathan	ldw	r4, 0(sp)
71*1fd5a2e1SPrashanth Swaminathan	ldw	r5, 4(sp)
72*1fd5a2e1SPrashanth Swaminathan	ldw	r6, 8(sp)
73*1fd5a2e1SPrashanth Swaminathan	ldw	r7, 12(sp)
74*1fd5a2e1SPrashanth Swaminathan	addi	sp, sp, 16
75*1fd5a2e1SPrashanth Swaminathan
76*1fd5a2e1SPrashanth Swaminathan	/* Call the user function, which leaves its result in r2 and r3.  */
77*1fd5a2e1SPrashanth Swaminathan	callr	r16
78*1fd5a2e1SPrashanth Swaminathan
79*1fd5a2e1SPrashanth Swaminathan	/* Pop off the stack frame.  */
80*1fd5a2e1SPrashanth Swaminathan	mov	sp, fp
81*1fd5a2e1SPrashanth Swaminathan	ldw	ra, 8(sp)
82*1fd5a2e1SPrashanth Swaminathan	ldw	fp, 4(sp)
83*1fd5a2e1SPrashanth Swaminathan	ldw	r16, 0(sp)
84*1fd5a2e1SPrashanth Swaminathan	addi	sp, sp, 12
85*1fd5a2e1SPrashanth Swaminathan	ret
86*1fd5a2e1SPrashanth Swaminathan	.cfi_endproc
87*1fd5a2e1SPrashanth Swaminathan	.size	ffi_call_sysv, .-ffi_call_sysv
88*1fd5a2e1SPrashanth Swaminathan
89*1fd5a2e1SPrashanth Swaminathan
90*1fd5a2e1SPrashanth Swaminathan/* Closure trampolines jump here after putting the C helper address
91*1fd5a2e1SPrashanth Swaminathan   in r9 and the closure pointer in r10.  The user-supplied arguments
92*1fd5a2e1SPrashanth Swaminathan   to the closure are in the normal places, in r4-r7 and on the
93*1fd5a2e1SPrashanth Swaminathan   stack.  Push the register arguments on the stack too and then call the
94*1fd5a2e1SPrashanth Swaminathan   C helper function to deal with them.  */
95*1fd5a2e1SPrashanth Swaminathan
96*1fd5a2e1SPrashanth Swaminathan	.section	.text
97*1fd5a2e1SPrashanth Swaminathan	.align	2
98*1fd5a2e1SPrashanth Swaminathan	.global	ffi_closure_sysv
99*1fd5a2e1SPrashanth Swaminathan	.type	ffi_closure_sysv, @function
100*1fd5a2e1SPrashanth Swaminathan
101*1fd5a2e1SPrashanth Swaminathanffi_closure_sysv:
102*1fd5a2e1SPrashanth Swaminathan	.cfi_startproc
103*1fd5a2e1SPrashanth Swaminathan
104*1fd5a2e1SPrashanth Swaminathan	/* Create the stack frame, pushing the register args on the stack
105*1fd5a2e1SPrashanth Swaminathan	   just below the stack args.  This is the same trick illustrated
106*1fd5a2e1SPrashanth Swaminathan	   in Figure 7-3 in the Nios II Processor Reference Handbook, used
107*1fd5a2e1SPrashanth Swaminathan	   for variable arguments and structures passed by value.  */
108*1fd5a2e1SPrashanth Swaminathan	addi	sp, sp, -20
109*1fd5a2e1SPrashanth Swaminathan	.cfi_def_cfa_offset 20
110*1fd5a2e1SPrashanth Swaminathan	stw	ra, 0(sp)
111*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 31, -20
112*1fd5a2e1SPrashanth Swaminathan	stw	r4, 4(sp)
113*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 4, -16
114*1fd5a2e1SPrashanth Swaminathan	stw	r5, 8(sp)
115*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 5, -12
116*1fd5a2e1SPrashanth Swaminathan	stw	r6, 12(sp)
117*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 6, -8
118*1fd5a2e1SPrashanth Swaminathan	stw	r7, 16(sp)
119*1fd5a2e1SPrashanth Swaminathan	.cfi_offset 7, -4
120*1fd5a2e1SPrashanth Swaminathan
121*1fd5a2e1SPrashanth Swaminathan	/* Call the helper.
122*1fd5a2e1SPrashanth Swaminathan	   r4 = pointer to arguments on stack
123*1fd5a2e1SPrashanth Swaminathan	   r5 = closure pointer (loaded in r10 by the trampoline)
124*1fd5a2e1SPrashanth Swaminathan	   r9 = address of helper function (loaded by trampoline) */
125*1fd5a2e1SPrashanth Swaminathan	addi	r4, sp, 4
126*1fd5a2e1SPrashanth Swaminathan	mov	r5, r10
127*1fd5a2e1SPrashanth Swaminathan	callr	r9
128*1fd5a2e1SPrashanth Swaminathan
129*1fd5a2e1SPrashanth Swaminathan	/* Pop the stack and return.  */
130*1fd5a2e1SPrashanth Swaminathan	ldw	ra, 0(sp)
131*1fd5a2e1SPrashanth Swaminathan	addi	sp, sp, 20
132*1fd5a2e1SPrashanth Swaminathan	.cfi_def_cfa_offset -20
133*1fd5a2e1SPrashanth Swaminathan	ret
134*1fd5a2e1SPrashanth Swaminathan	.cfi_endproc
135*1fd5a2e1SPrashanth Swaminathan	.size	ffi_closure_sysv, .-ffi_closure_sysv
136*1fd5a2e1SPrashanth Swaminathan
137