X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fmips%2Fmips_transform.c;h=f27380daa328af0a8d97f3dea17721a9af57c6cf;hb=c1fdf770d4d000dd5cf22daead32369342c5f5d1;hp=947c77559eb6c588eade18dd8ec63fdeb3158121;hpb=5f4a7559628fca2ee71c641e1eb14e8ee2e9c740;p=libfirm diff --git a/ir/be/mips/mips_transform.c b/ir/be/mips/mips_transform.c index 947c77559..f27380daa 100644 --- a/ir/be/mips/mips_transform.c +++ b/ir/be/mips/mips_transform.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -23,9 +23,7 @@ * @author Matthias Braun, Mehdi * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include @@ -60,9 +58,6 @@ #include "gen_mips_regalloc_if.h" -/** hold the current code generator during transformation */ -static mips_code_gen_t *env_cg = NULL; - /**************************************************************************************************** * _ _ __ _ _ * | | | | / _| | | (_) @@ -77,8 +72,7 @@ typedef ir_node *construct_binop_func(dbg_info *db, ir_graph *irg, ir_node *block, ir_node *left, ir_node *right); static INLINE int mode_needs_gp_reg(ir_mode *mode) { - return mode_is_int(mode) || mode_is_character(mode) - || mode_is_reference(mode); + return mode_is_int(mode) || mode_is_reference(mode); } ir_node *mips_create_Immediate(long val) @@ -125,8 +119,6 @@ static ir_node *try_create_Immediate(ir_node *node) tv = get_Const_tarval(node); if(tarval_is_long(tv)) { val = get_tarval_long(tv); - } else if(tarval_is_null(tv)) { - val = 0; } else { ir_fprintf(stderr, "Optimisation Warning: tarval %+F is not a long?\n", node); @@ -307,10 +299,8 @@ static ir_node* gen_Const(ir_node *node) if(tarval_is_long(tv)) { val = get_tarval_long(tv); - } else if(tarval_is_null(tv)) { - val = 0; } else { - panic("Can't get value of tarval %+F\n", node); + panic("Can't get value of tarval %+F", node); } val = get_tarval_long(tv); @@ -339,6 +329,7 @@ static ir_node* gen_SymConst(ir_node *node) dbg_info *dbgi = get_irn_dbg_info(node); ir_node *block = be_transform_node(get_nodes_block(node)); ir_entity *entity; + const arch_register_t **slots; ir_node *lui, *or_const, *or; if(get_SymConst_kind(node) != symconst_addr_ent) { @@ -353,6 +344,9 @@ static ir_node* gen_SymConst(ir_node *node) MIPS_IMM_SYMCONST_LO, entity, 0); or = new_rd_mips_or(dbgi, irg, block, lui, or_const); + slots = get_mips_slots(or_const); + slots[0] = &mips_gp_regs[REG_GP_NOREG]; + return or; } @@ -504,7 +498,7 @@ static ir_node *gen_Proj_DivMod(ir_node *node) break; } - panic("invalid proj attached to %+F\n", divmod); + panic("invalid proj attached to %+F", divmod); } static ir_node *gen_Proj_Start(ir_node *node) @@ -519,7 +513,7 @@ static ir_node *gen_Proj_Start(ir_node *node) ir_node *jump = new_rd_Jmp(dbgi, irg, block); return jump; } - if(node == be_get_old_anchor(anchor_tls)) { + if(node == get_irg_anchor(irg, anchor_tls)) { /* TODO... */ return be_duplicate_node(node); } @@ -580,7 +574,6 @@ static ir_node *gen_Phi(ir_node *node) copy_node_attr(node, phi); be_duplicate_deps(node, phi); - be_set_transformed_node(node, phi); be_enqueue_preds(node); return phi; @@ -780,7 +773,7 @@ static ir_node *gen_Conv(ir_node *node) } else if(src_size == 16) { res = new_rd_mips_seh(dbgi, irg, block, new_op); } else { - panic("invalid conv %+F\n", node); + panic("invalid conv %+F", node); } } else { ir_node *and_const; @@ -790,7 +783,7 @@ static ir_node *gen_Conv(ir_node *node) } else if(src_size == 16) { and_const = mips_create_Immediate(0xffff); } else { - panic("invalid conv %+F\n", node); + panic("invalid conv %+F", node); } res = new_rd_mips_and(dbgi, irg, block, new_op, and_const); } @@ -1040,7 +1033,7 @@ static void mips_fix_CopyB_Proj(mips_transform_env_t* env) { long n = get_Proj_proj(node); if(n == pn_CopyB_M_except) { - assert(0); + panic("Unsupported Proj from CopyB"); } else if(n == pn_CopyB_M_regular) { set_Proj_proj(node, pn_Store_M); } else if(n == pn_CopyB_M_except) { @@ -1097,33 +1090,12 @@ static void mips_transform_Reload(mips_transform_env_t* env) { } /* copy the register from the old node to the new Load */ - reg = arch_get_irn_register(env->cg->arch_env, node); - arch_set_irn_register(env->cg->arch_env, proj, reg); + reg = arch_get_irn_register(node); + arch_set_irn_register(proj, reg); exchange(node, proj); } -#if 0 -static ir_node *gen_node_for_StackParam(mips_transform_env_t *env) -{ - ir_node *node = env->irn; - ir_node *sp = get_irn_n(node, 0); - ir_node *load; - ir_node *nomem = new_rd_NoMem(env->irg); - ir_node *proj; - mips_attr_t *attr; - - load = new_rd_mips_load_r(env->dbg, env->irg, env->block, nomem, sp, mode_T); - attr = get_mips_attr(load); - attr->stack_entity = be_get_frame_entity(node); - attr->modes.load_store_mode = env->mode; - - proj = new_rd_Proj(env->dbg, env->irg, env->block, load, env->mode, pn_Load_res); - - return proj; -} -#endif - #if 0 static ir_node *gen_AddSP(ir_node *node) { @@ -1138,8 +1110,8 @@ static ir_node *gen_AddSP(ir_node *node) add = new_rd_mips_addu(env->dbg, env->irg, env->block, op1, op2); /* copy the register requirements from the old node to the new node */ - reg = arch_get_irn_register(env->cg->arch_env, node); - arch_set_irn_register(env->cg->arch_env, add, reg); + reg = arch_get_irn_register(node); + arch_set_irn_register(add, reg); return add; } @@ -1155,213 +1127,47 @@ static ir_node *gen_AddSP(ir_node *node) * *********************************************************/ -static ir_node *gen_Bad(ir_node *node) +typedef ir_node *(*mips_transform_func) (ir_node *node); + +static void register_transformer(ir_op *op, mips_transform_func func) { - panic("Unexpected node %+F found in mips transform phase.\n", node); - return NULL; + assert(op->ops.generic == NULL); + op->ops.generic = (op_func) func; } static void register_transformers(void) { clear_irp_opcodes_generic_func(); - op_Add->ops.generic = (op_func) gen_Add; - op_Sub->ops.generic = (op_func) gen_Sub; - op_And->ops.generic = (op_func) gen_And; - op_Or->ops.generic = (op_func) gen_Or; - op_Eor->ops.generic = (op_func) gen_Eor; - op_Shl->ops.generic = (op_func) gen_Shl; - op_Shr->ops.generic = (op_func) gen_Shr; - op_Shrs->ops.generic = (op_func) gen_Shrs; - op_Not->ops.generic = (op_func) gen_Not; - op_Minus->ops.generic = (op_func) gen_Minus; - op_Div->ops.generic = (op_func) gen_Div; - op_Mod->ops.generic = (op_func) gen_Mod; - op_DivMod->ops.generic = (op_func) gen_DivMod; - op_Abs->ops.generic = (op_func) gen_Abs; - op_Load->ops.generic = (op_func) gen_Load; - op_Store->ops.generic = (op_func) gen_Store; - op_Cond->ops.generic = (op_func) gen_Cond; - op_Conv->ops.generic = (op_func) gen_Conv; - op_Const->ops.generic = (op_func) gen_Const; - op_SymConst->ops.generic = (op_func) gen_SymConst; - op_Unknown->ops.generic = (op_func) gen_Unknown; - op_Proj->ops.generic = (op_func) gen_Proj; - op_Phi->ops.generic = (op_func) gen_Phi; - - op_Raise->ops.generic = (op_func) gen_Bad; - op_Sel->ops.generic = (op_func) gen_Bad; - op_InstOf->ops.generic = (op_func) gen_Bad; - op_Cast->ops.generic = (op_func) gen_Bad; - op_Free->ops.generic = (op_func) gen_Bad; - op_Tuple->ops.generic = (op_func) gen_Bad; - op_Id->ops.generic = (op_func) gen_Bad; - op_Confirm->ops.generic = (op_func) gen_Bad; - op_Filter->ops.generic = (op_func) gen_Bad; - op_CallBegin->ops.generic = (op_func) gen_Bad; - op_EndReg->ops.generic = (op_func) gen_Bad; - op_EndExcept->ops.generic = (op_func) gen_Bad; + register_transformer(op_Add, gen_Add); + register_transformer(op_Sub, gen_Sub); + register_transformer(op_And, gen_And); + register_transformer(op_Or, gen_Or); + register_transformer(op_Eor, gen_Eor); + register_transformer(op_Shl, gen_Shl); + register_transformer(op_Shr, gen_Shr); + register_transformer(op_Shrs, gen_Shrs); + register_transformer(op_Not, gen_Not); + register_transformer(op_Minus, gen_Minus); + register_transformer(op_Div, gen_Div); + register_transformer(op_Mod, gen_Mod); + register_transformer(op_DivMod, gen_DivMod); + register_transformer(op_Abs, gen_Abs); + register_transformer(op_Load, gen_Load); + register_transformer(op_Store, gen_Store); + register_transformer(op_Cond, gen_Cond); + register_transformer(op_Conv, gen_Conv); + register_transformer(op_Const, gen_Const); + register_transformer(op_SymConst, gen_SymConst); + register_transformer(op_Unknown, gen_Unknown); + register_transformer(op_Proj, gen_Proj); + register_transformer(op_Phi, gen_Phi); } -#if 0 -/** - * Transforms the given firm node (and maybe some other related nodes) - * into one or more assembler nodes. - * - * @param node the firm node - * @param env the debug module - */ -void mips_transform_node(ir_node *node, void *env) { - mips_code_gen_t *cgenv = (mips_code_gen_t *)env; - ir_opcode code = get_irn_opcode(node); - ir_node *asm_node = node; - mips_transform_env_t tenv; - - if (is_Block(node)) - return; - - tenv.block = get_nodes_block(node); - tenv.dbg = get_irn_dbg_info(node); - tenv.irg = current_ir_graph; - tenv.irn = node; - tenv.mode = get_irn_mode(node); - tenv.cg = cgenv; - -#define UNOP(firm_opcode, mips_nodetype) case iro_##firm_opcode: asm_node = mips_gen_##mips_nodetype(&tenv, get_##firm_opcode##_op(node)); break -#define BINOP(firm_opcode, mips_nodetype) case iro_##firm_opcode: asm_node = mips_gen_##mips_nodetype(&tenv, get_##firm_opcode##_left(node), get_##firm_opcode##_right(node)); break -#define IGN(a) case iro_##a: break -#define BAD(a) case iro_##a: goto bad - - switch (code) { - BINOP(Add, addu); - BINOP(Sub, sub); - BINOP(And, and); - BINOP(Or, or); - BINOP(Eor, xor); - UNOP(Not, not); - BINOP(Shl, sl); - BINOP(Shr, sr); - BINOP(Shrs, sra); - - case iro_Abs: - asm_node = gen_node_for_Abs(&tenv); - break; - - case iro_Rot: - asm_node = gen_node_for_Rot(&tenv); - break; - - case iro_Div: - asm_node = gen_node_for_Div(&tenv); - break; - - case iro_Mod: - asm_node = gen_node_for_Mod(&tenv); - break; - - case iro_Load: - asm_node = gen_node_for_Load(&tenv); - break; - - case iro_Store: - asm_node = gen_node_for_Store(&tenv); - break; - - case iro_Proj: - asm_node = gen_node_for_Proj(&tenv); - break; - - case iro_Conv: - asm_node = gen_node_for_Conv(&tenv); - break; - - case iro_DivMod: - asm_node = gen_node_for_DivMod(&tenv); - break; - - case iro_Mul: - asm_node = gen_node_for_Mul(&tenv); - break; - - case iro_Jmp: - asm_node = gen_node_for_Jmp(&tenv); - break; - - case iro_IJmp: - asm_node = gen_node_for_IJmp(&tenv); - break; - - case iro_Unknown: - asm_node = gen_node_for_Unknown(&tenv); - break; - - case iro_Cond: - asm_node = gen_node_for_Cond(&tenv); - break; - - case iro_Phi: - asm_node = gen_node_for_Phi(&tenv); - break; - - /* TODO: implement these nodes */ - BAD(Mux); - - /* You probably don't need to handle the following nodes */ - - // call is handled in the emit phase - IGN(Call); - // Cmp is handled together with Cond - IGN(Cmp); - IGN(Alloc); - - IGN(Block); - IGN(Start); - IGN(End); - IGN(NoMem); - IGN(Break); - IGN(Sync); - - IGN(Const); - IGN(SymConst); - - BAD(Raise); - BAD(Sel); - BAD(InstOf); - BAD(Cast); - BAD(Free); - BAD(Tuple); - BAD(Id); - BAD(Bad); - BAD(Confirm); - BAD(Filter); - BAD(CallBegin); - BAD(EndReg); - BAD(EndExcept); - - default: - if(be_is_StackParam(node)) { - //asm_node = gen_node_for_StackParam(&tenv); - } else if(be_is_AddSP(node)) { - asm_node = gen_node_for_AddSP(&tenv); - } - break; - -bad: - fprintf(stderr, "Not implemented: %s\n", get_irn_opname(node)); - assert(0); - } - - if (asm_node != node) { - exchange(node, asm_node); - } -} -#endif - void mips_transform_graph(mips_code_gen_t *cg) { - env_cg = cg; register_transformers(); - be_transform_graph(cg->birg, NULL, cg); + be_transform_graph(cg->birg, NULL); } /**