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