RISC-V go closures

This implements go closures for RISC-V.  It has been tested on
riscv64-suse-linux and against the libgo testsuite.
This commit is contained in:
Andreas Schwab
2018-08-09 15:41:17 +02:00
parent 65da63abc8
commit 4cb776bc80
3 changed files with 129 additions and 13 deletions
+86 -7
View File
@@ -67,8 +67,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 ffi_call_asm (size_t *stackargs, struct call_context *regargs,
void (*fn) (void), void *closure);
*/
#define FRAME_LEN (8 * FLTS + 8 * PTRS + 16)
@@ -98,6 +98,7 @@ ffi_call_asm:
# Load arguments
mv t1, a2
mv t2, a3
#if FLTS
FLARG fa0, -FRAME_LEN+0*FLTS(fp)
@@ -145,8 +146,10 @@ ffi_call_asm:
/*
ffi_closure_asm. Expects address of the passed-in ffi_closure in t1.
void ffi_closure_inner(size_t *stackargs, struct call_context *regargs,
ffi_closure *closure);
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
@@ -187,9 +190,11 @@ ffi_closure_asm:
SARG a7, 8*FLTS+7*PTRS(sp)
/* enter C */
addi a0, sp, FRAME_LEN
mv a1, sp
mv a2, t1
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
@@ -212,3 +217,77 @@ ffi_closure_asm:
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