From c56575a15d3e94a9a1da2c6e61c98246225a6652 Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sat, 14 Aug 2021 11:33:01 +0800 Subject: [PATCH] Some work on lowering record sub-signals --- src/lower.c | 39 +++++++++++++++++++++++++++------------ src/vcode.c | 10 ++++++++-- 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/lower.c b/src/lower.c index 769d3f9b..72981ca7 100644 --- a/src/lower.c +++ b/src/lower.c @@ -982,8 +982,13 @@ static vcode_reg_t lower_record_eq(vcode_reg_t r0, vcode_reg_t r1, type_t type) vcode_reg_t cmp = VCODE_INVALID_REG; type_t ftype = tree_type(type_field(type, i)); - if (type_is_array(ftype)) + if (type_is_array(ftype)) { + if (!lower_const_bounds(ftype)) { + lfield = emit_load_indirect(lfield); + rfield = emit_load_indirect(rfield); + } cmp = lower_array_cmp(lfield, rfield, ftype, ftype, VCODE_CMP_EQ); + } else if (type_is_record(ftype)) cmp = lower_record_eq(lfield, rfield, ftype); else { @@ -4961,6 +4966,26 @@ static bool lower_resolution_func(type_t type, vcode_res_fn_t **data, return false; } +static void lower_record_sub_signals(type_t type, vcode_reg_t subsig, + vcode_reg_t init_reg) +{ + const int nfields = type_fields(type); + for (int i = 0; i < nfields; i++) { + type_t ft = tree_type(type_field(type, i)); + vcode_reg_t field_reg = emit_record_ref(init_reg, i); + + if (type_is_record(ft)) + lower_record_sub_signals(ft, subsig, init_reg); + else { + vcode_reg_t size_reg = emit_const(vtype_offset(), byte_width(ft)); + vcode_reg_t count_reg = emit_const(vtype_offset(), 1); + emit_init_signal(subsig, field_reg, count_reg, size_reg, NULL); + if (i + 1 < nfields) + subsig = emit_add(subsig, count_reg); + } + } +} + static void lower_signal_decl(tree_t decl) { bool is_package_signal = false; @@ -5039,17 +5064,7 @@ static void lower_signal_decl(tree_t decl) } if (type_is_record(type)) { - vcode_reg_t subsig = shared; - const int nfields = type_fields(type); - for (int i = 0; i < nfields; i++) { - type_t ft = tree_type(type_field(type, i)); - vcode_reg_t field_reg = emit_record_ref(init_reg, i); - vcode_reg_t size_reg = emit_const(vtype_offset(), byte_width(ft)); - vcode_reg_t count_reg = emit_const(vtype_offset(), 1); - emit_init_signal(subsig, field_reg, count_reg, size_reg, resolution); - if (i + 1 < nfields) - subsig = emit_add(subsig, count_reg); - } + lower_record_sub_signals(type, shared, init_reg); } else { vcode_reg_t size_reg = emit_const(vtype_offset(), byte_width(type)); diff --git a/src/vcode.c b/src/vcode.c index 5d1018ef..dc0bfaa5 100644 --- a/src/vcode.c +++ b/src/vcode.c @@ -4407,10 +4407,16 @@ vcode_reg_t emit_memcmp(vcode_reg_t lhs, vcode_reg_t rhs, vcode_reg_t len) vcode_add_arg(op, rhs); vcode_add_arg(op, len); - VCODE_ASSERT(vtype_kind(vcode_reg_type(lhs)) == VCODE_TYPE_POINTER, + vcode_type_t ltype = vcode_reg_type(lhs); + vcode_type_t rtype = vcode_reg_type(rhs); + + VCODE_ASSERT(vtype_kind(ltype) == VCODE_TYPE_POINTER, "LHS of memcmp must have pointer type"); - VCODE_ASSERT(vtype_kind(vcode_reg_type(rhs)) == VCODE_TYPE_POINTER, + VCODE_ASSERT(vtype_kind(rtype) == VCODE_TYPE_POINTER, "RHS of memcmp must have pointer type"); + VCODE_ASSERT(vtype_eq(ltype, rtype), "LHS and RHS types not the same"); + VCODE_ASSERT(vtype_kind(vtype_pointed(ltype)) != VCODE_TYPE_UARRAY, + "cannot use memcmpy with uarray pointers"); VCODE_ASSERT(vtype_kind(vcode_reg_type(len)) == VCODE_TYPE_OFFSET, "length of memcmp must have offset type"); -- 2.39.2