sparc: support mode_b lowering
[libfirm] / ir / be / sparc / bearch_sparc.c
index 6e6282f..6467a44 100644 (file)
@@ -50,7 +50,6 @@
 #include "../besched.h"
 #include "be.h"
 #include "../bemachine.h"
-#include "../beilpsched.h"
 #include "../bemodule.h"
 #include "../beirg.h"
 #include "../bespillslots.h"
@@ -108,12 +107,15 @@ static void sparc_set_frame_offset(ir_node *node, int offset)
 static int sparc_get_sp_bias(const ir_node *node)
 {
        if (is_sparc_Save(node)) {
-               const sparc_save_attr_t *attr = get_sparc_save_attr_const(node);
-               /* Note we do not retport the change of the SPARC_MIN_STACKSIZE
+               const sparc_attr_t *attr = get_sparc_attr_const(node);
+               if (get_irn_arity(node) == 3)
+                       panic("no support for _reg variant yet");
+
+               /* Note we do not report the change of the SPARC_MIN_STACKSIZE
                 * size, since we have additional magic in the emitter which
                 * calculates that! */
-               assert(attr->initial_stacksize >= SPARC_MIN_STACKSIZE);
-               return attr->initial_stacksize - SPARC_MIN_STACKSIZE;
+               assert(attr->immediate_value <= -SPARC_MIN_STACKSIZE);
+               return attr->immediate_value + SPARC_MIN_STACKSIZE;
        }
        return 0;
 }
@@ -196,7 +198,8 @@ static void transform_Spill(ir_node *node)
        ir_node   *block  = get_nodes_block(node);
        dbg_info  *dbgi   = get_irn_dbg_info(node);
        ir_node   *ptr    = get_irn_n(node, be_pos_Spill_frame);
-       ir_node   *mem    = new_NoMem();
+       ir_graph  *irg    = get_irn_irg(node);
+       ir_node   *mem    = new_r_NoMem(irg);
        ir_node   *val    = get_irn_n(node, be_pos_Spill_val);
        ir_mode   *mode   = get_irn_mode(val);
        ir_entity *entity = be_get_frame_entity(node);
