xref: /aosp_15_r20/external/libffi/src/riscv/sysv.S (revision 1fd5a2e1d639cd1ddf29dd0c484c123bbd850c21)
1*1fd5a2e1SPrashanth Swaminathan/* -----------------------------------------------------------------------
2*1fd5a2e1SPrashanth Swaminathan   ffi.c - Copyright (c) 2015 Michael Knyszek <[email protected]>
3*1fd5a2e1SPrashanth Swaminathan                         2015 Andrew Waterman <[email protected]>
4*1fd5a2e1SPrashanth Swaminathan                         2018 Stef O'Rear <[email protected]>
5*1fd5a2e1SPrashanth Swaminathan
6*1fd5a2e1SPrashanth Swaminathan   RISC-V Foreign Function Interface
7*1fd5a2e1SPrashanth Swaminathan
8*1fd5a2e1SPrashanth Swaminathan   Permission is hereby granted, free of charge, to any person obtaining
9*1fd5a2e1SPrashanth Swaminathan   a copy of this software and associated documentation files (the
10*1fd5a2e1SPrashanth Swaminathan   ``Software''), to deal in the Software without restriction, including
11*1fd5a2e1SPrashanth Swaminathan   without limitation the rights to use, copy, modify, merge, publish,
12*1fd5a2e1SPrashanth Swaminathan   distribute, sublicense, and/or sell copies of the Software, and to
13*1fd5a2e1SPrashanth Swaminathan   permit persons to whom the Software is furnished to do so, subject to
14*1fd5a2e1SPrashanth Swaminathan   the following conditions:
15*1fd5a2e1SPrashanth Swaminathan
16*1fd5a2e1SPrashanth Swaminathan   The above copyright notice and this permission notice shall be included
17*1fd5a2e1SPrashanth Swaminathan   in all copies or substantial portions of the Software.
18*1fd5a2e1SPrashanth Swaminathan
19*1fd5a2e1SPrashanth Swaminathan   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20*1fd5a2e1SPrashanth Swaminathan   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21*1fd5a2e1SPrashanth Swaminathan   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22*1fd5a2e1SPrashanth Swaminathan   NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23*1fd5a2e1SPrashanth Swaminathan   HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24*1fd5a2e1SPrashanth Swaminathan   WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25*1fd5a2e1SPrashanth Swaminathan   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26*1fd5a2e1SPrashanth Swaminathan   DEALINGS IN THE SOFTWARE.
27*1fd5a2e1SPrashanth Swaminathan   ----------------------------------------------------------------------- */
28*1fd5a2e1SPrashanth Swaminathan
29*1fd5a2e1SPrashanth Swaminathan#define LIBFFI_ASM
30*1fd5a2e1SPrashanth Swaminathan#include <fficonfig.h>
31*1fd5a2e1SPrashanth Swaminathan#include <ffi.h>
32*1fd5a2e1SPrashanth Swaminathan
33*1fd5a2e1SPrashanth Swaminathan/* Define aliases so that we can handle all ABIs uniformly */
34*1fd5a2e1SPrashanth Swaminathan
35*1fd5a2e1SPrashanth Swaminathan#if __SIZEOF_POINTER__ == 8
36*1fd5a2e1SPrashanth Swaminathan#define PTRS 8
37*1fd5a2e1SPrashanth Swaminathan#define LARG ld
38*1fd5a2e1SPrashanth Swaminathan#define SARG sd
39*1fd5a2e1SPrashanth Swaminathan#else
40*1fd5a2e1SPrashanth Swaminathan#define PTRS 4
41*1fd5a2e1SPrashanth Swaminathan#define LARG lw
42*1fd5a2e1SPrashanth Swaminathan#define SARG sw
43*1fd5a2e1SPrashanth Swaminathan#endif
44*1fd5a2e1SPrashanth Swaminathan
45*1fd5a2e1SPrashanth Swaminathan#if __riscv_float_abi_double
46*1fd5a2e1SPrashanth Swaminathan#define FLTS 8
47*1fd5a2e1SPrashanth Swaminathan#define FLARG fld
48*1fd5a2e1SPrashanth Swaminathan#define FSARG fsd
49*1fd5a2e1SPrashanth Swaminathan#elif __riscv_float_abi_single
50*1fd5a2e1SPrashanth Swaminathan#define FLTS 4
51*1fd5a2e1SPrashanth Swaminathan#define FLARG flw
52*1fd5a2e1SPrashanth Swaminathan#define FSARG fsw
53*1fd5a2e1SPrashanth Swaminathan#else
54*1fd5a2e1SPrashanth Swaminathan#define FLTS 0
55*1fd5a2e1SPrashanth Swaminathan#endif
56*1fd5a2e1SPrashanth Swaminathan
57*1fd5a2e1SPrashanth Swaminathan#define fp s0
58*1fd5a2e1SPrashanth Swaminathan
59*1fd5a2e1SPrashanth Swaminathan    .text
60*1fd5a2e1SPrashanth Swaminathan    .globl  ffi_call_asm
61*1fd5a2e1SPrashanth Swaminathan    .type   ffi_call_asm, @function
62*1fd5a2e1SPrashanth Swaminathan    .hidden ffi_call_asm
63*1fd5a2e1SPrashanth Swaminathan/*
64*1fd5a2e1SPrashanth Swaminathan  struct call_context {
65*1fd5a2e1SPrashanth Swaminathan      floatreg fa[8];
66*1fd5a2e1SPrashanth Swaminathan      intreg a[8];
67*1fd5a2e1SPrashanth Swaminathan      intreg pad[rv32 ? 2 : 0];
68*1fd5a2e1SPrashanth Swaminathan      intreg save_fp, save_ra;
69*1fd5a2e1SPrashanth Swaminathan  }
70*1fd5a2e1SPrashanth Swaminathan  void ffi_call_asm (size_t *stackargs, struct call_context *regargs,
71*1fd5a2e1SPrashanth Swaminathan                     void (*fn) (void), void *closure);
72*1fd5a2e1SPrashanth Swaminathan*/
73*1fd5a2e1SPrashanth Swaminathan
74*1fd5a2e1SPrashanth Swaminathan#define FRAME_LEN (8 * FLTS + 8 * PTRS + 16)
75*1fd5a2e1SPrashanth Swaminathan
76*1fd5a2e1SPrashanth Swaminathanffi_call_asm:
77*1fd5a2e1SPrashanth Swaminathan    .cfi_startproc
78*1fd5a2e1SPrashanth Swaminathan
79*1fd5a2e1SPrashanth Swaminathan    /*
80*1fd5a2e1SPrashanth Swaminathan      We are NOT going to set up an ordinary stack frame.  In order to pass
81*1fd5a2e1SPrashanth Swaminathan      the stacked args to the called function, we adjust our stack pointer to
82*1fd5a2e1SPrashanth Swaminathan      a0, which is in the _caller's_ alloca area.  We establish our own stack
83*1fd5a2e1SPrashanth Swaminathan      frame at the end of the call_context.
84*1fd5a2e1SPrashanth Swaminathan
85*1fd5a2e1SPrashanth Swaminathan      Anything below the arguments will be freed at this point, although we
86*1fd5a2e1SPrashanth Swaminathan      preserve the call_context so that it can be read back in the caller.
87*1fd5a2e1SPrashanth Swaminathan    */
88*1fd5a2e1SPrashanth Swaminathan
89*1fd5a2e1SPrashanth Swaminathan    .cfi_def_cfa 11, FRAME_LEN # interim CFA based on a1
90*1fd5a2e1SPrashanth Swaminathan    SARG    fp, FRAME_LEN - 2*PTRS(a1)
91*1fd5a2e1SPrashanth Swaminathan    .cfi_offset 8, -2*PTRS
92*1fd5a2e1SPrashanth Swaminathan    SARG    ra, FRAME_LEN - 1*PTRS(a1)
93*1fd5a2e1SPrashanth Swaminathan    .cfi_offset 1, -1*PTRS
94*1fd5a2e1SPrashanth Swaminathan
95*1fd5a2e1SPrashanth Swaminathan    addi    fp, a1, FRAME_LEN
96*1fd5a2e1SPrashanth Swaminathan    mv      sp, a0
97*1fd5a2e1SPrashanth Swaminathan    .cfi_def_cfa 8, 0 # our frame is fully set up
98*1fd5a2e1SPrashanth Swaminathan
99*1fd5a2e1SPrashanth Swaminathan    # Load arguments
100*1fd5a2e1SPrashanth Swaminathan    mv      t1, a2
101*1fd5a2e1SPrashanth Swaminathan    mv      t2, a3
102*1fd5a2e1SPrashanth Swaminathan
103*1fd5a2e1SPrashanth Swaminathan#if FLTS
104*1fd5a2e1SPrashanth Swaminathan    FLARG   fa0, -FRAME_LEN+0*FLTS(fp)
105*1fd5a2e1SPrashanth Swaminathan    FLARG   fa1, -FRAME_LEN+1*FLTS(fp)
106*1fd5a2e1SPrashanth Swaminathan    FLARG   fa2, -FRAME_LEN+2*FLTS(fp)
107*1fd5a2e1SPrashanth Swaminathan    FLARG   fa3, -FRAME_LEN+3*FLTS(fp)
108*1fd5a2e1SPrashanth Swaminathan    FLARG   fa4, -FRAME_LEN+4*FLTS(fp)
109*1fd5a2e1SPrashanth Swaminathan    FLARG   fa5, -FRAME_LEN+5*FLTS(fp)
110*1fd5a2e1SPrashanth Swaminathan    FLARG   fa6, -FRAME_LEN+6*FLTS(fp)
111*1fd5a2e1SPrashanth Swaminathan    FLARG   fa7, -FRAME_LEN+7*FLTS(fp)
112*1fd5a2e1SPrashanth Swaminathan#endif
113*1fd5a2e1SPrashanth Swaminathan
114*1fd5a2e1SPrashanth Swaminathan    LARG    a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
115*1fd5a2e1SPrashanth Swaminathan    LARG    a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
116*1fd5a2e1SPrashanth Swaminathan    LARG    a2, -FRAME_LEN+8*FLTS+2*PTRS(fp)
117*1fd5a2e1SPrashanth Swaminathan    LARG    a3, -FRAME_LEN+8*FLTS+3*PTRS(fp)
118*1fd5a2e1SPrashanth Swaminathan    LARG    a4, -FRAME_LEN+8*FLTS+4*PTRS(fp)
119*1fd5a2e1SPrashanth Swaminathan    LARG    a5, -FRAME_LEN+8*FLTS+5*PTRS(fp)
120*1fd5a2e1SPrashanth Swaminathan    LARG    a6, -FRAME_LEN+8*FLTS+6*PTRS(fp)
121*1fd5a2e1SPrashanth Swaminathan    LARG    a7, -FRAME_LEN+8*FLTS+7*PTRS(fp)
122*1fd5a2e1SPrashanth Swaminathan
123*1fd5a2e1SPrashanth Swaminathan    /* Call */
124*1fd5a2e1SPrashanth Swaminathan    jalr    t1
125*1fd5a2e1SPrashanth Swaminathan
126*1fd5a2e1SPrashanth Swaminathan    /* Save return values - only a0/a1 (fa0/fa1) are used */
127*1fd5a2e1SPrashanth Swaminathan#if FLTS
128*1fd5a2e1SPrashanth Swaminathan    FSARG   fa0, -FRAME_LEN+0*FLTS(fp)
129*1fd5a2e1SPrashanth Swaminathan    FSARG   fa1, -FRAME_LEN+1*FLTS(fp)
130*1fd5a2e1SPrashanth Swaminathan#endif
131*1fd5a2e1SPrashanth Swaminathan
132*1fd5a2e1SPrashanth Swaminathan    SARG    a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
133*1fd5a2e1SPrashanth Swaminathan    SARG    a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
134*1fd5a2e1SPrashanth Swaminathan
135*1fd5a2e1SPrashanth Swaminathan    /* Restore and return */
136*1fd5a2e1SPrashanth Swaminathan    addi    sp, fp, -FRAME_LEN
137*1fd5a2e1SPrashanth Swaminathan    .cfi_def_cfa 2, FRAME_LEN
138*1fd5a2e1SPrashanth Swaminathan    LARG    ra, -1*PTRS(fp)
139*1fd5a2e1SPrashanth Swaminathan    .cfi_restore 1
140*1fd5a2e1SPrashanth Swaminathan    LARG    fp, -2*PTRS(fp)
141*1fd5a2e1SPrashanth Swaminathan    .cfi_restore 8
142*1fd5a2e1SPrashanth Swaminathan    ret
143*1fd5a2e1SPrashanth Swaminathan    .cfi_endproc
144*1fd5a2e1SPrashanth Swaminathan    .size   ffi_call_asm, .-ffi_call_asm
145*1fd5a2e1SPrashanth Swaminathan
146*1fd5a2e1SPrashanth Swaminathan
147*1fd5a2e1SPrashanth Swaminathan/*
148*1fd5a2e1SPrashanth Swaminathan  ffi_closure_asm. Expects address of the passed-in ffi_closure in t1.
149*1fd5a2e1SPrashanth Swaminathan  void ffi_closure_inner (ffi_cif *cif,
150*1fd5a2e1SPrashanth Swaminathan		          void (*fun) (ffi_cif *, void *, void **, void *),
151*1fd5a2e1SPrashanth Swaminathan		          void *user_data,
152*1fd5a2e1SPrashanth Swaminathan		          size_t *stackargs, struct call_context *regargs)
153*1fd5a2e1SPrashanth Swaminathan*/
154*1fd5a2e1SPrashanth Swaminathan
155*1fd5a2e1SPrashanth Swaminathan    .globl ffi_closure_asm
156*1fd5a2e1SPrashanth Swaminathan    .hidden ffi_closure_asm
157*1fd5a2e1SPrashanth Swaminathan    .type ffi_closure_asm, @function
158*1fd5a2e1SPrashanth Swaminathanffi_closure_asm:
159*1fd5a2e1SPrashanth Swaminathan    .cfi_startproc
160*1fd5a2e1SPrashanth Swaminathan
161*1fd5a2e1SPrashanth Swaminathan    addi    sp,  sp, -FRAME_LEN
162*1fd5a2e1SPrashanth Swaminathan    .cfi_def_cfa_offset FRAME_LEN
163*1fd5a2e1SPrashanth Swaminathan
164*1fd5a2e1SPrashanth Swaminathan    /* make a frame */
165*1fd5a2e1SPrashanth Swaminathan    SARG    fp, FRAME_LEN - 2*PTRS(sp)
166*1fd5a2e1SPrashanth Swaminathan    .cfi_offset 8, -2*PTRS
167*1fd5a2e1SPrashanth Swaminathan    SARG    ra, FRAME_LEN - 1*PTRS(sp)
168*1fd5a2e1SPrashanth Swaminathan    .cfi_offset 1, -1*PTRS
169*1fd5a2e1SPrashanth Swaminathan    addi    fp, sp, FRAME_LEN
170*1fd5a2e1SPrashanth Swaminathan
171*1fd5a2e1SPrashanth Swaminathan    /* save arguments */
172*1fd5a2e1SPrashanth Swaminathan#if FLTS
173*1fd5a2e1SPrashanth Swaminathan    FSARG   fa0, 0*FLTS(sp)
174*1fd5a2e1SPrashanth Swaminathan    FSARG   fa1, 1*FLTS(sp)
175*1fd5a2e1SPrashanth Swaminathan    FSARG   fa2, 2*FLTS(sp)
176*1fd5a2e1SPrashanth Swaminathan    FSARG   fa3, 3*FLTS(sp)
177*1fd5a2e1SPrashanth Swaminathan    FSARG   fa4, 4*FLTS(sp)
178*1fd5a2e1SPrashanth Swaminathan    FSARG   fa5, 5*FLTS(sp)
179*1fd5a2e1SPrashanth Swaminathan    FSARG   fa6, 6*FLTS(sp)
180*1fd5a2e1SPrashanth Swaminathan    FSARG   fa7, 7*FLTS(sp)
181*1fd5a2e1SPrashanth Swaminathan#endif
182*1fd5a2e1SPrashanth Swaminathan
183*1fd5a2e1SPrashanth Swaminathan    SARG    a0, 8*FLTS+0*PTRS(sp)
184*1fd5a2e1SPrashanth Swaminathan    SARG    a1, 8*FLTS+1*PTRS(sp)
185*1fd5a2e1SPrashanth Swaminathan    SARG    a2, 8*FLTS+2*PTRS(sp)
186*1fd5a2e1SPrashanth Swaminathan    SARG    a3, 8*FLTS+3*PTRS(sp)
187*1fd5a2e1SPrashanth Swaminathan    SARG    a4, 8*FLTS+4*PTRS(sp)
188*1fd5a2e1SPrashanth Swaminathan    SARG    a5, 8*FLTS+5*PTRS(sp)
189*1fd5a2e1SPrashanth Swaminathan    SARG    a6, 8*FLTS+6*PTRS(sp)
190*1fd5a2e1SPrashanth Swaminathan    SARG    a7, 8*FLTS+7*PTRS(sp)
191*1fd5a2e1SPrashanth Swaminathan
192*1fd5a2e1SPrashanth Swaminathan    /* enter C */
193*1fd5a2e1SPrashanth Swaminathan    LARG    a0, FFI_TRAMPOLINE_SIZE+0*PTRS(t1)
194*1fd5a2e1SPrashanth Swaminathan    LARG    a1, FFI_TRAMPOLINE_SIZE+1*PTRS(t1)
195*1fd5a2e1SPrashanth Swaminathan    LARG    a2, FFI_TRAMPOLINE_SIZE+2*PTRS(t1)
196*1fd5a2e1SPrashanth Swaminathan    addi    a3, sp, FRAME_LEN
197*1fd5a2e1SPrashanth Swaminathan    mv      a4, sp
198*1fd5a2e1SPrashanth Swaminathan
199*1fd5a2e1SPrashanth Swaminathan    call    ffi_closure_inner
200*1fd5a2e1SPrashanth Swaminathan
201*1fd5a2e1SPrashanth Swaminathan    /* return values */
202*1fd5a2e1SPrashanth Swaminathan#if FLTS
203*1fd5a2e1SPrashanth Swaminathan    FLARG   fa0, 0*FLTS(sp)
204*1fd5a2e1SPrashanth Swaminathan    FLARG   fa1, 1*FLTS(sp)
205*1fd5a2e1SPrashanth Swaminathan#endif
206*1fd5a2e1SPrashanth Swaminathan
207*1fd5a2e1SPrashanth Swaminathan    LARG    a0, 8*FLTS+0*PTRS(sp)
208*1fd5a2e1SPrashanth Swaminathan    LARG    a1, 8*FLTS+1*PTRS(sp)
209*1fd5a2e1SPrashanth Swaminathan
210*1fd5a2e1SPrashanth Swaminathan    /* restore and return */
211*1fd5a2e1SPrashanth Swaminathan    LARG    ra, FRAME_LEN-1*PTRS(sp)
212*1fd5a2e1SPrashanth Swaminathan    .cfi_restore 1
213*1fd5a2e1SPrashanth Swaminathan    LARG    fp, FRAME_LEN-2*PTRS(sp)
214*1fd5a2e1SPrashanth Swaminathan    .cfi_restore 8
215*1fd5a2e1SPrashanth Swaminathan    addi    sp, sp, FRAME_LEN
216*1fd5a2e1SPrashanth Swaminathan    .cfi_def_cfa_offset 0
217*1fd5a2e1SPrashanth Swaminathan    ret
218*1fd5a2e1SPrashanth Swaminathan    .cfi_endproc
219*1fd5a2e1SPrashanth Swaminathan    .size ffi_closure_asm, .-ffi_closure_asm
220*1fd5a2e1SPrashanth Swaminathan
221*1fd5a2e1SPrashanth Swaminathan/*
222*1fd5a2e1SPrashanth Swaminathan  ffi_go_closure_asm.  Expects address of the passed-in ffi_go_closure in t2.
223*1fd5a2e1SPrashanth Swaminathan  void ffi_closure_inner (ffi_cif *cif,
224*1fd5a2e1SPrashanth Swaminathan		          void (*fun) (ffi_cif *, void *, void **, void *),
225*1fd5a2e1SPrashanth Swaminathan		          void *user_data,
226*1fd5a2e1SPrashanth Swaminathan		          size_t *stackargs, struct call_context *regargs)
227*1fd5a2e1SPrashanth Swaminathan*/
228*1fd5a2e1SPrashanth Swaminathan
229*1fd5a2e1SPrashanth Swaminathan    .globl ffi_go_closure_asm
230*1fd5a2e1SPrashanth Swaminathan    .hidden ffi_go_closure_asm
231*1fd5a2e1SPrashanth Swaminathan    .type ffi_go_closure_asm, @function
232*1fd5a2e1SPrashanth Swaminathanffi_go_closure_asm:
233*1fd5a2e1SPrashanth Swaminathan    .cfi_startproc
234*1fd5a2e1SPrashanth Swaminathan
235*1fd5a2e1SPrashanth Swaminathan    addi    sp,  sp, -FRAME_LEN
236*1fd5a2e1SPrashanth Swaminathan    .cfi_def_cfa_offset FRAME_LEN
237*1fd5a2e1SPrashanth Swaminathan
238*1fd5a2e1SPrashanth Swaminathan    /* make a frame */
239*1fd5a2e1SPrashanth Swaminathan    SARG    fp, FRAME_LEN - 2*PTRS(sp)
240*1fd5a2e1SPrashanth Swaminathan    .cfi_offset 8, -2*PTRS
241*1fd5a2e1SPrashanth Swaminathan    SARG    ra, FRAME_LEN - 1*PTRS(sp)
242*1fd5a2e1SPrashanth Swaminathan    .cfi_offset 1, -1*PTRS
243*1fd5a2e1SPrashanth Swaminathan    addi    fp, sp, FRAME_LEN
244*1fd5a2e1SPrashanth Swaminathan
245*1fd5a2e1SPrashanth Swaminathan    /* save arguments */
246*1fd5a2e1SPrashanth Swaminathan#if FLTS
247*1fd5a2e1SPrashanth Swaminathan    FSARG   fa0, 0*FLTS(sp)
248*1fd5a2e1SPrashanth Swaminathan    FSARG   fa1, 1*FLTS(sp)
249*1fd5a2e1SPrashanth Swaminathan    FSARG   fa2, 2*FLTS(sp)
250*1fd5a2e1SPrashanth Swaminathan    FSARG   fa3, 3*FLTS(sp)
251*1fd5a2e1SPrashanth Swaminathan    FSARG   fa4, 4*FLTS(sp)
252*1fd5a2e1SPrashanth Swaminathan    FSARG   fa5, 5*FLTS(sp)
253*1fd5a2e1SPrashanth Swaminathan    FSARG   fa6, 6*FLTS(sp)
254*1fd5a2e1SPrashanth Swaminathan    FSARG   fa7, 7*FLTS(sp)
255*1fd5a2e1SPrashanth Swaminathan#endif
256*1fd5a2e1SPrashanth Swaminathan
257*1fd5a2e1SPrashanth Swaminathan    SARG    a0, 8*FLTS+0*PTRS(sp)
258*1fd5a2e1SPrashanth Swaminathan    SARG    a1, 8*FLTS+1*PTRS(sp)
259*1fd5a2e1SPrashanth Swaminathan    SARG    a2, 8*FLTS+2*PTRS(sp)
260*1fd5a2e1SPrashanth Swaminathan    SARG    a3, 8*FLTS+3*PTRS(sp)
261*1fd5a2e1SPrashanth Swaminathan    SARG    a4, 8*FLTS+4*PTRS(sp)
262*1fd5a2e1SPrashanth Swaminathan    SARG    a5, 8*FLTS+5*PTRS(sp)
263*1fd5a2e1SPrashanth Swaminathan    SARG    a6, 8*FLTS+6*PTRS(sp)
264*1fd5a2e1SPrashanth Swaminathan    SARG    a7, 8*FLTS+7*PTRS(sp)
265*1fd5a2e1SPrashanth Swaminathan
266*1fd5a2e1SPrashanth Swaminathan    /* enter C */
267*1fd5a2e1SPrashanth Swaminathan    LARG    a0, 1*PTRS(t2)
268*1fd5a2e1SPrashanth Swaminathan    LARG    a1, 2*PTRS(t2)
269*1fd5a2e1SPrashanth Swaminathan    mv      a2, t2
270*1fd5a2e1SPrashanth Swaminathan    addi    a3, sp, FRAME_LEN
271*1fd5a2e1SPrashanth Swaminathan    mv      a4, sp
272*1fd5a2e1SPrashanth Swaminathan
273*1fd5a2e1SPrashanth Swaminathan    call    ffi_closure_inner
274*1fd5a2e1SPrashanth Swaminathan
275*1fd5a2e1SPrashanth Swaminathan    /* return values */
276*1fd5a2e1SPrashanth Swaminathan#if FLTS
277*1fd5a2e1SPrashanth Swaminathan    FLARG   fa0, 0*FLTS(sp)
278*1fd5a2e1SPrashanth Swaminathan    FLARG   fa1, 1*FLTS(sp)
279*1fd5a2e1SPrashanth Swaminathan#endif
280*1fd5a2e1SPrashanth Swaminathan
281*1fd5a2e1SPrashanth Swaminathan    LARG    a0, 8*FLTS+0*PTRS(sp)
282*1fd5a2e1SPrashanth Swaminathan    LARG    a1, 8*FLTS+1*PTRS(sp)
283*1fd5a2e1SPrashanth Swaminathan
284*1fd5a2e1SPrashanth Swaminathan    /* restore and return */
285*1fd5a2e1SPrashanth Swaminathan    LARG    ra, FRAME_LEN-1*PTRS(sp)
286*1fd5a2e1SPrashanth Swaminathan    .cfi_restore 1
287*1fd5a2e1SPrashanth Swaminathan    LARG    fp, FRAME_LEN-2*PTRS(sp)
288*1fd5a2e1SPrashanth Swaminathan    .cfi_restore 8
289*1fd5a2e1SPrashanth Swaminathan    addi    sp, sp, FRAME_LEN
290*1fd5a2e1SPrashanth Swaminathan    .cfi_def_cfa_offset 0
291*1fd5a2e1SPrashanth Swaminathan    ret
292*1fd5a2e1SPrashanth Swaminathan    .cfi_endproc
293*1fd5a2e1SPrashanth Swaminathan    .size ffi_go_closure_asm, .-ffi_go_closure_asm
294