diff options
Diffstat (limited to 'js/src/ctypes/libffi/src/riscv/sysv.S')
-rw-r--r-- | js/src/ctypes/libffi/src/riscv/sysv.S | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/js/src/ctypes/libffi/src/riscv/sysv.S b/js/src/ctypes/libffi/src/riscv/sysv.S new file mode 100644 index 0000000000..522d0b0055 --- /dev/null +++ b/js/src/ctypes/libffi/src/riscv/sysv.S @@ -0,0 +1,293 @@ +/* ----------------------------------------------------------------------- + ffi.c - Copyright (c) 2015 Michael Knyszek <mknyszek@berkeley.edu> + 2015 Andrew Waterman <waterman@cs.berkeley.edu> + 2018 Stef O'Rear <sorear2@gmail.com> + + RISC-V Foreign Function Interface + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + ``Software''), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + ----------------------------------------------------------------------- */ + +#define LIBFFI_ASM +#include <fficonfig.h> +#include <ffi.h> + +/* Define aliases so that we can handle all ABIs uniformly */ + +#if __SIZEOF_POINTER__ == 8 +#define PTRS 8 +#define LARG ld +#define SARG sd +#else +#define PTRS 4 +#define LARG lw +#define SARG sw +#endif + +#if __riscv_float_abi_double +#define FLTS 8 +#define FLARG fld +#define FSARG fsd +#elif __riscv_float_abi_single +#define FLTS 4 +#define FLARG flw +#define FSARG fsw +#else +#define FLTS 0 +#endif + +#define fp s0 + + .text + .globl ffi_call_asm + .type ffi_call_asm, @function + .hidden ffi_call_asm +/* + struct call_context { + floatreg fa[8]; + intreg a[8]; + intreg pad[rv32 ? 2 : 0]; + intreg save_fp, save_ra; + } + void ffi_call_asm (size_t *stackargs, struct call_context *regargs, + void (*fn) (void), void *closure); +*/ + +#define FRAME_LEN (8 * FLTS + 8 * PTRS + 16) + +ffi_call_asm: + .cfi_startproc + + /* + We are NOT going to set up an ordinary stack frame. In order to pass + the stacked args to the called function, we adjust our stack pointer to + a0, which is in the _caller's_ alloca area. We establish our own stack + frame at the end of the call_context. + + Anything below the arguments will be freed at this point, although we + preserve the call_context so that it can be read back in the caller. + */ + + .cfi_def_cfa 11, FRAME_LEN # interim CFA based on a1 + SARG fp, FRAME_LEN - 2*PTRS(a1) + .cfi_offset 8, -2*PTRS + SARG ra, FRAME_LEN - 1*PTRS(a1) + .cfi_offset 1, -1*PTRS + + addi fp, a1, FRAME_LEN + mv sp, a0 + .cfi_def_cfa 8, 0 # our frame is fully set up + + # Load arguments + mv t1, a2 + mv t2, a3 + +#if FLTS + FLARG fa0, -FRAME_LEN+0*FLTS(fp) + FLARG fa1, -FRAME_LEN+1*FLTS(fp) + FLARG fa2, -FRAME_LEN+2*FLTS(fp) + FLARG fa3, -FRAME_LEN+3*FLTS(fp) + FLARG fa4, -FRAME_LEN+4*FLTS(fp) + FLARG fa5, -FRAME_LEN+5*FLTS(fp) + FLARG fa6, -FRAME_LEN+6*FLTS(fp) + FLARG fa7, -FRAME_LEN+7*FLTS(fp) +#endif + + LARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp) + LARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp) + LARG a2, -FRAME_LEN+8*FLTS+2*PTRS(fp) + LARG a3, -FRAME_LEN+8*FLTS+3*PTRS(fp) + LARG a4, -FRAME_LEN+8*FLTS+4*PTRS(fp) + LARG a5, -FRAME_LEN+8*FLTS+5*PTRS(fp) + LARG a6, -FRAME_LEN+8*FLTS+6*PTRS(fp) + LARG a7, -FRAME_LEN+8*FLTS+7*PTRS(fp) + + /* Call */ + jalr t1 + + /* Save return values - only a0/a1 (fa0/fa1) are used */ +#if FLTS + FSARG fa0, -FRAME_LEN+0*FLTS(fp) + FSARG fa1, -FRAME_LEN+1*FLTS(fp) +#endif + + SARG a0, -FRAME_LEN+8*FLTS+0*PTRS(fp) + SARG a1, -FRAME_LEN+8*FLTS+1*PTRS(fp) + + /* Restore and return */ + addi sp, fp, -FRAME_LEN + .cfi_def_cfa 2, FRAME_LEN + LARG ra, -1*PTRS(fp) + .cfi_restore 1 + LARG fp, -2*PTRS(fp) + .cfi_restore 8 + ret + .cfi_endproc + .size ffi_call_asm, .-ffi_call_asm + + +/* + ffi_closure_asm. Expects address of the passed-in ffi_closure in t1. + void ffi_closure_inner (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + size_t *stackargs, struct call_context *regargs) +*/ + + .globl ffi_closure_asm + .hidden ffi_closure_asm + .type ffi_closure_asm, @function +ffi_closure_asm: + .cfi_startproc + + addi sp, sp, -FRAME_LEN + .cfi_def_cfa_offset FRAME_LEN + + /* make a frame */ + SARG fp, FRAME_LEN - 2*PTRS(sp) + .cfi_offset 8, -2*PTRS + SARG ra, FRAME_LEN - 1*PTRS(sp) + .cfi_offset 1, -1*PTRS + addi fp, sp, FRAME_LEN + + /* save arguments */ +#if FLTS + FSARG fa0, 0*FLTS(sp) + FSARG fa1, 1*FLTS(sp) + FSARG fa2, 2*FLTS(sp) + FSARG fa3, 3*FLTS(sp) + FSARG fa4, 4*FLTS(sp) + FSARG fa5, 5*FLTS(sp) + FSARG fa6, 6*FLTS(sp) + FSARG fa7, 7*FLTS(sp) +#endif + + SARG a0, 8*FLTS+0*PTRS(sp) + SARG a1, 8*FLTS+1*PTRS(sp) + SARG a2, 8*FLTS+2*PTRS(sp) + SARG a3, 8*FLTS+3*PTRS(sp) + SARG a4, 8*FLTS+4*PTRS(sp) + SARG a5, 8*FLTS+5*PTRS(sp) + SARG a6, 8*FLTS+6*PTRS(sp) + SARG a7, 8*FLTS+7*PTRS(sp) + + /* enter C */ + LARG a0, FFI_TRAMPOLINE_SIZE+0*PTRS(t1) + LARG a1, FFI_TRAMPOLINE_SIZE+1*PTRS(t1) + LARG a2, FFI_TRAMPOLINE_SIZE+2*PTRS(t1) + addi a3, sp, FRAME_LEN + mv a4, sp + + call ffi_closure_inner + + /* return values */ +#if FLTS + FLARG fa0, 0*FLTS(sp) + FLARG fa1, 1*FLTS(sp) +#endif + + LARG a0, 8*FLTS+0*PTRS(sp) + LARG a1, 8*FLTS+1*PTRS(sp) + + /* restore and return */ + LARG ra, FRAME_LEN-1*PTRS(sp) + .cfi_restore 1 + LARG fp, FRAME_LEN-2*PTRS(sp) + .cfi_restore 8 + addi sp, sp, FRAME_LEN + .cfi_def_cfa_offset 0 + ret + .cfi_endproc + .size ffi_closure_asm, .-ffi_closure_asm + +/* + ffi_go_closure_asm. Expects address of the passed-in ffi_go_closure in t2. + void ffi_closure_inner (ffi_cif *cif, + void (*fun) (ffi_cif *, void *, void **, void *), + void *user_data, + size_t *stackargs, struct call_context *regargs) +*/ + + .globl ffi_go_closure_asm + .hidden ffi_go_closure_asm + .type ffi_go_closure_asm, @function +ffi_go_closure_asm: + .cfi_startproc + + addi sp, sp, -FRAME_LEN + .cfi_def_cfa_offset FRAME_LEN + + /* make a frame */ + SARG fp, FRAME_LEN - 2*PTRS(sp) + .cfi_offset 8, -2*PTRS + SARG ra, FRAME_LEN - 1*PTRS(sp) + .cfi_offset 1, -1*PTRS + addi fp, sp, FRAME_LEN + + /* save arguments */ +#if FLTS + FSARG fa0, 0*FLTS(sp) + FSARG fa1, 1*FLTS(sp) + FSARG fa2, 2*FLTS(sp) + FSARG fa3, 3*FLTS(sp) + FSARG fa4, 4*FLTS(sp) + FSARG fa5, 5*FLTS(sp) + FSARG fa6, 6*FLTS(sp) + FSARG fa7, 7*FLTS(sp) +#endif + + SARG a0, 8*FLTS+0*PTRS(sp) + SARG a1, 8*FLTS+1*PTRS(sp) + SARG a2, 8*FLTS+2*PTRS(sp) + SARG a3, 8*FLTS+3*PTRS(sp) + SARG a4, 8*FLTS+4*PTRS(sp) + SARG a5, 8*FLTS+5*PTRS(sp) + SARG a6, 8*FLTS+6*PTRS(sp) + SARG a7, 8*FLTS+7*PTRS(sp) + + /* enter C */ + LARG a0, 1*PTRS(t2) + LARG a1, 2*PTRS(t2) + mv a2, t2 + addi a3, sp, FRAME_LEN + mv a4, sp + + call ffi_closure_inner + + /* return values */ +#if FLTS + FLARG fa0, 0*FLTS(sp) + FLARG fa1, 1*FLTS(sp) +#endif + + LARG a0, 8*FLTS+0*PTRS(sp) + LARG a1, 8*FLTS+1*PTRS(sp) + + /* restore and return */ + LARG ra, FRAME_LEN-1*PTRS(sp) + .cfi_restore 1 + LARG fp, FRAME_LEN-2*PTRS(sp) + .cfi_restore 8 + addi sp, sp, FRAME_LEN + .cfi_def_cfa_offset 0 + ret + .cfi_endproc + .size ffi_go_closure_asm, .-ffi_go_closure_asm |