Fix typos in comments: s/wether/whether/ and related corrections.
[libfirm] / ir / be / sparc / bearch_sparc.c
index 821f5a2..5e3fbed 100644 (file)
@@ -20,6 +20,7 @@
 /**
  * @file
  * @brief    The main sparc backend driver file.
+ * @author   Hannes Rapp, Matthias Braun
  * @version  $Id$
  */
 #include "config.h"
@@ -69,7 +70,7 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 static arch_irn_class_t sparc_classify(const ir_node *node)
 {
        (void) node;
-       return 0;
+       return arch_irn_class_none;
 }
 
 static ir_entity *sparc_get_frame_entity(const ir_node *node)
@@ -116,6 +117,8 @@ static int sparc_get_sp_bias(const ir_node *node)
                 * calculates that! */
                assert(attr->immediate_value <= -SPARC_MIN_STACKSIZE);
                return attr->immediate_value + SPARC_MIN_STACKSIZE;
+       } else if (is_sparc_RestoreZero(node)) {
+               return SP_BIAS_RESET;
        }
        return 0;
 }
@@ -235,7 +238,7 @@ static void sparc_after_ra_walker(ir_node *block, void *data)
 
 static void sparc_collect_frame_entity_nodes(ir_node *node, void *data)
 {
-       be_fec_env_t  *env = data;
+       be_fec_env_t  *env = (be_fec_env_t*)data;
        const ir_mode *mode;
        int            align;
        ir_entity     *entity;
@@ -280,10 +283,12 @@ static void sparc_set_frame_entity(ir_node *node, ir_entity *entity)
 
 static void sparc_after_ra(ir_graph *irg)
 {
-       be_fec_env_t *fec_env = be_new_frame_entity_coalescer(irg);
+       be_stack_layout_t *stack_layout = be_get_irg_stack_layout(irg);
+       bool               at_begin     = stack_layout->sp_relative ? true : false;
+       be_fec_env_t      *fec_env      = be_new_frame_entity_coalescer(irg);
 
        irg_walk_graph(irg, NULL, sparc_collect_frame_entity_nodes, fec_env);
-       be_assign_entities(fec_env, sparc_set_frame_entity);
+       be_assign_entities(fec_env, sparc_set_frame_entity, at_begin);
        be_free_frame_entity_coalescer(fec_env);
 
        irg_block_walk_graph(irg, NULL, sparc_after_ra_walker, NULL);
@@ -294,7 +299,7 @@ static void sparc_init_graph(ir_graph *irg)
        (void) irg;
 }
 
-const arch_isa_if_t sparc_isa_if;
+extern const arch_isa_if_t sparc_isa_if;
 static sparc_isa_t sparc_isa_template = {
        {
                &sparc_isa_if,                      /* isa interface implementation */
@@ -343,9 +348,9 @@ static void rewrite_unsigned_float_Conv(ir_node *node)
                ir_node   *signed_x    = new_rd_Conv(dbgi, block, unsigned_x, mode_s);
                ir_node   *res         = new_rd_Conv(dbgi, block, signed_x, mode_d);
                ir_node   *zero        = new_r_Const(irg, get_mode_null(mode_s));
-               ir_node   *cmp         = new_rd_Cmp(dbgi, block, signed_x, zero);
-               ir_node   *proj_lt     = new_r_Proj(cmp, mode_b, pn_Cmp_Lt);
-               ir_node   *cond        = new_rd_Cond(dbgi, block, proj_lt);
+               ir_node   *cmp         = new_rd_Cmp(dbgi, block, signed_x, zero,
+                                                   ir_relation_less);
+               ir_node   *cond        = new_rd_Cond(dbgi, block, cmp);
                ir_node   *proj_true   = new_r_Proj(cond, mode_X, pn_Cond_true);
                ir_node   *proj_false  = new_r_Proj(cond, mode_X, pn_Cond_false);
                ir_node   *in_true[1]  = { proj_true };
@@ -477,14 +482,7 @@ static void sparc_handle_intrinsics(void)
  */
 static arch_env_t *sparc_init(FILE *outfile)
 {
-       static int run_once = 0;
-       sparc_isa_t *isa;
-
-       if (run_once)
-               return NULL;
-       run_once = 1;
-
-       isa = XMALLOC(sparc_isa_t);
+       sparc_isa_t *isa = XMALLOC(sparc_isa_t);
        memcpy(isa, &sparc_isa_template, sizeof(*isa));
        isa->constants = pmap_create();
 
@@ -502,7 +500,7 @@ static arch_env_t *sparc_init(FILE *outfile)
  */
 static void sparc_done(void *self)
 {
-       sparc_isa_t *isa = self;
+       sparc_isa_t *isa = (sparc_isa_t*)self;
 
        /* emit now all global declarations */
        be_gas_emit_decls(isa->base.main_env);
@@ -536,15 +534,32 @@ static int sparc_get_reg_class_alignment(const arch_register_class_t *cls)
        return get_mode_size_bytes(mode);
 }
 
+static ir_node *sparc_create_set(ir_node *cond)
+{
+       return ir_create_cond_set(cond, mode_Iu);
+}
+
 static void sparc_lower_for_target(void)
 {
-       int i;
-       int n_irgs = get_irp_n_irgs();
+       size_t i, n_irgs = get_irp_n_irgs();
+       lower_mode_b_config_t lower_mode_b_config = {
+               mode_Iu,
+               sparc_create_set,
+               0,
+       };
+       lower_params_t params = {
+               4,                                     /* def_ptr_alignment */
+               LF_COMPOUND_RETURN | LF_RETURN_HIDDEN, /* flags */
+               ADD_HIDDEN_ALWAYS_IN_FRONT,            /* hidden_params */
+               NULL,                                  /* find pointer type */
+               NULL,                                  /* ret_compound_in_regs */
+       };
 
-       /* TODO, doubleword lowering and others */
+       lower_calls_with_compounds(&params);
 
        for (i = 0; i < n_irgs; ++i) {
                ir_graph *irg = get_irp_irg(i);
+               ir_lower_mode_b(irg, &lower_mode_b_config);
                lower_switch(irg, 256, false);
        }
 }
@@ -552,9 +567,17 @@ static void sparc_lower_for_target(void)
 static int sparc_is_mux_allowed(ir_node *sel, ir_node *mux_false,
                                 ir_node *mux_true)
 {
-       (void) sel;
-       (void) mux_false;
-       (void) mux_true;
+       ir_graph *irg  = get_irn_irg(sel);
+       ir_mode  *mode = get_irn_mode(mux_true);
+
+       if (get_irg_phase_state(irg) == phase_low)
+               return false;
+
+       if (!mode_is_int(mode) && !mode_is_reference(mode) && mode != mode_b)
+               return false;
+       if (is_Const(mux_true) && is_Const_one(mux_true) &&
+                       is_Const(mux_false) && is_Const_null(mux_false))
+               return true;
        return false;
 }
 
@@ -576,7 +599,6 @@ static const backend_params *sparc_get_backend_params(void)
                0,     /* no inline assembly */
                0,     /* no support for RotL nodes */
                1,     /* big endian */
-               sparc_lower_for_target, /* lowering callback */
                &arch_dep,              /* will be set later */
                sparc_is_mux_allowed,   /* parameter for if conversion */
                NULL,  /* float arithmetic mode */
@@ -610,6 +632,7 @@ static int sparc_is_valid_clobber(const char *clobber)
 
 const arch_isa_if_t sparc_isa_if = {
        sparc_init,
+       sparc_lower_for_target,
        sparc_done,
        NULL,                /* handle intrinsics */
        sparc_get_reg_class_for_mode,
@@ -627,7 +650,7 @@ const arch_isa_if_t sparc_isa_if = {
        sparc_prepare_graph,
        sparc_before_ra,
        sparc_after_ra,
-       NULL, /* finish */
+       sparc_finish,
        sparc_emit_routine,
 };