X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Flower%2Flower_dw.c;h=a0cd50f2a58b14cfbb4ceb1fe17ee3a7d8329b33;hb=9e32caf2e94f99e6d057b69e5b8384e26de2e785;hp=cd42ecbc14932df62cabeae69233f31c185f3375;hpb=492fde34e04d04a03994f006b468688c062935c6;p=libfirm diff --git a/ir/lower/lower_dw.c b/ir/lower/lower_dw.c index cd42ecbc1..a0cd50f2a 100644 --- a/ir/lower/lower_dw.c +++ b/ir/lower/lower_dw.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. * @@ -288,7 +288,7 @@ static void prepare_links(ir_node *node, void *env) lenv->entries[get_irn_idx(node)] = link; lenv->flags |= MUST_BE_LOWERED; - } else if (get_irn_op(node) == op_Conv) { + } else if (is_Conv(node)) { /* Conv nodes have two modes */ ir_node *pred = get_Conv_op(node); mode = get_irn_mode(pred); @@ -525,7 +525,7 @@ static ir_node *get_intrinsic_address(ir_type *method, ir_op *op, ent = entry->ent; } /* if */ sym.entity_p = ent; - return new_r_SymConst(current_ir_graph, block, sym, symconst_addr_ent); + return new_r_SymConst(current_ir_graph, block, mode_P_code, sym, symconst_addr_ent); } /* get_intrinsic_address */ /** @@ -915,7 +915,7 @@ static void lower_Shr(ir_node *node, ir_mode *mode, lower_env_t *env) { tarval *tv = get_Const_tarval(right); if (tarval_is_long(tv) && - get_tarval_long(tv) >= get_mode_size_bits(mode)) { + get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) { ir_node *block = get_nodes_block(node); ir_node *left = get_Shr_left(node); ir_node *c; @@ -950,14 +950,15 @@ static void lower_Shl(ir_node *node, ir_mode *mode, lower_env_t *env) { tarval *tv = get_Const_tarval(right); if (tarval_is_long(tv) && - get_tarval_long(tv) >= get_mode_size_bits(mode)) { + get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) { + ir_mode *mode_l; ir_node *block = get_nodes_block(node); ir_node *left = get_Shl_left(node); ir_node *c; long shf_cnt = get_tarval_long(tv) - get_mode_size_bits(mode); int idx = get_irn_idx(left); - left = env->entries[idx]->low_word; + left = new_r_Conv(irg, block, env->entries[idx]->low_word, mode); idx = get_irn_idx(node); if (shf_cnt > 0) { @@ -966,7 +967,8 @@ static void lower_Shl(ir_node *node, ir_mode *mode, lower_env_t *env) { } else { env->entries[idx]->high_word = left; } /* if */ - env->entries[idx]->low_word = new_r_Const(irg, block, mode, get_mode_null(mode)); + mode_l = env->params->low_unsigned; + env->entries[idx]->low_word = new_r_Const(irg, block, mode_l, get_mode_null(mode_l)); return; } /* if */ @@ -985,7 +987,7 @@ static void lower_Shrs(ir_node *node, ir_mode *mode, lower_env_t *env) { tarval *tv = get_Const_tarval(right); if (tarval_is_long(tv) && - get_tarval_long(tv) >= get_mode_size_bits(mode)) { + get_tarval_long(tv) >= (int) get_mode_size_bits(mode)) { ir_node *block = get_nodes_block(node); ir_node *left = get_Shrs_left(node); long shf_cnt = get_tarval_long(tv) - get_mode_size_bits(mode); @@ -1020,7 +1022,7 @@ static void lower_Rot(ir_node *node, ir_mode *mode, lower_env_t *env) { tarval *tv = get_Const_tarval(right); if (tarval_is_long(tv) && - get_tarval_long(tv) == get_mode_size_bits(mode)) { + get_tarval_long(tv) == (int) get_mode_size_bits(mode)) { ir_node *left = get_Rot_left(node); ir_node *h, *l; int idx = get_irn_idx(left); @@ -1242,13 +1244,28 @@ static void lower_Cond(ir_node *node, ir_mode *mode, lower_env_t *env) { assert(projT && projF); /* create a new high compare */ - block = get_nodes_block(cmp); + block = get_nodes_block(node); dbg = get_irn_dbg_info(cmp); irg = current_ir_graph; + pnc = get_Proj_proj(sel); + + if (is_Const(right) && is_Const_null(right)) { + if (pnc == pn_Cmp_Eq || pnc == pn_Cmp_Lg) { + /* x ==/!= 0 ==> or(low,high) ==/!= 0 */ + ir_mode *mode = env->params->low_unsigned; + ir_node *low = new_r_Conv(irg, block, lentry->low_word, mode); + ir_node *high = new_r_Conv(irg, block, lentry->high_word, mode); + ir_node *or = new_rd_Or(dbg, irg, block, low, high, mode); + ir_node *cmp = new_rd_Cmp(dbg, irg, block, or, new_Const_long(mode, 0)); + + ir_node *proj = new_r_Proj(irg, block, cmp, mode_b, pnc); + set_Cond_selector(node, proj); + return; + } + } cmpH = new_rd_Cmp(dbg, irg, block, lentry->high_word, rentry->high_word); - pnc = get_Proj_proj(sel); if (pnc == pn_Cmp_Eq) { /* simple case:a == b <==> a_h == b_h && a_l == b_l */ pmap_entry *entry = pmap_find(env->proj_2_block, projF); @@ -1428,7 +1445,8 @@ static void lower_Conv_to_Ls(ir_node *node, lower_env_t *env) { env->entries[idx]->low_word = op; if (mode_is_signed(imode)) { - env->entries[idx]->high_word = new_rd_Shrs(dbg, irg, block, op, + ir_node *op_conv = new_rd_Conv(dbg, irg, block, op, dst_mode_h); + env->entries[idx]->high_word = new_rd_Shrs(dbg, irg, block, op_conv, new_Const_long(mode_Iu, get_mode_size_bits(dst_mode_h) - 1), dst_mode_h); } else { env->entries[idx]->high_word = new_Const(dst_mode_h, get_mode_null(dst_mode_h)); @@ -1995,10 +2013,11 @@ static void lower_Call(ir_node *node, ir_mode *mode, lower_env_t *env) { * Translate an Unknown into two. */ static void lower_Unknown(ir_node *node, ir_mode *mode, lower_env_t *env) { - int idx = get_irn_idx(node); + int idx = get_irn_idx(node); ir_graph *irg = current_ir_graph; + ir_mode *low_mode = env->params->low_unsigned; - env->entries[idx]->low_word = + env->entries[idx]->low_word = new_r_Unknown(irg, low_mode); env->entries[idx]->high_word = new_r_Unknown(irg, mode); } /* lower_Unknown */ @@ -2010,9 +2029,7 @@ static void lower_Unknown(ir_node *node, ir_mode *mode, lower_env_t *env) { static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) { ir_mode *mode_l = env->params->low_unsigned; ir_graph *irg = current_ir_graph; - ir_node *block; - ir_node *unk_l; - ir_node *unk_h; + ir_node *block, *unk_l, *unk_h, *phi_l, *phi_h; ir_node **inl, **inh; dbg_info *dbg; int idx, i, arity = get_Phi_n_preds(phi); @@ -2064,8 +2081,13 @@ static void lower_Phi(ir_node *phi, ir_mode *mode, lower_env_t *env) { idx = get_irn_idx(phi); assert(idx < env->n_entries); - env->entries[idx]->low_word = new_rd_Phi(dbg, irg, block, arity, inl, mode_l); - env->entries[idx]->high_word = new_rd_Phi(dbg, irg, block, arity, inh, mode); + env->entries[idx]->low_word = phi_l = new_rd_Phi(dbg, irg, block, arity, inl, mode_l); + env->entries[idx]->high_word = phi_h = new_rd_Phi(dbg, irg, block, arity, inh, mode); + + /* Don't forget to link the new Phi nodes into the block! */ + set_irn_link(phi_l, get_irn_link(block)); + set_irn_link(phi_h, phi_l); + set_irn_link(block, phi_h); if (enq) { /* not yet finished */ @@ -2220,7 +2242,7 @@ static void lower_ops(ir_node *node, void *env) int idx = get_irn_idx(node); ir_mode *mode = get_irn_mode(node); - if (mode == mode_b || get_irn_op(node) == op_Psi) { + if (mode == mode_b || is_Psi(node)) { int i; for (i = get_irn_arity(node) - 1; i >= 0; --i) { @@ -2292,6 +2314,13 @@ static int cmp_conv_tp(const void *elt, const void *key, size_t size) { return (e1->imode - e2->imode) | (e1->omode - e2->omode); } /* static int cmp_conv_tp */ +/** + * Enter a lowering function into an ir_op. + */ +static void enter_lower_func(ir_op *op, lower_func func) { + op->ops.generic = (op_func)func; +} + /* * Do the lowering. */ @@ -2388,7 +2417,7 @@ void lower_dw_ops(const lwrdw_param_t *param) /* first clear the generic function pointer for all ops */ clear_irp_opcodes_generic_func(); -#define LOWER2(op, fkt) op_##op->ops.generic = (op_func)fkt +#define LOWER2(op, fkt) enter_lower_func(op_##op, fkt) #define LOWER(op) LOWER2(op, lower_##op) #define LOWER_BIN(op) LOWER2(op, lower_Binop) #define LOWER_UN(op) LOWER2(op, lower_Unop)