sparc: implement float->unsigned conversions
[libfirm] / ir / be / beabi.c
index 1da1d04..1e6cb71 100644 (file)
@@ -21,7 +21,6 @@
  * @file
  * @brief       Backend ABI implementation.
  * @author      Sebastian Hack, Michael Beck
- * @version     $Id$
  */
 #include "config.h"
 
 #include "irgwalk.h"
 #include "irprintf_t.h"
 #include "irgopt.h"
-#include "irbitset.h"
 #include "iropt_t.h"
+#include "irtools.h"
 #include "heights.h"
 #include "pdeq.h"
-#include "irtools.h"
+#include "util.h"
 #include "raw_bitset.h"
 #include "error.h"
 #include "pset_new.h"
@@ -387,7 +386,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
        const ir_edge_t        *edge;
        int                    *reg_param_idxs;
        int                    *stack_param_idx;
-       int                     i, n, destroy_all_regs;
+       int                     i, n;
        int                     throws_exception;
        size_t                  s;
        size_t                  p;
@@ -524,20 +523,6 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
                }
        }
 
-       /* check for the return_twice property */
-       destroy_all_regs = 0;
-       if (is_SymConst_addr_ent(call_ptr)) {
-               ir_entity *ent = get_SymConst_entity(call_ptr);
-
-               if (get_entity_additional_properties(ent) & mtp_property_returns_twice)
-                       destroy_all_regs = 1;
-       } else {
-               ir_type *call_tp = get_Call_type(irn);
-
-               if (get_method_additional_properties(call_tp) & mtp_property_returns_twice)
-                       destroy_all_regs = 1;
-       }
-
        /* Put caller save into the destroyed set and state registers in the states
         * set */
        for (i = 0, n = arch_env->n_register_classes; i < n; ++i) {
@@ -558,7 +543,7 @@ static ir_node *adjust_call(be_abi_irg_t *env, ir_node *irn, ir_node *curr_sp)
                                 * checking */
                                continue;
                        }
-                       if (destroy_all_regs || arch_register_is_caller_save(arch_env, reg)) {
+                       if (arch_register_is_caller_save(arch_env, reg)) {
                                if (!(reg->type & arch_register_type_ignore)) {
                                        ARR_APP1(const arch_register_t*, destroyed_regs, reg);
                                }
@@ -880,7 +865,7 @@ static ir_node *adjust_alloc(be_abi_irg_t *env, ir_node *alloc, ir_node *curr_sp
        count = get_Alloc_count(alloc);
 
        /* we might need to multiply the count with the element size */
-       if (type != firm_unknown_type && get_type_size_bytes(type) != 1) {
+       if (!is_unknown_type(type) && get_type_size_bytes(type) != 1) {
                ir_mode   *mode  = get_irn_mode(count);
                ir_tarval *tv    = new_tarval_from_long(get_type_size_bytes(type),
                                                        mode);
@@ -945,14 +930,14 @@ static ir_node *adjust_free(be_abi_irg_t *env, ir_node *free, ir_node *curr_sp)
        assert(get_Free_where(free) == stack_alloc);
 
        /* we might need to multiply the size with the element size */
-       if (type != firm_unknown_type && get_type_size_bytes(type) != 1) {
+       if (!is_unknown_type(type) && get_type_size_bytes(type) != 1) {
                ir_tarval *tv   = new_tarval_from_long(get_type_size_bytes(type), mode_Iu);
                ir_node   *cnst = new_rd_Const(dbg, irg, tv);
-               ir_node   *mul  = new_rd_Mul(dbg, block, get_Free_size(free),
+               ir_node   *mul  = new_rd_Mul(dbg, block, get_Free_count(free),
                                             cnst, mode_Iu);
                size = mul;
        } else {
-               size = get_Free_size(free);
+               size = get_Free_count(free);
        }
 
        stack_alignment = 1 << arch_env->stack_alignment;
@@ -1166,9 +1151,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);
+       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;
 
@@ -1188,11 +1174,17 @@ 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);
+               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);
 
-               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;
                }
@@ -1222,8 +1214,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);
+
        return res;
 }