@@ -295,8 +298,12 @@ const arch_isa_if_t sparc_isa_if;
 static sparc_isa_t sparc_isa_template = {
        {
                &sparc_isa_if,                      /* isa interface implementation */
-               &sparc_gp_regs[REG_SP],             /* stack pointer register */
-               &sparc_gp_regs[REG_FRAME_POINTER],  /* base pointer register */
+               N_SPARC_REGISTERS,
+               sparc_registers,
+               N_SPARC_CLASSES,
+               sparc_reg_classes,
+               &sparc_registers[REG_SP],           /* stack pointer register */
+               &sparc_registers[REG_FRAME_POINTER],/* base pointer register */
                &sparc_reg_classes[CLASS_sparc_gp], /* link pointer register class */
                -1,                                 /* stack direction */
                3,                                  /* power of two stack alignment
@@ -328,28 +335,28 @@ static void rewrite_unsigned_float_Conv(ir_node *node)
        part_block(node);
 
        {
-               ir_node  *block       = get_nodes_block(node);
-               ir_node  *unsigned_x  = get_Conv_op(node);
-               ir_mode  *mode_u      = get_irn_mode(unsigned_x);
-               ir_mode  *mode_s      = find_signed_mode(mode_u);
-               ir_mode  *mode_d      = mode_D;
-               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  *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 };
-               ir_node  *in_false[1] = { proj_false };
-               ir_node  *true_block  = new_r_Block(irg, ARRAY_SIZE(in_true), in_true);
-               ir_node  *false_block = new_r_Block(irg, ARRAY_SIZE(in_false),in_false);
-               ir_node  *true_jmp    = new_r_Jmp(true_block);
-               ir_node  *false_jmp   = new_r_Jmp(false_block);
-               tarval   *correction  = new_tarval_from_double(4294967296., mode_d);
-               ir_node  *c_const     = new_r_Const(irg, correction);
-               ir_node  *fadd        = new_rd_Add(dbgi, true_block, res, c_const,
+               ir_node   *block       = get_nodes_block(node);
+               ir_node   *unsigned_x  = get_Conv_op(node);
+               ir_mode   *mode_u      = get_irn_mode(unsigned_x);
+               ir_mode   *mode_s      = find_signed_mode(mode_u);
+               ir_mode   *mode_d      = mode_D;
+               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   *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 };
+               ir_node   *in_false[1] = { proj_false };
+               ir_node   *true_block  = new_r_Block(irg, ARRAY_SIZE(in_true), in_true);
+               ir_node   *false_block = new_r_Block(irg, ARRAY_SIZE(in_false),in_false);
+               ir_node   *true_jmp    = new_r_Jmp(true_block);
+               ir_node   *false_jmp   = new_r_Jmp(false_block);
+               ir_tarval *correction  = new_tarval_from_double(4294967296., mode_d);
+               ir_node   *c_const     = new_r_Const(irg, correction);
+               ir_node   *fadd        = new_rd_Add(dbgi, true_block, res, c_const,
                                                   mode_d);
 
                ir_node  *lower_in[2] = { true_jmp, false_jmp };
@@ -372,10 +379,10 @@ static void rewrite_unsigned_float_Conv(ir_node *node)
 
 static int sparc_rewrite_Conv(ir_node *node, void *ctx)
 {
-       (void) ctx;
        ir_mode *to_mode   = get_irn_mode(node);
        ir_node *op        = get_Conv_op(node);
        ir_mode *from_mode = get_irn_mode(op);
+       (void) ctx;
 
        if (mode_is_float(to_mode) && mode_is_int(from_mode)
                        && get_mode_size_bits(from_mode) == 32
@@ -505,18 +512,6 @@ static void sparc_done(void *self)
        free(isa);
 }
 
-static unsigned sparc_get_n_reg_class(void)
-{
-       return N_CLASSES;
-}
-
-static const arch_register_class_t *sparc_get_reg_class(unsigned i)
-{
-       assert(i < N_CLASSES);
-       return &sparc_reg_classes[i];
-}
-
-
 
 /**
  * Get the register class which shall be used to store a value of a given mode.
@@ -532,39 +527,6 @@ static const arch_register_class_t *sparc_get_reg_class_for_mode(const ir_mode *
                return &sparc_reg_classes[CLASS_sparc_gp];
 }
 
-static int sparc_to_appear_in_schedule(void *block_env, const ir_node *irn)
-{
-       (void) block_env;
-
-       if (!is_sparc_irn(irn))
-               return -1;
-
-       return 1;
-}
-
-list_sched_selector_t sparc_sched_selector;
-
-/**
- * Returns the reg_pressure scheduler with to_appear_in_schedule() overloaded
- */
-static const list_sched_selector_t *sparc_get_list_sched_selector(
-               const void *self, list_sched_selector_t *selector)
-{
-       (void) self;
-       (void) selector;
-
-       sparc_sched_selector = trivial_selector;
-       sparc_sched_selector.to_appear_in_schedule = sparc_to_appear_in_schedule;
-       return &sparc_sched_selector;
-}
-
-static const ilp_sched_selector_t *sparc_get_ilp_sched_selector(
-               const void *self)
-{
-       (void) self;
-       return NULL;
-}
-
 /**
  * Returns the necessary byte alignment for storing a register of given class.
  */
@@ -574,19 +536,45 @@ 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();
-
-       /* TODO, doubleword lowering and others */
+       lower_mode_b_config_t lower_mode_b_config = {
+               mode_Iu,
+               sparc_create_set,
+               0,
+       };
 
        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);
        }
 }
 
+static int sparc_is_mux_allowed(ir_node *sel, ir_node *mux_false,
+                                ir_node *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;
+}
+
 /**
  * Returns the libFirm configuration parameter for this backend.
  */
@@ -607,7 +595,7 @@ static const backend_params *sparc_get_backend_params(void)
                1,     /* big endian */
                sparc_lower_for_target, /* lowering callback */
                &arch_dep,              /* will be set later */
-               NULL,  /* parameter for if conversion */
+               sparc_is_mux_allowed,   /* parameter for if conversion */
                NULL,  /* float arithmetic mode */
                0,     /* no trampoline support: size 0 */
                0,     /* no trampoline support: align 0 */
@@ -617,21 +605,6 @@ static const backend_params *sparc_get_backend_params(void)
        return &p;
 }
 
-static const be_execution_unit_t ***sparc_get_allowed_execution_units(
-               const ir_node *irn)
-{
-       (void) irn;
-       /* TODO */
-       panic("sparc_get_allowed_execution_units not implemented yet");
-}
-
-static const be_machine_t *sparc_get_machine(const void *self)
-{
-       (void) self;
-       /* TODO */
-       panic("sparc_get_machine not implemented yet");
-}
-
 static ir_graph **sparc_get_backend_irg_list(const void *self,
                                              ir_graph ***irgs)
 {
@@ -656,16 +629,10 @@ const arch_isa_if_t sparc_isa_if = {
        sparc_init,
        sparc_done,
        NULL,                /* handle intrinsics */
-       sparc_get_n_reg_class,
-       sparc_get_reg_class,
        sparc_get_reg_class_for_mode,
        NULL,
-       sparc_get_list_sched_selector,
-       sparc_get_ilp_sched_selector,
        sparc_get_reg_class_alignment,
        sparc_get_backend_params,
-       sparc_get_allowed_execution_units,
-       sparc_get_machine,
        sparc_get_backend_irg_list,
        NULL,                    /* mark remat */
        sparc_parse_asm_constraint,