X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2FTEMPLATE%2FTEMPLATE_transform.c;h=7a8b7e02e26f077407a68de4c721c27eacdb4aaa;hb=81191be9419f49c1338f460dd7cd180197aa46d5;hp=f88973dbfed260554c0f18d6c8fa672ca8f5754a;hpb=ad9464a5db0b98cb926aae609abe84db70b74291;p=libfirm diff --git a/ir/be/TEMPLATE/TEMPLATE_transform.c b/ir/be/TEMPLATE/TEMPLATE_transform.c index f88973dbf..7a8b7e02e 100644 --- a/ir/be/TEMPLATE/TEMPLATE_transform.c +++ b/ir/be/TEMPLATE/TEMPLATE_transform.c @@ -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); }