add special constant to represent VA_START-address in a parameter_entity
authorMatthias Braun <matze@braunis.de>
Mon, 22 Aug 2011 12:47:14 +0000 (14:47 +0200)
committerMatthias Braun <matze@braunis.de>
Mon, 22 Aug 2011 14:27:37 +0000 (16:27 +0200)
include/libfirm/typerep.h
ir/be/beabi.c
ir/be/beabihelper.c
ir/lower/lower_calls.c
ir/lower/lower_dw.c

index 3f49774..3c52b51 100644 (file)
@@ -413,6 +413,8 @@ FIRM_API dbg_info *get_entity_dbg_info(const ir_entity *ent);
  */
 FIRM_API void set_entity_dbg_info(ir_entity *ent, dbg_info *db);
 
+#define IR_VA_START_PARAMETER_NUMBER  ((size_t)-1)
+
 /**
  * returns true if a given entity is a parameter_entity representing the
  * address of a function parameter
index b823fa1..9966c83 100644 (file)
@@ -1166,10 +1166,10 @@ static ir_type *compute_arg_type(ir_graph *irg, be_abi_call_t *call,
                                                                 ir_type *method_type, ir_entity ***param_map)
 {
        struct obstack *obst = be_get_be_obst(irg);
-       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;
+       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);
+       ir_entity *va_start_entity = NULL;
        size_t   f;
        int      ofs  = 0;
 
@@ -1177,12 +1177,7 @@ static ir_type *compute_arg_type(ir_graph *irg, be_abi_call_t *call,
        size_t i;
        ir_entity **map;
 
-       /* 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);
+       *param_map = map = OALLOCNZ(obst, ir_entity*, n_params);
        res = new_type_struct(new_id_from_chars("arg_type", 8));
 
        /* collect existing entities for value_param_types */
@@ -1194,7 +1189,13 @@ 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_real_params);
+               if (num == IR_VA_START_PARAMETER_NUMBER) {
+                       /* move entity to new arg_type */
+                       set_entity_owner(entity, res);
+                       va_start_entity = entity;
+                       continue;
+               }
+               assert(num < n_params);
                if (map[num] != NULL)
                        panic("multiple entities for parameter %u in %+F found", f, irg);
 
@@ -1228,13 +1229,12 @@ static ir_type *compute_arg_type(ir_graph *irg, be_abi_call_t *call,
                ofs += get_type_size_bytes(param_type);
                arg->stack_ent = entity;
        }
+       if (va_start_entity != NULL) {
+               set_entity_offset(va_start_entity, ofs);
+       }
        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;
 }
 
index a7a8b6e..c5f9555 100644 (file)
@@ -690,7 +690,10 @@ void be_add_parameter_entity_stores(ir_graph *irg)
                if (!is_parameter_entity(entity))
                        continue;
 
-               arg  = get_entity_parameter_number(entity);
+               arg = get_entity_parameter_number(entity);
+               if (arg == IR_VA_START_PARAMETER_NUMBER)
+                       continue;
+
                addr = new_r_Sel(start_block, mem, frame, 0, NULL, entity);
                if (entity->attr.parameter.doubleword_low_mode != NULL) {
                        ir_mode *mode      = entity->attr.parameter.doubleword_low_mode;
index fbb1e64..9d64b13 100644 (file)
@@ -77,6 +77,8 @@ static void fix_parameter_entities(ir_graph *irg, size_t n_compound_ret)
 
                /* increase parameter number since we added a new parameter in front */
                num = get_entity_parameter_number(member);
+               if (num == IR_VA_START_PARAMETER_NUMBER)
+                       continue;
                set_entity_parameter_number(member, num + n_compound_ret);
        }
 }
index c92c2af..76966b8 100644 (file)
@@ -1606,15 +1606,9 @@ 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);
-       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);
+       parameter_entities = ALLOCANZ(ir_entity*, orig_n_params);
 
        ir_type *frame_type = get_irg_frame_type(irg);
        size_t   n          = get_compound_n_members(frame_type);
@@ -1628,23 +1622,22 @@ static void fix_parameter_entities(ir_graph *irg)
                if (!is_parameter_entity(entity))
                        continue;
                p = get_entity_parameter_number(entity);
-               assert(p < orig_n_real_params);
+               if (p == IR_VA_START_PARAMETER_NUMBER)
+                       continue;
+               assert(p < orig_n_params);
                assert(parameter_entities[p] == NULL);
                parameter_entities[p] = entity;
        }
 
        /* adjust indices */
        n_param = 0;
-       for (i = 0; i < orig_n_real_params; ++i, ++n_param) {
+       for (i = 0; i < orig_n_params; ++i, ++n_param) {
                ir_entity *entity = parameter_entities[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);