From 355d06b2ec8b63569a679681c8ef2d7806252f6f Mon Sep 17 00:00:00 2001 From: Christoph Mallon Date: Wed, 17 Aug 2011 21:00:50 +0200 Subject: [PATCH] Allow selecting one past the last parameter to get variadic parameters. --- ir/be/beabi.c | 17 ++++++++++++++--- ir/lower/lower_dw.c | 21 +++++++++++++++++---- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ir/be/beabi.c b/ir/be/beabi.c index 1da1d04a8..b823fa140 100644 --- a/ir/be/beabi.c +++ b/ir/be/beabi.c @@ -1169,6 +1169,7 @@ static ir_type *compute_arg_type(ir_graph *irg, be_abi_call_t *call, ir_type *frame_type = get_irg_frame_type(irg); size_t n_params = get_method_n_params(method_type); size_t n_frame_members = get_compound_n_members(frame_type); + size_t n_real_params = n_params; size_t f; int ofs = 0; @@ -1176,7 +1177,12 @@ static ir_type *compute_arg_type(ir_graph *irg, be_abi_call_t *call, size_t i; ir_entity **map; - *param_map = map = OALLOCNZ(obst, ir_entity*, n_params); + /* Allow selecting one past the last parameter to get the variadic + * parameters. */ + if (get_method_variadicity(method_type) == variadicity_variadic) + ++n_real_params; + + *param_map = map = OALLOCNZ(obst, ir_entity*, n_real_params); res = new_type_struct(new_id_from_chars("arg_type", 8)); /* collect existing entities for value_param_types */ @@ -1188,11 +1194,11 @@ static ir_type *compute_arg_type(ir_graph *irg, be_abi_call_t *call, if (!is_parameter_entity(entity)) continue; num = get_entity_parameter_number(entity); - assert(num < n_params); + assert(num < n_real_params); if (map[num] != NULL) panic("multiple entities for parameter %u in %+F found", f, irg); - if (!get_call_arg(call, 0, num, 1)->on_stack) { + if (num != n_params && !get_call_arg(call, 0, num, 1)->on_stack) { /* don't move this entity */ continue; } @@ -1224,6 +1230,11 @@ static ir_type *compute_arg_type(ir_graph *irg, be_abi_call_t *call, } set_type_size_bytes(res, ofs); set_type_state(res, layout_fixed); + + if (n_params != n_real_params && map[n_params] != NULL) { + set_entity_offset(map[n_params], ofs); + } + return res; } diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c index 7b7db7519..31a2bb3ce 100644 --- a/ir/lower/lower_dw.c +++ b/ir/lower/lower_dw.c @@ -1606,7 +1606,15 @@ static void fix_parameter_entities(ir_graph *irg) ir_type *orig_mtp = get_type_link(mtp); size_t orig_n_params = get_method_n_params(orig_mtp); - ir_entity **parameter_entities = ALLOCANZ(ir_entity*, orig_n_params); + size_t orig_n_real_params = orig_n_params; + ir_entity **parameter_entities; + + /* Allow selecting one past the last parameter to get the variadic + * parameters. */ + if (get_method_variadicity(orig_mtp) == variadicity_variadic) + ++orig_n_real_params; + + parameter_entities = ALLOCANZ(ir_entity*, orig_n_real_params); ir_type *frame_type = get_irg_frame_type(irg); size_t n = get_compound_n_members(frame_type); @@ -1620,19 +1628,24 @@ static void fix_parameter_entities(ir_graph *irg) if (!is_parameter_entity(entity)) continue; p = get_entity_parameter_number(entity); - assert(p < orig_n_params); + assert(p < orig_n_real_params); assert(parameter_entities[p] == NULL); parameter_entities[p] = entity; } /* adjust indices */ n_param = 0; - for (i = 0; i < orig_n_params; ++i, ++n_param) { + for (i = 0; i < orig_n_real_params; ++i, ++n_param) { ir_entity *entity = parameter_entities[i]; - ir_type *tp = get_method_param_type(orig_mtp, i); + ir_type *tp; + if (entity != NULL) set_entity_parameter_number(entity, n_param); + if (i == orig_n_params) + break; + + tp = get_method_param_type(orig_mtp, i); if (is_Primitive_type(tp)) { ir_mode *mode = get_type_mode(tp); if (mode == env->high_signed || mode == env->high_unsigned) { -- 2.20.1