sparc: support mode_b lowering
[libfirm] / ir / be / sparc / bearch_sparc.c
index fc2dd02..6467a44 100644 (file)
@@ -107,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;
 }
@@ -195,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);
@@ -294,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
@@ -327,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 };
@@ -504,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.
@@ -540,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.
  */
@@ -573,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 */
@@ -607,8 +629,6 @@ 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_reg_class_alignment,