From afca01c6ef18d7eebec07239ddae714b07b80c7e Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Mon, 15 Jan 2024 20:24:39 +0000 Subject: [PATCH] Simplify logic in lower_direct_mapped_port --- src/lower.c | 72 +++++++++++++++++++-------------------- test/lower/directmap5.vhd | 25 ++++++++++++++ test/test_lower.c | 30 ++++++++++++++++ 3 files changed, 91 insertions(+), 36 deletions(-) create mode 100644 test/lower/directmap5.vhd diff --git a/src/lower.c b/src/lower.c index 6d6be159..74e9a947 100644 --- a/src/lower.c +++ b/src/lower.c @@ -11853,58 +11853,58 @@ static void lower_direct_mapped_port(lower_unit_t *lu, driver_set_t *ds, lower_put_vcode_obj(port, var, lu); } + vcode_reg_t bounds_reg = VCODE_INVALID_REG; + if (!type_const_bounds(port_type)) + bounds_reg = lower_get_type_bounds(lu, port_type); + if (type_is_array(type)) { vcode_reg_t locus = lower_debug_locus(map); - lower_check_array_sizes(lu, port_type, type, VCODE_INVALID_REG, - src_reg, locus); + lower_check_array_sizes(lu, port_type, type, bounds_reg, src_reg, locus); } - if (!type_is_homogeneous(type)) { - vcode_reg_t ptr = emit_index(var, VCODE_INVALID_REG); - if (field != -1) - ptr = emit_record_ref(ptr, field); + if (field == -1 && vcode_reg_kind(src_reg) == VCODE_TYPE_SIGNAL) + emit_alias_signal(src_reg, lower_debug_locus(port)); - if (have_uarray_ptr(ptr)) { - assert(have_uarray_ptr(src_reg)); - vcode_reg_t meta_reg = emit_load_indirect(src_reg); - emit_store_indirect(meta_reg, ptr); - } - else { - vcode_reg_t count_reg = VCODE_INVALID_REG; - if (type_is_array(type)) { - count_reg = lower_array_total_len(lu, type, src_reg); - src_reg = lower_array_data(src_reg); - } + if (field != -1) { + vcode_reg_t ptr_reg = emit_index(var, VCODE_INVALID_REG); + vcode_reg_t field_reg = emit_record_ref(ptr_reg, field); - emit_copy(ptr, src_reg, count_reg); + if (have_uarray_ptr(field_reg)) { + vcode_reg_t data_reg = lower_array_data(src_reg); + vcode_reg_t meta_reg = lower_rewrap(data_reg, bounds_reg); + emit_store_indirect(meta_reg, field_reg); } + else if (type_is_record(type)) + emit_copy(field_reg, src_reg, VCODE_INVALID_REG); + else if (!type_is_homogeneous(type)) { + vcode_reg_t data_reg = lower_array_data(src_reg); + vcode_reg_t count_reg = lower_array_total_len(lu, type, bounds_reg); + emit_copy(field_reg, data_reg, count_reg); + } + else + emit_store_indirect(src_reg, field_reg); } - else if (field == -1 && type_is_array(type)) { + else if (type_is_record(type)) { + vcode_reg_t ptr_reg = emit_index(var, VCODE_INVALID_REG); + emit_copy(ptr_reg, src_reg, VCODE_INVALID_REG); + } + else if (type_is_array(type)) { vcode_reg_t data_reg = lower_array_data(src_reg); - emit_alias_signal(data_reg, lower_debug_locus(port)); - if (vtype_kind(vcode_var_type(var)) == VCODE_TYPE_UARRAY) { - vcode_reg_t wrap_reg = lower_wrap(lu, port_type, data_reg); + if (bounds_reg != VCODE_INVALID_REG) { + vcode_reg_t wrap_reg = lower_rewrap(data_reg, bounds_reg); emit_store(wrap_reg, var); } + else if (!type_is_homogeneous(type)) { + vcode_reg_t ptr_reg = emit_index(var, VCODE_INVALID_REG); + vcode_reg_t count_reg = lower_array_total_len(lu, type, src_reg); + emit_copy(ptr_reg, data_reg, count_reg); + } else emit_store(data_reg, var); } - else if (field == -1) { - emit_alias_signal(src_reg, lower_debug_locus(port)); + else emit_store(src_reg, var); - } - else { - vcode_reg_t data_reg = lower_array_data(src_reg); - vcode_reg_t port_reg = emit_index(var, VCODE_INVALID_REG); - vcode_reg_t field_reg = emit_record_ref(port_reg, field); - if (have_uarray_ptr(field_reg)) { - vcode_reg_t wrap_reg = lower_wrap(lu, type, data_reg); - emit_store_indirect(wrap_reg, field_reg); - } - else - emit_store_indirect(data_reg, field_reg); - } hset_insert(direct, map); hset_insert(direct, port); diff --git a/test/lower/directmap5.vhd b/test/lower/directmap5.vhd new file mode 100644 index 00000000..1de20a91 --- /dev/null +++ b/test/lower/directmap5.vhd @@ -0,0 +1,25 @@ +entity directmap5 is +end entity; + +architecture test of directmap5 is + type t_rec is record + x, y : integer; + end record; + + type t_rec_array is array (natural range <>) of t_rec; + + function get_value return natural is + begin + return 3; + end function; + + signal s : t_rec_array(1 to 3); +begin + + b: block is + port ( t : t_rec_array(1 to get_value) ); + port map ( s ); + begin + end block; + +end architecture; diff --git a/test/test_lower.c b/test/test_lower.c index 2d157a1f..afc02edf 100644 --- a/test/test_lower.c +++ b/test/test_lower.c @@ -5790,6 +5790,35 @@ START_TEST(test_subtype2) } END_TEST +START_TEST(test_directmap5) +{ + input_from_file(TESTDIR "/lower/directmap5.vhd"); + + run_elab(); + + vcode_unit_t vu = find_unit("WORK.DIRECTMAP5.B"); + vcode_select_unit(vu); + + EXPECT_BB(0) = { + { VCODE_OP_PACKAGE_INIT, .name = "STD.STANDARD" }, + { VCODE_OP_VAR_UPREF, .hops = 1, .name = "S" }, + { VCODE_OP_CONST, .value = 1 }, + { VCODE_OP_CONTEXT_UPREF, .hops = 1 }, + { VCODE_OP_FCALL, .func = "WORK.DIRECTMAP5.GET_VALUE()N" }, + { VCODE_OP_CONST, .value = 0 }, + { VCODE_OP_DEBUG_LOCUS }, + { VCODE_OP_RANGE_LENGTH }, + { VCODE_OP_CONST, .value = 3 }, + { VCODE_OP_LENGTH_CHECK }, + { VCODE_OP_WRAP }, + { VCODE_OP_STORE, .name = "T" }, + { VCODE_OP_RETURN }, + }; + + CHECK_BB(0); +} +END_TEST + Suite *get_lower_tests(void) { Suite *s = suite_create("lower"); @@ -5930,6 +5959,7 @@ Suite *get_lower_tests(void) tcase_add_test(tc, test_bounds2); tcase_add_test(tc, test_directmap4); tcase_add_test(tc, test_subtype2); + tcase_add_test(tc, test_directmap5); suite_add_tcase(s, tc); return s; -- 2.39.2