besched: Add and use sched_replace().
[libfirm] / ir / be / TEMPLATE / TEMPLATE_transform.c
index f88973d..7a8b7e0 100644 (file)
@@ -20,7 +20,6 @@
 /**
  * @file
  * @brief   code selection (transform FIRM into TEMPLATE FIRM)
- * @version $Id$
  */
 #include "config.h"
 
@@ -34,8 +33,8 @@
 #include "debug.h"
 #include "error.h"
 
-#include "../benode.h"
-#include "../betranshlp.h"
+#include "benode.h"
+#include "betranshlp.h"
 #include "bearch_TEMPLATE_t.h"
 
 #include "TEMPLATE_nodes_attr.h"
@@ -49,6 +48,8 @@ DEBUG_ONLY(static firm_dbg_module_t *dbg = NULL;)
 typedef ir_node* (*new_binop_func)(dbg_info *dbgi, ir_node *block,
                                    ir_node *left, ir_node *right);
 
+static ir_mode *gp_regs_mode;
+
 static ir_node *transform_binop(ir_node *node, new_binop_func new_func)
 {
        ir_node  *block     = get_nodes_block(node);
@@ -77,18 +78,26 @@ static ir_node *gen_Eor(ir_node *node)
        return transform_binop(node, new_bd_TEMPLATE_Xor);
 }
 
-static ir_node *gen_Quot(ir_node *node)
+static ir_node *gen_Div(ir_node *node)
 {
+       ir_mode *mode = get_Div_resmode(node);
+       assert(mode_is_float(mode));
        return transform_binop(node, new_bd_TEMPLATE_fDiv);
 }
 
 static ir_node *gen_Shl(ir_node *node)
 {
+       ir_mode *mode = get_irn_mode(node);
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo shift!=32 not supported");
        return transform_binop(node, new_bd_TEMPLATE_Shl);
 }
 
 static ir_node *gen_Shr(ir_node *node)
 {
+       ir_mode *mode = get_irn_mode(node);
+       if (get_mode_modulo_shift(mode) != 32)
+               panic("modulo shift!=32 not supported");
        return transform_binop(node, new_bd_TEMPLATE_Shr);
 }
 
@@ -153,17 +162,14 @@ static ir_node *gen_Not(ir_node *node)
 
 static ir_node *gen_Const(ir_node *node)
 {
-       ir_node  *block     = get_nodes_block(node);
-       ir_node  *new_block = be_transform_node(block);
-       dbg_info *dbgi      = get_irn_dbg_info(node);
-       tarval   *value     = get_Const_tarval(node);
-       ir_node  *result;
+       ir_node   *block     = get_nodes_block(node);
+       ir_node   *new_block = be_transform_node(block);
+       dbg_info  *dbgi      = get_irn_dbg_info(node);
+       ir_tarval *value     = get_Const_tarval(node);
+       ir_node   *result;
 
        result = new_bd_TEMPLATE_Const(dbgi, new_block, value);
 
-       /* make sure the node does not float above the barrier into the prologue */
-       be_dep_on_frame(result);
-
        return result;
 }
 
@@ -212,6 +218,28 @@ static ir_node *gen_Jmp(ir_node *node)
        return new_bd_TEMPLATE_Jmp(dbgi, new_block);
 }
 
+static ir_node *gen_Start(ir_node *node)
+{
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+
+       return new_bd_TEMPLATE_Start(dbgi, new_block);
+}
+
+static ir_node *gen_Return(ir_node *node)
+{
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+       ir_node  *mem       = get_Return_mem(node);
+       ir_node  *new_mem   = be_transform_node(mem);
+       ir_graph *irg       = get_irn_irg(node);
+       ir_node  *sp        = get_irg_frame(irg);
+
+       return new_bd_TEMPLATE_Return(dbgi, new_block, sp, new_mem);
+}
+
 /**
  * returns true if mode should be stored in a general purpose register
  */
@@ -222,14 +250,8 @@ static inline bool mode_needs_gp_reg(ir_mode *mode)
 
 static ir_node *gen_Phi(ir_node *node)
 {
+       ir_mode                   *mode = get_irn_mode(node);
        const arch_register_req_t *req;
-       ir_node  *block     = get_nodes_block(node);
-       ir_node  *new_block = be_transform_node(block);
-       dbg_info *dbgi      = get_irn_dbg_info(node);
-       ir_mode  *mode      = get_irn_mode(node);
-       ir_graph *irg       = get_irn_irg(node);
-       ir_node  *phi;
-
        if (mode_needs_gp_reg(mode)) {
                mode = mode_Iu;
                req  = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].class_req;
@@ -237,36 +259,65 @@ static ir_node *gen_Phi(ir_node *node)
                req = arch_no_register_req;
        }
 
