X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fsparc%2Fsparc_transform.c;h=c54bab704dcad70848b706d1eaf06e97db9998b7;hb=91f9fd8a65f0db8bcf956cfe54ac4cca394c45e8;hp=afa819f42a64b55286483b984aef27a621814a0e;hpb=0b94073dd21f4a3f013821b34d0440708daa41e2;p=libfirm diff --git a/ir/be/sparc/sparc_transform.c b/ir/be/sparc/sparc_transform.c index afa819f42..c54bab704 100644 --- a/ir/be/sparc/sparc_transform.c +++ b/ir/be/sparc/sparc_transform.c @@ -150,95 +150,6 @@ static ir_node *gen_sign_extension(dbg_info *dbgi, ir_node *block, ir_node *op, return rshift_node; } -/** - * returns true if it is assured, that the upper bits of a node are "clean" - * which means for a 16 or 8 bit value, that the upper bits in the register - * are 0 for unsigned and a copy of the last significant bit for signed - * numbers. - */ -static bool upper_bits_clean(ir_node *node, ir_mode *mode) -{ - switch ((ir_opcode)get_irn_opcode(node)) { - case iro_And: - if (!mode_is_signed(mode)) { - return upper_bits_clean(get_And_left(node), mode) - || upper_bits_clean(get_And_right(node), mode); - } - /* FALLTHROUGH */ - case iro_Or: - case iro_Eor: - return upper_bits_clean(get_binop_left(node), mode) - && upper_bits_clean(get_binop_right(node), mode); - - case iro_Shr: - if (mode_is_signed(mode)) { - return false; /* TODO */ - } else { - ir_node *right = get_Shr_right(node); - if (is_Const(right)) { - ir_tarval *tv = get_Const_tarval(right); - long val = get_tarval_long(tv); - if (val >= 32 - (long)get_mode_size_bits(mode)) - return true; - } - return upper_bits_clean(get_Shr_left(node), mode); - } - - case iro_Shrs: - return upper_bits_clean(get_Shrs_left(node), mode); - - case iro_Const: { - ir_tarval *tv = get_Const_tarval(node); - long val = get_tarval_long(tv); - if (mode_is_signed(mode)) { - long shifted = val >> (get_mode_size_bits(mode)-1); - return shifted == 0 || shifted == -1; - } else { - unsigned long shifted = (unsigned long)val; - shifted >>= get_mode_size_bits(mode)-1; - shifted >>= 1; - return shifted == 0; - } - } - - case iro_Conv: { - ir_mode *dest_mode = get_irn_mode(node); - ir_node *op = get_Conv_op(node); - ir_mode *src_mode = get_irn_mode(op); - unsigned src_bits = get_mode_size_bits(src_mode); - unsigned dest_bits = get_mode_size_bits(dest_mode); - /* downconvs are a nop */ - if (src_bits <= dest_bits) - return upper_bits_clean(op, mode); - if (dest_bits <= get_mode_size_bits(mode) - && mode_is_signed(dest_mode) == mode_is_signed(mode)) - return true; - return false; - } - - case iro_Proj: { - ir_node *pred = get_Proj_pred(node); - switch (get_irn_opcode(pred)) { - case iro_Load: { - ir_mode *load_mode = get_Load_mode(pred); - unsigned load_bits = get_mode_size_bits(load_mode); - unsigned bits = get_mode_size_bits(mode); - if (load_bits > bits) - return false; - if (mode_is_signed(mode) != mode_is_signed(load_mode)) - return false; - return true; - } - default: - break; - } - } - default: - break; - } - return false; -} - /** * Extend a value to 32 bit signed/unsigned depending on its mode. * @@ -290,9 +201,10 @@ static bool is_imm_encodeable(const ir_node *node) static bool needs_extension(ir_node *op) { ir_mode *mode = get_irn_mode(op); - if (get_mode_size_bits(mode) >= get_mode_size_bits(mode_gp)) + unsigned gp_bits = get_mode_size_bits(mode_gp); + if (get_mode_size_bits(mode) >= gp_bits) return false; - return !upper_bits_clean(op, mode); + return !be_upper_bits_clean(op, mode); } /** @@ -1451,31 +1363,20 @@ static ir_node *gen_Conv(ir_node *node) return create_itof(dbgi, block, new_op, dst_mode); } } else { /* complete in gp registers */ - int min_bits; - ir_mode *min_mode; - - if (src_bits == dst_bits || dst_mode == mode_b) { + if (src_bits >= dst_bits || dst_mode == mode_b) { /* kill unnecessary conv */ return be_transform_node(op); } - if (src_bits < dst_bits) { - min_bits = src_bits; - min_mode = src_mode; - } else { - min_bits = dst_bits; - min_mode = dst_mode; - } - - if (upper_bits_clean(op, min_mode)) { + if (be_upper_bits_clean(op, src_mode)) { return be_transform_node(op); } new_op = be_transform_node(op); - if (mode_is_signed(min_mode)) { - return gen_sign_extension(dbgi, block, new_op, min_bits); + if (mode_is_signed(src_mode)) { + return gen_sign_extension(dbgi, block, new_op, src_bits); } else { - return gen_zero_extension(dbgi, block, new_op, min_bits); + return gen_zero_extension(dbgi, block, new_op, src_bits); } } } @@ -1521,7 +1422,6 @@ static ir_node *gen_Start(ir_node *node) size_t i; /* start building list of start constraints */ - assert(obstack_object_size(obst) == 0); /* calculate number of outputs */ n_outs = 4; /* memory, g0, g7, sp */ @@ -1950,12 +1850,16 @@ static ir_node *gen_Call(ir_node *node) } assert(result_info->req1 == NULL); } + const unsigned *allocatable_regs = be_birg_from_irg(irg)->allocatable_regs; for (i = 0; i < N_SPARC_REGISTERS; ++i) { const arch_register_t *reg; if (!rbitset_is_set(cconv->caller_saves, i)) continue; reg = &sparc_registers[i]; - arch_set_irn_register_req_out(res, o++, reg->single_req); + arch_set_irn_register_req_out(res, o, reg->single_req); + if (!rbitset_is_set(allocatable_regs, reg->global_index)) + arch_set_irn_register_out(res, o, reg); + ++o; } assert(o == out_arity); @@ -2129,18 +2033,10 @@ static const arch_register_req_t *get_float_req(ir_mode *mode) } } -/** - * Transform some Phi nodes - */ static ir_node *gen_Phi(ir_node *node) { + ir_mode *mode = get_irn_mode(node); const arch_register_req_t *req; - ir_node *block = be_transform_node(get_nodes_block(node)); - ir_graph *irg = current_ir_graph; - dbg_info *dbgi = get_irn_dbg_info(node); - ir_mode *mode = get_irn_mode(node); - ir_node *phi; - if (mode_needs_gp_reg(mode)) { /* we shouldn't have any 64bit stuff around anymore */ assert(get_mode_size_bits(mode) <= 32); @@ -2153,14 +2049,7 @@ static ir_node *gen_Phi(ir_node *node) req = arch_no_register_req; } - /* phi nodes allow loops, so we use the old arguments for now - * and fix this later */ - phi = new_ir_node(dbgi, irg, 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_irn_register_req_out(phi, 0, req); - be_enqueue_preds(node); - return phi; + return be_transform_phi(node, req); } /** @@ -2223,15 +2112,6 @@ static ir_node *gen_Proj_Store(ir_node *node) panic("Unsupported Proj from Store"); } -/** - * Transform the Projs from a Cmp. - */ -static ir_node *gen_Proj_Cmp(ir_node *node) -{ - (void) node; - panic("not implemented"); -} - /** * transform Projs from a Div */ @@ -2432,8 +2312,6 @@ static ir_node *gen_Proj(ir_node *node) return gen_Proj_Load(node); case iro_Call: return gen_Proj_Call(node); - case iro_Cmp: - return gen_Proj_Cmp(node); case iro_Switch: case iro_Cond: return be_duplicate_node(node);