diff options
Diffstat (limited to 'gcc/expmed.c')
-rw-r--r-- | gcc/expmed.c | 37 |
1 files changed, 29 insertions, 8 deletions
diff --git a/gcc/expmed.c b/gcc/expmed.c index 883eff5b52b..6acc8956e26 100644 --- a/gcc/expmed.c +++ b/gcc/expmed.c @@ -2096,8 +2096,8 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, /* We'll be needing a couple extra algorithm structures now. */ - alg_in = (struct algorithm *)alloca (sizeof (struct algorithm)); - best_alg = (struct algorithm *)alloca (sizeof (struct algorithm)); + alg_in = alloca (sizeof (struct algorithm)); + best_alg = alloca (sizeof (struct algorithm)); /* If we have a group of zero bits at the low-order part of T, try multiplying by the remaining bits and then doing a shift. */ @@ -2300,7 +2300,8 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t, you should swap the two operands if OP0 would be constant. */ rtx -expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp) +expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, + int unsignedp) { rtx const_op1 = op1; @@ -2514,6 +2515,28 @@ expand_mult (enum machine_mode mode, rtx op0, rtx op1, rtx target, int unsignedp } } + if (GET_CODE (op0) == CONST_DOUBLE) + { + rtx temp = op0; + op0 = op1; + op1 = temp; + } + + /* Expand x*2.0 as x+x. */ + if (GET_CODE (op1) == CONST_DOUBLE + && GET_MODE_CLASS (mode) == MODE_FLOAT) + { + REAL_VALUE_TYPE d; + REAL_VALUE_FROM_CONST_DOUBLE (d, op1); + + if (REAL_VALUES_EQUAL (d, dconst2)) + { + op0 = force_reg (GET_MODE (op0), op0); + return expand_binop (mode, add_optab, op0, op0, + target, unsignedp, OPTAB_LIB_WIDEN); + } + } + /* This used to use umul_optab if unsigned, but for non-widening multiply there is no difference between signed and unsigned. */ op0 = expand_binop (mode, @@ -2605,7 +2628,7 @@ choose_multiplier (unsigned HOST_WIDE_INT d, int n, int precision, abort (); if (mhigh_hi > 1 || mlow_hi > 1) abort (); - /* assert that mlow < mhigh. */ + /* Assert that mlow < mhigh. */ if (! (mlow_hi < mhigh_hi || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo))) abort (); @@ -3801,7 +3824,7 @@ expand_divmod (int rem_flag, enum tree_code code, enum machine_mode mode, build_int_2 (pre_shift, 0), NULL_RTX, unsignedp); quotient = expand_mult (compute_mode, t1, gen_int_mode (ml, compute_mode), - NULL_RTX, 0); + NULL_RTX, 1); insn = get_last_insn (); set_unique_reg_note (insn, @@ -4092,12 +4115,10 @@ make_tree (tree type, rtx x) t = make_node (RTL_EXPR); TREE_TYPE (t) = type; -#ifdef POINTERS_EXTEND_UNSIGNED /* If TYPE is a POINTER_TYPE, X might be Pmode with TYPE_MODE being ptr_mode. So convert. */ - if (POINTER_TYPE_P (type) && GET_MODE (x) != TYPE_MODE (type)) + if (POINTER_TYPE_P (type)) x = convert_memory_address (TYPE_MODE (type), x); -#endif RTL_EXPR_RTL (t) = x; /* There are no insns to be output |