From fcf1d0805df08c3a8ce7d2690f4fcfc7b41ca140 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Mon, 21 Jun 2021 17:19:08 +0800 Subject: [PATCH] Resolved value works --- src/cgen.c | 19 +++++++++++++++++++ src/lower.c | 3 +++ src/rt/rtkern.c | 15 +++++++++------ src/vcode.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- src/vcode.h | 2 ++ 5 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/cgen.c b/src/cgen.c index 13f4d14c..059c66ea 100644 --- a/src/cgen.c +++ b/src/cgen.c @@ -1866,6 +1866,22 @@ static void cgen_op_nets(int op, cgen_ctx_t *ctx) #endif } +static void cgen_op_resolved(int op, cgen_ctx_t *ctx) +{ + vcode_signal_t sig = vcode_get_signal(op); + + vcode_reg_t result = vcode_get_result(op); + + LLVMValueRef display = cgen_display_upref(1, ctx); + LLVMValueRef sig_struct = LLVMBuildStructGEP(builder, display, sig, ""); + LLVMValueRef raw_ptr = LLVMBuildStructGEP(builder, sig_struct, 1, ""); + + ctx->regs[result] = LLVMBuildCast(builder, LLVMBitCast, + LLVMBuildLoad(builder, raw_ptr, ""), + cgen_type(vcode_reg_type(result)), + cgen_reg_name(result)); +} + static LLVMValueRef cgen_pointer_to_arg_data(int op, int arg, cgen_ctx_t *ctx) { const vtype_kind_t kind = vcode_reg_kind(vcode_get_arg(op, arg)); @@ -3009,6 +3025,9 @@ static void cgen_op(int i, cgen_ctx_t *ctx) case VCODE_OP_NETS: cgen_op_nets(i, ctx); break; + case VCODE_OP_RESOLVED: + cgen_op_resolved(i, ctx); + break; case VCODE_OP_SCHED_WAVEFORM: cgen_op_sched_waveform(i, ctx); break; diff --git a/src/lower.c b/src/lower.c index 61e0249b..05c40b62 100644 --- a/src/lower.c +++ b/src/lower.c @@ -2068,6 +2068,7 @@ static vcode_reg_t lower_signal_ref(tree_t decl, expr_ctx_t ctx) if (ctx == EXPR_LVALUE) return emit_nets(sig); else { +#if 0 vcode_var_t shadow = vcode_signal_shadow(sig); if (shadow != VCODE_INVALID_VAR) { vcode_reg_t ptr_reg = emit_var_upref(vcode_unit_depth(), shadow); @@ -2079,6 +2080,8 @@ static vcode_reg_t lower_signal_ref(tree_t decl, expr_ctx_t ctx) } else return emit_nets(sig); +#endif + return emit_resolved(sig); } } diff --git a/src/rt/rtkern.c b/src/rt/rtkern.c index 7bdcddc9..fafb1076 100644 --- a/src/rt/rtkern.c +++ b/src/rt/rtkern.c @@ -177,7 +177,6 @@ typedef struct { e_node_t enode; uint32_t width; uint32_t size; - rt_sigdata_t data; } rt_signal_t; // The code generator knows the layout of this struct @@ -1804,8 +1803,8 @@ static void rt_setup_scopes_recur(e_node_t e, unsigned *next_scope, if (e_kind(e) == E_SCOPE) { const int nsignals = e_signals(e); - rt_scope_t *rs = xcalloc_array(nsignals, sizeof(rt_sigdata_t)); - scopes[(*next_scope)++] = rs; + rt_scope_t *context = xcalloc_array(nsignals, sizeof(rt_sigdata_t)); + scopes[(*next_scope)++] = context; *total_mem += nsignals * sizeof(rt_sigdata_t); @@ -1822,7 +1821,7 @@ static void rt_setup_scopes_recur(e_node_t e, unsigned *next_scope, r->tmp_alloc = 0; r->pending = false; r->usage = 0; - r->context = rs; + r->context = context; } for (int i = 0; i < nsignals; i++) { @@ -1834,7 +1833,11 @@ static void rt_setup_scopes_recur(e_node_t e, unsigned *next_scope, r->width = e_width(s); r->size = e_size(s); - rs->signals[i].sig_id = sig_id; + assert(e_nexuses(s) == 1); + rt_nexus_t *n = &(nexus[e_pos(e_nexus(s, 0))]); + + context->signals[i].sig_id = sig_id; + context->signals[i].displaced = n->resolved; } } @@ -1914,8 +1917,8 @@ static void rt_setup(e_node_t top) heap_free(eventq_heap); eventq_heap = heap_new(512); - rt_setup_scopes(top); rt_setup_nexus(top); + rt_setup_scopes(top); #if 0 if (netdb == NULL) { diff --git a/src/vcode.c b/src/vcode.c index 75211868..3c3176fa 100644 --- a/src/vcode.c +++ b/src/vcode.c @@ -54,7 +54,8 @@ DECLARE_AND_DEFINE_ARRAY(vcode_type); (x == VCODE_OP_CONST) #define OP_HAS_SIGNAL(x) \ (x == VCODE_OP_NETS || x == VCODE_OP_RESOLVED_ADDRESS \ - || x == VCODE_OP_SET_INITIAL || x == VCODE_OP_NEEDS_LAST_VALUE) + || x == VCODE_OP_SET_INITIAL || x == VCODE_OP_NEEDS_LAST_VALUE \ + || x == VCODE_OP_RESOLVED) #define OP_HAS_DIM(x) \ (x == VCODE_OP_UARRAY_LEFT || x == VCODE_OP_UARRAY_RIGHT \ || x == VCODE_OP_UARRAY_DIR || x == VCODE_OP_UARRAY_LEN) @@ -1056,6 +1057,7 @@ const char *vcode_op_string(vcode_op_t op) "storage hint", "debug out", "nested pcall", "cover stmt", "cover cond", "uarray len", "temp stack mark", "temp stack restore", "nested resume", "undefined", "image map", "range null", "var upref", "init nexus", + "resolved" }; if ((unsigned)op >= ARRAY_LEN(strs)) return "???"; @@ -1660,6 +1662,16 @@ void vcode_dump_with_mark(int mark_op) } break; + case VCODE_OP_RESOLVED: + { + col += vcode_dump_reg(op->result); + col += color_printf(" := %s $white$%s$$", + vcode_op_string(op->kind), + istr(vcode_signal_name(op->signal))); + vcode_dump_result_type(col, op); + } + break; + case VCODE_OP_SCHED_WAVEFORM: { printf("%s ", vcode_op_string(op->kind)); @@ -3750,6 +3762,38 @@ vcode_reg_t emit_nets(vcode_signal_t sig) return op->result; } +vcode_reg_t emit_resolved(vcode_signal_t sig) +{ + block_t *b = &(active_unit->blocks.items[active_block]); + for (int i = b->ops.count - 1; i >= 0; i--) { + const op_t *op = &(b->ops.items[i]); + if (op->kind == VCODE_OP_RESOLVED && op->signal == sig) + return op->result; + } + + op_t *op = vcode_add_op(VCODE_OP_RESOLVED); + op->signal = sig; + + vcode_type_t stype = vcode_signal_type(sig); + op->type = stype; + + VCODE_ASSERT(vtype_kind(stype) == VCODE_TYPE_SIGNAL, + "argument to resolved is not a signal"); + + vcode_type_t rtype = vtype_base(stype); + + const vtype_kind_t rkind = vtype_kind(rtype); + if (rkind == VCODE_TYPE_CARRAY || rkind == VCODE_TYPE_UARRAY) + rtype = vtype_elem(rtype); + + op->result = vcode_add_reg(vtype_pointer(rtype)); + + reg_t *rr = vcode_reg_data(op->result); + rr->bounds = vcode_signal_bounds(sig); + + return op->result; +} + void emit_sched_waveform(vcode_reg_t nets, vcode_reg_t nnets, vcode_reg_t values, vcode_reg_t reject, vcode_reg_t after) diff --git a/src/vcode.h b/src/vcode.h index a01a3832..c2c4a359 100644 --- a/src/vcode.h +++ b/src/vcode.h @@ -133,6 +133,7 @@ typedef enum { VCODE_OP_RANGE_NULL, VCODE_OP_VAR_UPREF, VCODE_OP_INIT_NEXUS, + VCODE_OP_RESOLVED, } vcode_op_t; typedef enum { @@ -383,6 +384,7 @@ vcode_reg_t emit_index(vcode_var_t var, vcode_reg_t offset); vcode_reg_t emit_cast(vcode_type_t type, vcode_reg_t bounds, vcode_reg_t reg); void emit_return(vcode_reg_t reg); vcode_reg_t emit_nets(int hops); +vcode_reg_t emit_resolved(vcode_signal_t sig); void emit_sched_waveform(vcode_reg_t nets, vcode_reg_t nnets, vcode_reg_t values, vcode_reg_t reject, vcode_reg_t after); -- 2.39.2