X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Firarch.c;h=d7d5a3514d6f96f75eba96580ed4f23bdc32066c;hb=eda9d668d0e8c8246015b4c5e743316a6a835a23;hp=7f15232ba9e6c3d0cf565b9cb97fc173739d50a5;hpb=9372d5147d6b19582b1a6ea35586630d225ae532;p=libfirm diff --git a/ir/ir/irarch.c b/ir/ir/irarch.c index 7f15232ba..d7d5a3514 100644 --- a/ir/ir/irarch.c +++ b/ir/ir/irarch.c @@ -1,12 +1,37 @@ -/** - * @file irarch.c - * @date 28.9.2004 - * @author Sebastian Hack - * @brief Machine dependent firm optimizations. +/* + * Copyright (C) 1995-2007 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. * - * $Id$ + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + +/** + * @file + * @brief Machine dependent Firm optimizations. + * @date 28.9.2004 + * @author Sebastian Hack, Michael Beck + * @version $Id$ */ -#include +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_STDLIB_H +# include +#endif + #include #include "irnode_t.h" @@ -55,22 +80,6 @@ new_rd_Mulh (dbg_info *db, ir_graph *irg, ir_node *block, ir_node *in[2]; ir_node *res; - if (! op_Mulh) { - rflct_sig_t *sig; - int mulh_opc = get_next_ir_opcode(); - - op_Mulh = new_ir_op(mulh_opc, "Mulh", op_pin_state_floats, irop_flag_commutative, oparity_binary, 0, 0); - sig = rflct_signature_allocate(1, 3); - rflct_signature_set_arg(sig, 0, 0, "Res", RFLCT_MC(Int), 0, 0); - rflct_signature_set_arg(sig, 1, 0, "Block", RFLCT_MC(BB), 0, 0); - rflct_signature_set_arg(sig, 1, 1, "Op 0", RFLCT_MC(Int), 0, 0); - rflct_signature_set_arg(sig, 1, 2, "Op 1", RFLCT_MC(Int), 0, 0); - - rflct_new_opcode(mulh_opc, "Mulh", false); - rflct_opcode_add_signature(mulh_opc, sig); - - } - in[0] = op1; in[1] = op2; res = new_ir_node(db, irg, block, op_Mulh, mode, 2, in); @@ -88,11 +97,20 @@ void arch_dep_init(arch_dep_params_factory_t factory) if (factory != NULL) params = factory(); - if (params && (opts & (arch_dep_div_by_const|arch_dep_mod_by_const))) { - if (! op_Mulh) { - /* create the Mulh operation */ - op_Mulh = new_ir_op(get_next_ir_opcode(), "Mulh", op_pin_state_floats, irop_flag_commutative, oparity_binary, 0, 0); - } + if (! op_Mulh) { + rflct_sig_t *sig; + int mulh_opc = get_next_ir_opcode(); + + /* create the Mulh operation */ + op_Mulh = new_ir_op(mulh_opc, "Mulh", op_pin_state_floats, irop_flag_commutative, oparity_binary, 0, 0, NULL); + sig = rflct_signature_allocate(1, 3); + rflct_signature_set_arg(sig, 0, 0, "Res", RFLCT_MC(Int), 0, 0); + rflct_signature_set_arg(sig, 1, 0, "Block", RFLCT_MC(BB), 0, 0); + rflct_signature_set_arg(sig, 1, 1, "Op 0", RFLCT_MC(Int), 0, 0); + rflct_signature_set_arg(sig, 1, 2, "Op 1", RFLCT_MC(Int), 0, 0); + + rflct_new_opcode(mulh_opc, "Mulh", 0); + rflct_opcode_add_signature(mulh_opc, sig); } } @@ -100,7 +118,7 @@ void arch_dep_set_opts(arch_dep_opts_t the_opts) { opts = the_opts; } -/* check, whether a mode allows a Mulh instruction */ +/** check, whether a mode allows a Mulh instruction. */ static int allow_Mulh(ir_mode *mode) { if (get_mode_size_bits(mode) > params->max_bits_for_mulh) @@ -108,6 +126,7 @@ static int allow_Mulh(ir_mode *mode) return (mode_is_signed(mode) && params->allow_mulhs) || (!mode_is_signed(mode) && params->allow_mulhu); } +/* Replace Muls with Shifts and Add/Subs. */ ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn) { ir_node *res = irn; @@ -190,7 +209,7 @@ ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn) } #endif - // Go over all recorded one groups. + /* Go over all recorded one groups. */ curr_bit = compr[0]; for(i = 1; i < compr_len; i = end_of_group + 2) { @@ -199,7 +218,7 @@ ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn) ones_in_group = compr[i]; zeros_in_group = 0; - // Scan for singular 0s in a sequence + /* Scan for singular 0s in a sequence. */ for(j = i + 1; j < compr_len && compr[j] == 1; j += 2) { zeros_in_group += 1; ones_in_group += (j + 1 < compr_len ? compr[j + 1] : 0); @@ -223,8 +242,8 @@ ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn) fprintf(stderr, " j:%d, ones:%d\n", j, curr_ones); #endif - // If this ones group is a singleton group (it has no - // singleton zeros inside + /* If this ones group is a singleton group (it has no + singleton zeros inside. */ if(singleton) shift_with_sub[shift_with_sub_pos++] = biased_curr_bit; else if(j == i) @@ -358,7 +377,7 @@ ir_node *arch_dep_replace_mul_with_shifts(ir_node *irn) */ static int tv_ld2(tarval *tv, int bits) { - int i, k, num; + int i, k = 0, num; for (num = i = 0; i < bits; ++i) { unsigned char v = get_tarval_sub_bits(tv, i); @@ -395,6 +414,7 @@ static int tv_ld2(tarval *tv, int bits) #define ONE(m) get_mode_one(m) #define ZERO(m) get_mode_null(m) +/** The result of a the magic() function. */ struct ms { tarval *M; /**< magic number */ int s; /**< shift amount */ @@ -481,6 +501,7 @@ static struct ms magic(tarval *d) return mag; } +/** The result of the magicu() function. */ struct mu { tarval *M; /**< magic add constant */ int s; /**< shift amount */ @@ -557,7 +578,7 @@ static struct mu magicu(tarval *d) } /** - * build the Mulh replacement code for n / tv + * Build the Mulh replacement code for n / tv. * * Note that 'div' might be a mod or DivMod operation as well */ @@ -633,6 +654,7 @@ static ir_node *replace_div_by_mulh(ir_node *div, tarval *tv) return q; } +/* Replace Divs with Shifts and Add/Subs and Mulh. */ ir_node *arch_dep_replace_div_by_const(ir_node *irn) { ir_node *res = irn; @@ -654,11 +676,16 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn) if (get_irn_op(c) != op_Const) return irn; + tv = get_Const_tarval(c); + + /* check for division by zero */ + if (classify_tarval(tv) == TV_CLASSIFY_NULL) + return irn; + left = get_Div_left(irn); mode = get_irn_mode(left); block = get_irn_n(irn, -1); dbg = get_irn_dbg_info(irn); - tv = get_Const_tarval(c); bits = get_mode_size_bits(mode); n = (bits + 7) / 8; @@ -716,11 +743,12 @@ ir_node *arch_dep_replace_div_by_const(ir_node *irn) } if (res != irn) - hook_arch_dep_replace_div_by_const(irn); + hook_arch_dep_replace_division_by_const(irn); return res; } +/* Replace Mods with Shifts and Add/Subs and Mulh. */ ir_node *arch_dep_replace_mod_by_const(ir_node *irn) { ir_node *res = irn; @@ -742,12 +770,16 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn) if (get_irn_op(c) != op_Const) return irn; + tv = get_Const_tarval(c); + + /* check for division by zero */ + if (classify_tarval(tv) == TV_CLASSIFY_NULL) + return irn; + left = get_Mod_left(irn); mode = get_irn_mode(left); block = get_irn_n(irn, -1); dbg = get_irn_dbg_info(irn); - tv = get_Const_tarval(c); - bits = get_mode_size_bits(mode); n = (bits + 7) / 8; @@ -807,11 +839,12 @@ ir_node *arch_dep_replace_mod_by_const(ir_node *irn) } if (res != irn) - hook_arch_dep_replace_mod_by_const(irn); + hook_arch_dep_replace_division_by_const(irn); return res; } +/* Replace DivMods with Shifts and Add/Subs and Mulh. */ void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn) { *div = *mod = NULL; @@ -834,11 +867,16 @@ void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn if (get_irn_op(c) != op_Const) return; + tv = get_Const_tarval(c); + + /* check for division by zero */ + if (classify_tarval(tv) == TV_CLASSIFY_NULL) + return; + left = get_DivMod_left(irn); mode = get_irn_mode(left); block = get_irn_n(irn, -1); dbg = get_irn_dbg_info(irn); - tv = get_Const_tarval(c); bits = get_mode_size_bits(mode); n = (bits + 7) / 8; @@ -914,7 +952,7 @@ void arch_dep_replace_divmod_by_const(ir_node **div, ir_node **mod, ir_node *irn } if (*div) - hook_arch_dep_replace_DivMod_by_const(irn); + hook_arch_dep_replace_division_by_const(irn); } @@ -928,6 +966,7 @@ static const arch_dep_params_t default_params = { 32 /* Mulh allowed up to 32 bit */ }; +/* A default parameter factory for testing purposes. */ const arch_dep_params_t *arch_dep_default_factory(void) { return &default_params; }