besched: Add and use sched_replace().
[libfirm] / ir / be / TEMPLATE / TEMPLATE_transform.c
index 72996fa..7a8b7e0 100644 (file)
@@ -20,7 +20,6 @@
 /**
  * @file
  * @brief   code selection (transform FIRM into TEMPLATE FIRM)
- * @version $Id$
  */
 #include "config.h"
 
 #include "irmode_t.h"
 #include "irgmod.h"
 #include "iredges.h"
-#include "irvrfy.h"
 #include "ircons.h"
 #include "iropt_t.h"
 #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"
@@ -50,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);
@@ -78,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);
 }
 
@@ -154,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;
 }
 
@@ -213,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
  */
@@ -223,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;
@@ -238,80 +259,76 @@ 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);
-
-       arch_set_out_register_req(phi, 0, req);
-       be_enqueue_preds(node);
-       return phi;
+       return be_transform_phi(node, req);
 }
 
-static ir_node *bad_transform(ir_node *node)
+static ir_node *gen_Proj_Start(ir_node *node)
 {
-       panic("TEMPLATE backend: unexpected node %+F", 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 void set_transformer(ir_op *op, be_transform_func transform_func)
+static ir_node *gen_Proj(ir_node *node)
 {
-       op->ops.generic = (op_func)transform_func;
+       ir_node *pred = get_Proj_pred(node);
+
+       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)
 {
-       /* first clear the generic function pointer for all ops */
-       clear_irp_opcodes_generic_func();
-
-       set_transformer(op_Add,       gen_Add);
-       set_transformer(op_And,       gen_And);
-       set_transformer(op_Const,     gen_Const);
-       set_transformer(op_Eor,       gen_Eor);
-       set_transformer(op_Jmp,       gen_Jmp);
-       set_transformer(op_Load,      gen_Load);
-       set_transformer(op_Minus,     gen_Minus);
-       set_transformer(op_Mul,       gen_Mul);
-       set_transformer(op_Not,       gen_Not);
-       set_transformer(op_Or,        gen_Or);
-       set_transformer(op_Phi,       gen_Phi);
-       set_transformer(op_Quot,      gen_Quot);
-       set_transformer(op_Shl,       gen_Shl);
-       set_transformer(op_Shr,       gen_Shr);
-       set_transformer(op_Store,     gen_Store);
-       set_transformer(op_Sub,       gen_Sub);
-
-       /* TODO: implement missing nodes */
-
-
-       /* you should not see the following nodes */
-       set_transformer(op_ASM,       bad_transform);
-       set_transformer(op_Builtin,   bad_transform);
-       set_transformer(op_CallBegin, bad_transform);
-       set_transformer(op_Cast,      bad_transform);
-       set_transformer(op_Confirm,   bad_transform);
-       set_transformer(op_DivMod,    bad_transform);
-       set_transformer(op_EndExcept, bad_transform);
-       set_transformer(op_EndReg,    bad_transform);
-       set_transformer(op_Filter,    bad_transform);
-       set_transformer(op_Free,      bad_transform);
-       set_transformer(op_Id,        bad_transform);
-       set_transformer(op_InstOf,    bad_transform);
-       set_transformer(op_Mulh,      bad_transform);
-       set_transformer(op_Mux,       bad_transform);
-       set_transformer(op_Raise,     bad_transform);
-       set_transformer(op_Sel,       bad_transform);
-       set_transformer(op_Tuple,     bad_transform);
+       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_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);
 }
 
 /**
  * Transform generic IR-nodes into TEMPLATE machine instructions
  */
-void TEMPLATE_transform_graph(TEMPLATE_code_gen_t *cg)
+void TEMPLATE_transform_graph(ir_graph *irg)
 {
+       gp_regs_mode = TEMPLATE_reg_classes[CLASS_TEMPLATE_gp].mode;
+
        TEMPLATE_register_transformers();
-       be_transform_graph(cg->irg, NULL);
+       be_transform_graph(irg, NULL);
 }
 
 void TEMPLATE_init_transform(void)