1 /* -----------------------------------------------------------------------
2 ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu>
3 2015 Andrew Waterman <waterman@cs.berkeley.edu>
4 2018 Stef O'Rear <sorear2@gmail.com>
6 RISC-V Foreign Function Interface
8 Permission is hereby granted, free of charge, to any person obtaining
9 a copy of this software and associated documentation files (the
10 ``Software''), to deal in the Software without restriction, including
11 without limitation the rights to use, copy, modify, merge, publish,
12 distribute, sublicense, and/or sell copies of the Software, and to
13 permit persons to whom the Software is furnished to do so, subject to
14 the following conditions:
16 The above copyright notice and this permission notice shall be included
17 in all copies or substantial portions of the Software.
19 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
20 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 DEALINGS IN THE SOFTWARE.
27 ----------------------------------------------------------------------- */
30 #include <fficonfig.h>
33 /* Define aliases so that we can handle all ABIs uniformly */
35 #if __SIZEOF_POINTER__ == 8
45 #if __riscv_float_abi_double
49 #elif __riscv_float_abi_single
61 .type ffi_call_asm, @function
67 intreg pad[rv32 ? 2 : 0];
68 intreg save_fp, save_ra;
70 void ffi_call_asm(size_t *stackargs, struct call_context *regargs,
74 #define FRAME_LEN (8 * FLTS + 8 * PTRS + 16)
80 We are NOT going to set up an ordinary stack frame. In order to pass
81 the stacked args to the called function, we adjust our stack pointer to
82 a0, which is in the _caller's_ alloca area. We establish our own stack
83 frame at the end of the call_context.
85 Anything below the arguments will be freed at this point, although we
86 preserve the call_context so that it can be read back in the caller.
89 .cfi_def_cfa 11, FRAME_LEN # interim CFA based on a1
90 SARG fp, FRAME_LEN - 2*PTRS(a1)
91 .cfi_offset 8, -2*PTRS
92 SARG ra, FRAME_LEN - 1*PTRS(a1)
93 .cfi_offset 1, -1*PTRS
95 addi fp, a1, FRAME_LEN
97 .cfi_def_cfa 8, 0 # our frame is fully set up
103 FLARG fa0, -FRAME_LEN+0*FLTS(fp)
104 FLARG fa1, -FRAME_LEN+1*FLTS(fp)
105 FLARG fa2, -FRAME_LEN+2*FLTS(fp)
106 FLARG fa3, -FRAME_LEN+3*FLTS(fp)
107 FLARG fa4, -FRAME_LEN+4*FLTS(fp)
108 FLARG fa5, -FRAME_LEN+5*FLTS(fp)
109 FLARG fa6, -FRAME_LEN+6*FLTS(fp)
110 FLARG fa7, -FRAME_LEN+7*FLTS(fp)
113 LARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
114 LARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
115 LARG a2, -FRAME_LEN+8*FLTS+2*PTRS(fp)
116 LARG a3, -FRAME_LEN+8*FLTS+3*PTRS(fp)
117 LARG a4, -FRAME_LEN+8*FLTS+4*PTRS(fp)
118 LARG a5, -FRAME_LEN+8*FLTS+5*PTRS(fp)
119 LARG a6, -FRAME_LEN+8*FLTS+6*PTRS(fp)
120 LARG a7, -FRAME_LEN+8*FLTS+7*PTRS(fp)
125 /* Save return values - only a0/a1 (fa0/fa1) are used */
127 FSARG fa0, -FRAME_LEN+0*FLTS(fp)
128 FSARG fa1, -FRAME_LEN+1*FLTS(fp)
131 SARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp)
132 SARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp)
134 /* Restore and return */
135 addi sp, fp, -FRAME_LEN
136 .cfi_def_cfa 2, FRAME_LEN
143 .size ffi_call_asm, .-ffi_call_asm
147 ffi_closure_asm. Expects address of the passed-in ffi_closure in t1.
148 void ffi_closure_inner(size_t *stackargs, struct call_context *regargs,
149 ffi_closure *closure);
152 .globl ffi_closure_asm
153 .hidden ffi_closure_asm
154 .type ffi_closure_asm, @function
158 addi sp, sp, -FRAME_LEN
159 .cfi_def_cfa_offset FRAME_LEN
162 SARG fp, FRAME_LEN - 2*PTRS(sp)
163 .cfi_offset 8, -2*PTRS
164 SARG ra, FRAME_LEN - 1*PTRS(sp)
165 .cfi_offset 1, -1*PTRS
166 addi fp, sp, FRAME_LEN
170 FSARG fa0, 0*FLTS(sp)
171 FSARG fa1, 1*FLTS(sp)
172 FSARG fa2, 2*FLTS(sp)
173 FSARG fa3, 3*FLTS(sp)
174 FSARG fa4, 4*FLTS(sp)
175 FSARG fa5, 5*FLTS(sp)
176 FSARG fa6, 6*FLTS(sp)
177 FSARG fa7, 7*FLTS(sp)
180 SARG a0, 8*FLTS+0*PTRS(sp)
181 SARG a1, 8*FLTS+1*PTRS(sp)
182 SARG a2, 8*FLTS+2*PTRS(sp)
183 SARG a3, 8*FLTS+3*PTRS(sp)
184 SARG a4, 8*FLTS+4*PTRS(sp)
185 SARG a5, 8*FLTS+5*PTRS(sp)
186 SARG a6, 8*FLTS+6*PTRS(sp)
187 SARG a7, 8*FLTS+7*PTRS(sp)
190 addi a0, sp, FRAME_LEN
194 call ffi_closure_inner
198 FLARG fa0, 0*FLTS(sp)
199 FLARG fa1, 1*FLTS(sp)
202 LARG a0, 8*FLTS+0*PTRS(sp)
203 LARG a1, 8*FLTS+1*PTRS(sp)
205 /* restore and return */
206 LARG ra, FRAME_LEN-1*PTRS(sp)
208 LARG fp, FRAME_LEN-2*PTRS(sp)
210 addi sp, sp, FRAME_LEN
211 .cfi_def_cfa_offset 0
214 .size ffi_closure_asm, .-ffi_closure_asm