-       phi = new_ir_node(dbgi, irg, new_block, op_Phi, mode, get_irn_arity(node),
-                         get_irn_in(node)+1);
-       copy_node_attr(irg, node, phi);
-       be_duplicate_deps(node, phi);
+       return be_transform_phi(node, req);
+}
+
+static ir_node *gen_Proj_Start(ir_node *node)
+{
+       dbg_info *dbgi      = get_irn_dbg_info(node);
+       ir_node  *block     = get_nodes_block(node);
+       ir_node  *new_block = be_transform_node(block);
+       ir_node  *start     = get_Proj_pred(node);
+       ir_node  *new_start = be_transform_node(start);
+       long      pn        = get_Proj_proj(node);
+
+       switch ((pn_Start) pn) {
+       case pn_Start_X_initial_exec:
+               return new_bd_TEMPLATE_Jmp(dbgi, new_block);
+       case pn_Start_M:
+               return new_rd_Proj(dbgi, new_start, mode_M, pn_TEMPLATE_Start_M);
+       case pn_Start_T_args:
+               return new_r_Bad(get_irn_irg(block), mode_T);
+       case pn_Start_P_frame_base:
+               return new_rd_Proj(dbgi, new_start, gp_regs_mode, pn_TEMPLATE_Start_stack);
+       }
+       panic("unexpected Start proj %ld\n", pn);
+}
+
+static ir_node *gen_Proj(ir_node *node)
+{
+       ir_node *pred = get_Proj_pred(node);
 
-       arch_set_out_register_req(phi, 0, req);
-       be_enqueue_preds(node);
-       return phi;
+       switch (get_irn_opcode(pred)) {
+       case iro_Start: return gen_Proj_Start(node);
+       default:
+               panic("code selection can't handle Proj after %+F\n", pred);
+       }
 }
 
 static void TEMPLATE_register_transformers(void)
 {
        be_start_transform_setup();
 
-       be_set_transform_function(op_Add,   gen_Add);
-       be_set_transform_function(op_And,   gen_And);
-       be_set_transform_function(op_Const, gen_Const);
-       be_set_transform_function(op_Eor,   gen_Eor);
-       be_set_transform_function(op_Jmp,   gen_Jmp);
-       be_set_transform_function(op_Load,  gen_Load);
-       be_set_transform_function(op_Minus, gen_Minus);
-       be_set_transform_function(op_Mul,   gen_Mul);
-       be_set_transform_function(op_Not,   gen_Not);
-       be_set_transform_function(op_Or,    gen_Or);
-       be_set_transform_function(op_Phi,   gen_Phi);
-       be_set_transform_function(op_Quot,  gen_Quot);
-       be_set_transform_function(op_Shl,   gen_Shl);
-       be_set_transform_function(op_Shr,   gen_Shr);
-       be_set_transform_function(op_Store, gen_Store);
-       be_set_transform_function(op_Sub,   gen_Sub);
+       be_set_transform_function(op_Add,    gen_Add);
+       be_set_transform_function(op_And,    gen_And);
+       be_set_transform_function(op_Const,  gen_Const);
+       be_set_transform_function(op_Div,    gen_Div);
+       be_set_transform_function(op_Eor,    gen_Eor);
+       be_set_transform_function(op_Jmp,    gen_Jmp);
+       be_set_transform_function(op_Load,   gen_Load);
+       be_set_transform_function(op_Minus,  gen_Minus);
+       be_set_transform_function(op_Mul,    gen_Mul);
+       be_set_transform_function(op_Not,    gen_Not);
+       be_set_transform_function(op_Or,     gen_Or);
+       be_set_transform_function(op_Proj,   gen_Proj);
+       be_set_transform_function(op_Phi,    gen_Phi);
+       be_set_transform_function(op_Return, gen_Return);
+       be_set_transform_function(op_Shl,    gen_Shl);
+       be_set_transform_function(op_Shr,    gen_Shr);
+       be_set_transform_function(op_Start,  gen_Start);
+       be_set_transform_function(op_Store,  gen_Store);
+       be_set_transform_function(op_Sub,    gen_Sub);
 }
 
 /**
@@ -274,6 +325,8 @@ static void TEMPLATE_register_transformers(void)
  */
 void TEMPLATE_transform_graph(ir_graph *irg)
 {
+       gp_regs_mode = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].mode;
+
        TEMPLATE_register_transformers();
        be_transform_graph(irg, NULL);
 }