diff options
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/expmed.c | 59 |
2 files changed, 44 insertions, 25 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eb0b34f..9f0bc0f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2005-11-28 Roger Sayle <roger@eyesopen.com> + + * expmed.c (div_cost): Replace with... + (sdiv_cost, udiv_cost): New. + (init_expmed): Initialize sdiv_cost and udiv_cost, not div_cost. + Rename the div and mod fields, used to initialize sdiv_pow2_cheap + and smod_pow2_cheap, to sdiv_32 and smod_32 to avoid confusion. + (expand_divmod): Replace use of div_cost with either sdiv_cost + or udiv_cost depending upon the signedness of the operation. + 2005-11-28 Alexandre Oliva <aoliva@redhat.com> PR libfortran/24991 diff --git a/gcc/expmed.c b/gcc/expmed.c index ec2758e..28f876b 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -103,7 +103,8 @@ static int shift_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; static int shiftadd_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; static int shiftsub_cost[NUM_MACHINE_MODES][MAX_BITS_PER_WORD]; static int mul_cost[NUM_MACHINE_MODES]; -static int div_cost[NUM_MACHINE_MODES]; +static int sdiv_cost[NUM_MACHINE_MODES]; +static int udiv_cost[NUM_MACHINE_MODES]; static int mul_widen_cost[NUM_MACHINE_MODES]; static int mul_highpart_cost[NUM_MACHINE_MODES]; @@ -115,11 +116,12 @@ init_expmed (void) struct rtx_def reg; rtunion reg_fld[2]; struct rtx_def plus; rtunion plus_fld1; struct rtx_def neg; - struct rtx_def udiv; rtunion udiv_fld1; struct rtx_def mult; rtunion mult_fld1; - struct rtx_def div; rtunion div_fld1; - struct rtx_def mod; rtunion mod_fld1; + struct rtx_def sdiv; rtunion sdiv_fld1; + struct rtx_def udiv; rtunion udiv_fld1; struct rtx_def zext; + struct rtx_def sdiv_32; rtunion sdiv_32_fld1; + struct rtx_def smod_32; rtunion smod_32_fld1; struct rtx_def wide_mult; rtunion wide_mult_fld1; struct rtx_def wide_lshr; rtunion wide_lshr_fld1; struct rtx_def wide_trunc; @@ -155,21 +157,25 @@ init_expmed (void) PUT_CODE (&all.neg, NEG); XEXP (&all.neg, 0) = &all.reg; - PUT_CODE (&all.udiv, UDIV); - XEXP (&all.udiv, 0) = &all.reg; - XEXP (&all.udiv, 1) = &all.reg; - PUT_CODE (&all.mult, MULT); XEXP (&all.mult, 0) = &all.reg; XEXP (&all.mult, 1) = &all.reg; - PUT_CODE (&all.div, DIV); - XEXP (&all.div, 0) = &all.reg; - XEXP (&all.div, 1) = 32 < MAX_BITS_PER_WORD ? cint[32] : GEN_INT (32); + PUT_CODE (&all.sdiv, DIV); + XEXP (&all.sdiv, 0) = &all.reg; + XEXP (&all.sdiv, 1) = &all.reg; - PUT_CODE (&all.mod, MOD); - XEXP (&all.mod, 0) = &all.reg; - XEXP (&all.mod, 1) = XEXP (&all.div, 1); + PUT_CODE (&all.udiv, UDIV); + XEXP (&all.udiv, 0) = &all.reg; + XEXP (&all.udiv, 1) = &all.reg; + + PUT_CODE (&all.sdiv_32, DIV); + XEXP (&all.sdiv_32, 0) = &all.reg; + XEXP (&all.sdiv_32, 1) = 32 < MAX_BITS_PER_WORD ? cint[32] : GEN_INT (32); + + PUT_CODE (&all.smod_32, MOD); + XEXP (&all.smod_32, 0) = &all.reg; + XEXP (&all.smod_32, 1) = XEXP (&all.sdiv_32, 1); PUT_CODE (&all.zext, ZERO_EXTEND); XEXP (&all.zext, 0) = &all.reg; @@ -205,10 +211,11 @@ init_expmed (void) PUT_MODE (&all.reg, mode); PUT_MODE (&all.plus, mode); PUT_MODE (&all.neg, mode); - PUT_MODE (&all.udiv, mode); PUT_MODE (&all.mult, mode); - PUT_MODE (&all.div, mode); - PUT_MODE (&all.mod, mode); + PUT_MODE (&all.sdiv, mode); + PUT_MODE (&all.udiv, mode); + PUT_MODE (&all.sdiv_32, mode); + PUT_MODE (&all.smod_32, mode); PUT_MODE (&all.wide_trunc, mode); PUT_MODE (&all.shift, mode); PUT_MODE (&all.shift_mult, mode); @@ -217,11 +224,14 @@ init_expmed (void) add_cost[mode] = rtx_cost (&all.plus, SET); neg_cost[mode] = rtx_cost (&all.neg, SET); - div_cost[mode] = rtx_cost (&all.udiv, SET); mul_cost[mode] = rtx_cost (&all.mult, SET); + sdiv_cost[mode] = rtx_cost (&all.sdiv, SET); + udiv_cost[mode] = rtx_cost (&all.udiv, SET); - sdiv_pow2_cheap[mode] = (rtx_cost (&all.div, SET) <= 2 * add_cost[mode]); - smod_pow2_cheap[mode] = (rtx_cost (&all.mod, SET) <= 4 * add_cost[mode]); + sdiv_pow2_cheap[mode] = (rtx_cost (&all.sdiv_32, SET) + <= 2 * add_cost[mode]); + smod_pow2_cheap[mode] = (rtx_cost (&all.smod_32, SET) + <= 4 * add_cost[mode]); wider_mode = GET_MODE_WIDER_MODE (mode); if (wider_mode != VOIDmode) @@ -3911,11 +3921,10 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, /* Only deduct something for a REM if the last divide done was for a different constant. Then set the constant of the last divide. */ - max_cost = div_cost[compute_mode] - - (rem_flag && ! (last_div_const != 0 && op1_is_constant - && INTVAL (op1) == last_div_const) - ? mul_cost[compute_mode] + add_cost[compute_mode] - : 0); + max_cost = unsignedp ? udiv_cost[compute_mode] : sdiv_cost[compute_mode]; + if (rem_flag && ! (last_div_const != 0 && op1_is_constant + && INTVAL (op1) == last_div_const)) + max_cost -= mul_cost[compute_mode] + add_cost[compute_mode]; last_div_const = ! rem_flag && op1_is_constant ? INTVAL (op1) : 0; |