From 3cc61c337bf79c4aac094c7bba3626c10881dfd7 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 23 Oct 2022 14:00:42 +0100 Subject: [PATCH] Move all JIT exits to jit-exits.c --- src/jit/jit-core.c | 6 +- src/jit/jit-exits.c | 308 ++++++++++++++++++++++++++++++++- src/jit/jit-interp.c | 404 +------------------------------------------ src/jit/jit-irgen.c | 4 - 4 files changed, 312 insertions(+), 410 deletions(-) diff --git a/src/jit/jit-core.c b/src/jit/jit-core.c index 0b61f0c5..1e5e37e3 100644 --- a/src/jit/jit-core.c +++ b/src/jit/jit-core.c @@ -622,7 +622,9 @@ bool jit_try_call_packed(jit_t *j, jit_handle_t handle, jit_scalar_t context, ffi_type_t atype = (f->spec >> 8) & 0xf; ffi_type_t rtype = f->spec & 0xf; - jit_scalar_t args[2] = { context }; + jit_scalar_t args[JIT_MAX_ARGS]; + args[0] = context; + if (ffi_is_integral(atype)) args[1].integer = ffi_widen_int(atype, input, insz); else if (atype == FFI_FLOAT) { @@ -647,7 +649,7 @@ bool jit_try_call_packed(jit_t *j, jit_handle_t handle, jit_scalar_t context, else if (rtype == FFI_POINTER) memcpy(output, result.pointer, outsz); else - fatal_trace("unhandled FFI result type %x", atype); + fatal_trace("unhandled FFI result type %x", rtype); return true; } diff --git a/src/jit/jit-exits.c b/src/jit/jit-exits.c index 6266b8e9..706c8eb8 100644 --- a/src/jit/jit-exits.c +++ b/src/jit/jit-exits.c @@ -543,6 +543,68 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args) } break; + case JIT_EXIT_REPORT: + { + uint8_t *msg = args[0].pointer; + int32_t len = args[1].integer; + int32_t severity = args[2].integer; + tree_t where = args[3].pointer; + + x_report(msg, len, severity, where); + } + break; + + case JIT_EXIT_INIT_SIGNAL: + { + int32_t count = args[0].integer; + int32_t size = args[1].integer; + jit_scalar_t value = { .integer = args[2].integer }; + int32_t flags = args[3].integer; + tree_t where = args[4].pointer; + int32_t offset = args[5].integer; + bool scalar = args[6].integer; + + sig_shared_t *ss; + if (!jit_has_runtime(thread->jit)) + ss = NULL; // Called during constant folding + else { + const uint8_t *ptr = scalar ? &value.integer : value.pointer; + ss = x_init_signal(count, size, ptr, flags, where, offset); + } + + args[0].pointer = ss; + } + break; + + case JIT_EXIT_RESOLVE_SIGNAL: + { + if (!jit_has_runtime(thread->jit)) + return; // Called during constant folding + + sig_shared_t *shared = args[0].pointer; + jit_handle_t handle = args[1].integer; + void *context = args[2].pointer; + int32_t ileft = args[3].integer; + int32_t nlits = args[4].integer; + int32_t flags = args[5].integer; + + x_resolve_signal2(shared, handle, context, ileft, nlits, flags); + } + break; + + case JIT_EXIT_DRIVE_SIGNAL: + { + if (!jit_has_runtime(thread->jit)) + return; // Called during constant folding + + sig_shared_t *ss = args[0].pointer; + int32_t offset = args[1].integer; + int32_t count = args[2].integer; + + x_drive_signal(ss, offset, count); + } + break; + case JIT_EXIT_MAP_SIGNAL: { sig_shared_t *src_ss = args[0].pointer; @@ -565,6 +627,60 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args) } break; + case JIT_EXIT_MAP_CONST: + { + sig_shared_t *dst_ss = args[0].pointer; + uint32_t dst_offset = args[1].integer; + jit_scalar_t initval = { .integer = args[2].integer }; + uint32_t dst_count = args[3].integer; + bool scalar = args[4].integer; + + const void *vptr = scalar ? &initval.integer : initval.pointer; + + x_map_const(dst_ss, dst_offset, vptr, dst_count); + } + break; + + case JIT_EXIT_SCHED_PROCESS: + { + if (!jit_has_runtime(thread->jit)) + return; // TODO: this should not be necessary + + int64_t after = args[0].integer; + x_sched_process(after); + } + break; + + case JIT_EXIT_SCHED_WAVEFORM: + { + sig_shared_t *shared = args[0].pointer; + int32_t offset = args[1].integer; + int32_t count = args[2].integer; + jit_scalar_t value = { .integer = args[3].integer }; + int64_t after = args[4].integer; + int64_t reject = args[5].integer; + bool scalar = args[6].integer; + + if (scalar) + x_sched_waveform_s(shared, offset, value.integer, after, reject); + else + x_sched_waveform(shared, offset, value.pointer, count, + after, reject); + } + break; + + case JIT_EXIT_SCHED_EVENT: + { + sig_shared_t *shared = args[0].pointer; + int32_t offset = args[1].integer; + int32_t count = args[2].integer; + int8_t recur = args[3].integer; + sig_shared_t *wake = args[4].pointer; + + x_sched_event(shared, offset, count, recur, wake); + } + break; + case JIT_EXIT_INT_TO_STRING: { int64_t value = args[0].integer; @@ -581,6 +697,31 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args) } break; + case JIT_EXIT_ALIAS_SIGNAL: + { + sig_shared_t *ss = args[0].pointer; + tree_t where = args[1].pointer; + + x_alias_signal(ss, where); + } + break; + + case JIT_EXIT_REAL_TO_STRING: + { + double value = args[0].real; + + mspace_t *m = jit_get_mspace(jit_thread_local()->jit); + char *buf = mspace_alloc(m, 32); + if (buf == NULL) + return; + + ffi_uarray_t u = x_real_to_string(value, buf, 32); + args[0].pointer = u.ptr; + args[1].integer = u.dims[0].left; + args[2].integer = u.dims[0].length; + } + break; + case JIT_EXIT_DISCONNECT: { sig_shared_t *shared = args[0].pointer; @@ -600,6 +741,49 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args) } break; + case JIT_EXIT_UNREACHABLE: + { + tree_t where = args[0].pointer; + x_unreachable(where); + } + break; + + case JIT_EXIT_OVERFLOW: + { + int32_t lhs = args[0].integer; + int32_t rhs = args[1].integer; + tree_t where = args[2].pointer; + + x_overflow(lhs, rhs, where); + } + break; + + case JIT_EXIT_INDEX_FAIL: + { + int32_t value = args[0].integer; + int32_t left = args[1].integer; + int32_t right = args[2].integer; + range_kind_t dir = args[3].integer; + tree_t where = args[4].pointer; + tree_t hint = args[5].pointer; + + x_index_fail(value, left, right, dir, where, hint); + } + break; + + case JIT_EXIT_RANGE_FAIL: + { + int64_t value = args[0].integer; + int64_t left = args[1].integer; + int64_t right = args[2].integer; + range_kind_t dir = args[3].integer; + tree_t where = args[4].pointer; + tree_t hint = args[5].pointer; + + x_range_fail(value, left, right, dir, where, hint); + } + break; + case JIT_EXIT_FORCE: { sig_shared_t *shared = args[0].pointer; @@ -690,11 +874,133 @@ void __nvc_do_exit(jit_exit_t which, jit_anchor_t *anchor, jit_scalar_t *args) case JIT_EXIT_DIV_ZERO: { tree_t where = args[0].pointer; - x_div_zero(where); } break; + case JIT_EXIT_LENGTH_FAIL: + { + int32_t left = args[0].integer; + int32_t right = args[1].integer; + int32_t dim = args[2].integer; + tree_t where = args[3].pointer; + + x_length_fail(left, right, dim, where); + } + break; + + case JIT_EXIT_NULL_DEREF: + { + tree_t where = args[0].pointer; + x_null_deref(where); + } + break; + + case JIT_EXIT_EXPONENT_FAIL: + { + int32_t value = args[0].integer; + tree_t where = args[1].pointer; + + x_exponent_fail(value, where); + } + break; + + case JIT_EXIT_FILE_OPEN: + { + int8_t *status = args[0].pointer; + void **_fp = args[1].pointer; + uint8_t *name_bytes = args[2].pointer; + int32_t name_len = args[3].integer; + int32_t mode = args[4].integer; + tree_t where = args[5].pointer; + + x_file_open(status, _fp, name_bytes, name_len, mode, where); + } + break; + + case JIT_EXIT_FILE_CLOSE: + { + void **_fp = args[0].pointer; + x_file_close(_fp); + } + break; + + case JIT_EXIT_FILE_READ: + { + void **_fp = args[0].pointer; + uint8_t *data = args[1].pointer; + int32_t size = args[2].integer; + int32_t count = args[3].integer; + int32_t *out = args[4].pointer; + + x_file_read(_fp, data, size, count, out); + } + break; + + case JIT_EXIT_FILE_WRITE: + { + void **_fp = args[0].pointer; + uint8_t *data = args[1].pointer; + int32_t len = args[2].integer; + + x_file_write(_fp, data, len); + } + break; + + case JIT_EXIT_ENDFILE: + { + void *_fp = args[0].pointer; + args[0].integer = x_endfile(_fp); + } + break; + + case JIT_EXIT_DEBUG_OUT: + { + int64_t value = args[0].integer; + debugf("DEBUG %"PRIi64, value); + } + break; + + case JIT_EXIT_LAST_EVENT: + { + sig_shared_t *shared = args[0].pointer; + uint32_t offset = args[1].integer; + uint32_t count = args[2].integer; + + args[0].integer = x_last_event(shared, offset, count); + } + break; + + case JIT_EXIT_LAST_ACTIVE: + { + sig_shared_t *shared = args[0].pointer; + uint32_t offset = args[1].integer; + uint32_t count = args[2].integer; + + args[0].integer = x_last_active(shared, offset, count); + } + break; + + case JIT_EXIT_TEST_EVENT: + { + sig_shared_t *shared = args[0].pointer; + int32_t offset = args[1].integer; + int32_t count = args[2].integer; + + args[0].integer = x_test_net_event(shared, offset, count); + } + break; + + case JIT_EXIT_TEST_ACTIVE: + { + sig_shared_t *shared = args[0].pointer; + int32_t offset = args[1].integer; + int32_t count = args[2].integer; + + args[0].integer = x_test_net_active(shared, offset, count); + } + break; + default: fatal_trace("unhandled exit %s", jit_exit_name(which)); } diff --git a/src/jit/jit-interp.c b/src/jit/jit-interp.c index a4091b1a..ee4edf80 100644 --- a/src/jit/jit-interp.c +++ b/src/jit/jit-interp.c @@ -699,412 +699,10 @@ static void interp_galloc(jit_interp_t *state, jit_ir_t *ir) thread->anchor = NULL; } -static void interp_range_fail(jit_interp_t *state) -{ - int64_t value = state->args[0].integer; - int64_t left = state->args[1].integer; - int64_t right = state->args[2].integer; - range_kind_t dir = state->args[3].integer; - tree_t where = state->args[4].pointer; - tree_t hint = state->args[5].pointer; - - x_range_fail(value, left, right, dir, where, hint); -} - -static void interp_index_fail(jit_interp_t *state) -{ - int32_t value = state->args[0].integer; - int32_t left = state->args[1].integer; - int32_t right = state->args[2].integer; - range_kind_t dir = state->args[3].integer; - tree_t where = state->args[4].pointer; - tree_t hint = state->args[5].pointer; - - x_index_fail(value, left, right, dir, where, hint); -} - -static void interp_overflow(jit_interp_t *state) -{ - int32_t lhs = state->args[0].integer; - int32_t rhs = state->args[1].integer; - tree_t where = state->args[2].pointer; - - x_overflow(lhs, rhs, where); -} - -static void interp_null_deref(jit_interp_t *state) -{ - tree_t where = state->args[0].pointer; - - x_null_deref(where); -} - -static void interp_length_fail(jit_interp_t *state) -{ - int32_t left = state->args[0].integer; - int32_t right = state->args[1].integer; - int32_t dim = state->args[2].integer; - tree_t where = state->args[3].pointer; - - x_length_fail(left, right, dim, where); -} - -static void interp_exponent_fail(jit_interp_t *state) -{ - int32_t value = state->args[0].integer; - tree_t where = state->args[1].pointer; - - x_exponent_fail(value, where); -} - -static void interp_unreachable(jit_interp_t *state) -{ - tree_t where = state->args[0].pointer; - - x_unreachable(where); -} - -static void interp_report(jit_interp_t *state) -{ - uint8_t *msg = state->args[0].pointer; - int32_t len = state->args[1].integer; - int32_t severity = state->args[2].integer; - tree_t where = state->args[3].pointer; - - x_report(msg, len, severity, where); -} - -static void interp_scalar_init_signal(jit_interp_t *state) -{ - int32_t count = state->args[0].integer; - int32_t size = state->args[1].integer; - jit_scalar_t value = { .integer = state->args[2].integer }; - int32_t flags = state->args[3].integer; - tree_t where = state->args[4].pointer; - int32_t offset = state->args[5].integer; - bool scalar = state->args[6].integer; - - sig_shared_t *ss; - if (!jit_has_runtime(state->func->jit)) - ss = NULL; // Called during constant folding - else { - const uint8_t *ptr = scalar ? &value.integer : value.pointer; - ss = x_init_signal(count, size, ptr, flags, where, offset); - } - - state->args[0].pointer = ss; - state->nargs = 1; -} - -static void interp_drive_signal(jit_interp_t *state) -{ - if (!jit_has_runtime(state->func->jit)) - return; // Called during constant folding - - sig_shared_t *ss = state->args[0].pointer; - int32_t offset = state->args[1].integer; - int32_t count = state->args[2].integer; - - x_drive_signal(ss, offset, count); -} - -static void interp_sched_process(jit_interp_t *state) -{ - if (!jit_has_runtime(state->func->jit)) - return; // TODO: this should not be necessary - - int64_t after = state->args[0].integer; - - x_sched_process(after); -} - -static void interp_sched_waveform(jit_interp_t *state) -{ - sig_shared_t *shared = state->args[0].pointer; - int32_t offset = state->args[1].integer; - int32_t count = state->args[2].integer; - jit_scalar_t value = { .integer = state->args[3].integer }; - int64_t after = state->args[4].integer; - int64_t reject = state->args[5].integer; - bool scalar = state->args[6].integer; - - if (scalar) - x_sched_waveform_s(shared, offset, value.integer, after, reject); - else - x_sched_waveform(shared, offset, value.pointer, count, after, reject); -} - -static void interp_sched_event(jit_interp_t *state) -{ - sig_shared_t *shared = state->args[0].pointer; - int32_t offset = state->args[1].integer; - int32_t count = state->args[2].integer; - int8_t recur = state->args[3].integer; - sig_shared_t *wake = state->args[4].pointer; - - x_sched_event(shared, offset, count, recur, wake); -} - -static void interp_test_event(jit_interp_t *state) -{ - sig_shared_t *shared = state->args[0].pointer; - int32_t offset = state->args[1].integer; - int32_t count = state->args[2].integer; - - state->args[0].integer = x_test_net_event(shared, offset, count); - state->nargs = 1; -} - -static void interp_test_active(jit_interp_t *state) -{ - sig_shared_t *shared = state->args[0].pointer; - int32_t offset = state->args[1].integer; - int32_t count = state->args[2].integer; - - state->args[0].integer = x_test_net_active(shared, offset, count); - state->nargs = 1; -} - -static void interp_file_open(jit_interp_t *state) -{ - int8_t *status = state->args[0].pointer; - void **_fp = state->args[1].pointer; - uint8_t *name_bytes = state->args[2].pointer; - int32_t name_len = state->args[3].integer; - int32_t mode = state->args[4].integer; - tree_t where = state->args[5].pointer; - - x_file_open(status, _fp, name_bytes, name_len, mode, where); -} - -static void interp_file_close(jit_interp_t *state) -{ - void **_fp = state->args[0].pointer; - - x_file_close(_fp); -} - -static void interp_file_read(jit_interp_t *state) -{ - void **_fp = state->args[0].pointer; - uint8_t *data = state->args[1].pointer; - int32_t size = state->args[2].integer; - int32_t count = state->args[3].integer; - int32_t *out = state->args[4].pointer; - - x_file_read(_fp, data, size, count, out); -} - -static void interp_file_write(jit_interp_t *state) -{ - void **_fp = state->args[0].pointer; - uint8_t *data = state->args[1].pointer; - int32_t len = state->args[2].integer; - - x_file_write(_fp, data, len); -} - -static void interp_endfile(jit_interp_t *state) -{ - void *_fp = state->args[0].pointer; - - state->args[0].integer = x_endfile(_fp); - state->nargs = 1; -} - -static void interp_real_to_string(jit_interp_t *state) -{ - double value = state->args[0].real; - - char *buf = mspace_alloc(state->mspace, 32); - if (buf == NULL) - return; - - ffi_uarray_t u = x_real_to_string(value, buf, 32); - state->args[0].pointer = u.ptr; - state->args[1].integer = u.dims[0].left; - state->args[2].integer = u.dims[0].length; - state->nargs = 3; -} - -static void interp_debug_out(jit_interp_t *state) -{ - int64_t value = state->args[0].integer; - debugf("DEBUG %"PRIi64, value); -} - -static void interp_alias_signal(jit_interp_t *state) -{ - sig_shared_t *ss = state->args[0].pointer; - tree_t where = state->args[1].pointer; - - x_alias_signal(ss, where); -} - -static void interp_map_const(jit_interp_t *state) -{ - sig_shared_t *dst_ss = state->args[0].pointer; - uint32_t dst_offset = state->args[1].integer; - jit_scalar_t initval = { .integer = state->args[2].integer }; - uint32_t dst_count = state->args[3].integer; - bool scalar = state->args[4].integer; - - const void *vptr = scalar ? &initval.integer : initval.pointer; - - x_map_const(dst_ss, dst_offset, vptr, dst_count); -} - -static void interp_resolve_signal(jit_interp_t *state) -{ - if (!jit_has_runtime(state->func->jit)) - return; // Called during constant folding - - sig_shared_t *shared = state->args[0].pointer; - jit_handle_t handle = state->args[1].integer; - void *context = state->args[2].pointer; - int32_t ileft = state->args[3].integer; - int32_t nlits = state->args[4].integer; - int32_t flags = state->args[5].integer; - - x_resolve_signal2(shared, handle, context, ileft, nlits, flags); -} - -static void interp_last_event(jit_interp_t *state) -{ - sig_shared_t *shared = state->args[0].pointer; - uint32_t offset = state->args[1].integer; - uint32_t count = state->args[2].integer; - - state->args[0].integer = x_last_event(shared, offset, count); - state->nargs = 1; -} - -static void interp_last_active(jit_interp_t *state) -{ - sig_shared_t *shared = state->args[0].pointer; - uint32_t offset = state->args[1].integer; - uint32_t count = state->args[2].integer; - - state->args[0].integer = x_last_active(shared, offset, count); - state->nargs = 1; -} - static void interp_exit(jit_interp_t *state, jit_ir_t *ir) { state->anchor->irpos = ir - state->func->irbuf; - - switch (ir->arg1.exit) { - case JIT_EXIT_INDEX_FAIL: - interp_index_fail(state); - break; - - case JIT_EXIT_OVERFLOW: - interp_overflow(state); - break; - - case JIT_EXIT_NULL_DEREF: - interp_null_deref(state); - break; - - case JIT_EXIT_LENGTH_FAIL: - interp_length_fail(state); - break; - - case JIT_EXIT_UNREACHABLE: - interp_unreachable(state); - break; - - case JIT_EXIT_EXPONENT_FAIL: - interp_exponent_fail(state); - break; - - case JIT_EXIT_REPORT: - interp_report(state); - break; - - case JIT_EXIT_REAL_TO_STRING: - interp_real_to_string(state); - break; - - case JIT_EXIT_RANGE_FAIL: - interp_range_fail(state); - break; - - case JIT_EXIT_INIT_SIGNAL: - interp_scalar_init_signal(state); - break; - - case JIT_EXIT_DRIVE_SIGNAL: - interp_drive_signal(state); - break; - - case JIT_EXIT_SCHED_PROCESS: - interp_sched_process(state); - break; - - case JIT_EXIT_SCHED_WAVEFORM: - interp_sched_waveform(state); - break; - - case JIT_EXIT_TEST_EVENT: - interp_test_event(state); - break; - - case JIT_EXIT_TEST_ACTIVE: - interp_test_active(state); - break; - - case JIT_EXIT_SCHED_EVENT: - interp_sched_event(state); - break; - - case JIT_EXIT_FILE_OPEN: - interp_file_open(state); - break; - - case JIT_EXIT_FILE_CLOSE: - interp_file_close(state); - break; - - case JIT_EXIT_FILE_READ: - interp_file_read(state); - break; - - case JIT_EXIT_FILE_WRITE: - interp_file_write(state); - break; - - case JIT_EXIT_ENDFILE: - interp_endfile(state); - break; - - case JIT_EXIT_DEBUG_OUT: - interp_debug_out(state); - break; - - case JIT_EXIT_ALIAS_SIGNAL: - interp_alias_signal(state); - break; - - case JIT_EXIT_MAP_CONST: - interp_map_const(state); - break; - - case JIT_EXIT_RESOLVE_SIGNAL: - interp_resolve_signal(state); - break; - - case JIT_EXIT_LAST_EVENT: - interp_last_event(state); - break; - - case JIT_EXIT_LAST_ACTIVE: - interp_last_active(state); - break; - - default: - __nvc_do_exit(ir->arg1.exit, state->anchor, state->args); - } + __nvc_do_exit(ir->arg1.exit, state->anchor, state->args); } static void interp_fficall(jit_interp_t *state, jit_ir_t *ir) diff --git a/src/jit/jit-irgen.c b/src/jit/jit-irgen.c index be42c3be..9b8c3f49 100644 --- a/src/jit/jit-irgen.c +++ b/src/jit/jit-irgen.c @@ -1105,8 +1105,6 @@ static void irgen_send_args(jit_irgen_t *g, int op, int first) for (int i = 0, pslot = first; i < nargs; i++) { vcode_reg_t vreg = vcode_get_arg(op, i); int slots = irgen_slots_for_type(vcode_reg_type(vreg)); - if (vcode_reg_kind(vreg) == VCODE_TYPE_SIGNAL) - slots++; if (slots > 1) { jit_reg_t base = jit_value_as_reg(irgen_get_value(g, vreg)); for (int j = 0; j < slots; j++) @@ -3441,8 +3439,6 @@ static void irgen_params(jit_irgen_t *g, int first) vcode_reg_t preg = vcode_param_reg(i); vcode_type_t vtype = vcode_param_type(i); int slots = irgen_slots_for_type(vtype); - if (vcode_reg_kind(preg) == VCODE_TYPE_SIGNAL) - slots++; g->map[preg] = j_recv(g, pslot++); for (int i = 1; i < slots; i++) j_recv(g, pslot++); // Must be contiguous registers -- 2.39.2