diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2017-08-30 11:20:19 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2017-08-30 11:20:19 +0000 |
commit | 16d2200070f49ed71053b81699e37bd539a0ee69 (patch) | |
tree | c89eef6816d81c30d7695888167b3345c11aae26 /gcc/optabs.c | |
parent | f4f6058097d99812ee3eda98d09c23fccdc7ba94 (diff) | |
download | gcc-16d2200070f49ed71053b81699e37bd539a0ee69.zip gcc-16d2200070f49ed71053b81699e37bd539a0ee69.tar.gz gcc-16d2200070f49ed71053b81699e37bd539a0ee69.tar.bz2 |
[71/77] Use opt_scalar_mode for mode iterators
This patch uses opt_scalar_mode when iterating over scalar modes.
2017-08-30 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* coretypes.h (opt_scalar_mode): New typedef.
* gdbhooks.py (build_pretty_printers): Handle it.
* machmode.h (mode_iterator::get_2xwider): Add overload for
opt_mode<T>.
* emit-rtl.c (init_emit_once): Use opt_scalar_mode when iterating
over scalar modes.
* expr.c (convert_mode_scalar): Likewise.
* omp-low.c (omp_clause_aligned_alignment): Likewise.
* optabs.c (expand_float): Likewise.
(expand_fix): Likewise.
* tree-vect-stmts.c (vectorizable_conversion): Likewise.
gcc/c-family/
* c-common.c (c_common_fixed_point_type_for_size): Use opt_scalar_mode
for the mode iterator.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r251522
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r-- | gcc/optabs.c | 137 |
1 files changed, 73 insertions, 64 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c index d3ceaba..d30e4c6 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -4692,6 +4692,7 @@ expand_float (rtx to, rtx from, int unsignedp) && is_a <scalar_mode> (GET_MODE (to), &to_mode) && is_a <scalar_mode> (GET_MODE (from), &from_mode)) { + opt_scalar_mode fmode_iter; rtx_code_label *label = gen_label_rtx (); rtx temp; REAL_VALUE_TYPE offset; @@ -4700,12 +4701,15 @@ expand_float (rtx to, rtx from, int unsignedp) least as wide as the target. Using FMODE will avoid rounding woes with unsigned values greater than the signed maximum value. */ - FOR_EACH_MODE_FROM (fmode, to_mode) - if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode) - && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing) - break; + FOR_EACH_MODE_FROM (fmode_iter, to_mode) + { + scalar_mode fmode = fmode_iter.require (); + if (GET_MODE_PRECISION (from_mode) < GET_MODE_BITSIZE (fmode) + && can_float_p (fmode, from_mode, 0) != CODE_FOR_nothing) + break; + } - if (fmode == VOIDmode) + if (!fmode_iter.exists (&fmode)) { /* There is no such mode. Pretend the target is wide enough. */ fmode = to_mode; @@ -4840,6 +4844,7 @@ expand_fix (rtx to, rtx from, int unsignedp) enum insn_code icode; rtx target = to; machine_mode fmode, imode; + opt_scalar_mode fmode_iter; bool must_trunc = false; /* We first try to find a pair of modes, one real and one integer, at @@ -4911,66 +4916,70 @@ expand_fix (rtx to, rtx from, int unsignedp) if (unsignedp && is_a <scalar_int_mode> (GET_MODE (to), &to_mode) && HWI_COMPUTABLE_MODE_P (to_mode)) - FOR_EACH_MODE_FROM (fmode, GET_MODE (from)) - if (CODE_FOR_nothing != can_fix_p (to_mode, fmode, 0, &must_trunc) - && (!DECIMAL_FLOAT_MODE_P (fmode) - || GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode))) - { - int bitsize; - REAL_VALUE_TYPE offset; - rtx limit; - rtx_code_label *lab1, *lab2; - rtx_insn *insn; - - bitsize = GET_MODE_PRECISION (to_mode); - real_2expN (&offset, bitsize - 1, fmode); - limit = const_double_from_real_value (offset, fmode); - lab1 = gen_label_rtx (); - lab2 = gen_label_rtx (); - - if (fmode != GET_MODE (from)) - from = convert_to_mode (fmode, from, 0); - - /* See if we need to do the subtraction. */ - do_pending_stack_adjust (); - emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, GET_MODE (from), - 0, lab1); - - /* If not, do the signed "fix" and branch around fixup code. */ - expand_fix (to, from, 0); - emit_jump_insn (targetm.gen_jump (lab2)); - emit_barrier (); - - /* Otherwise, subtract 2**(N-1), convert to signed number, - then add 2**(N-1). Do the addition using XOR since this - will often generate better code. */ - emit_label (lab1); - target = expand_binop (GET_MODE (from), sub_optab, from, limit, - NULL_RTX, 0, OPTAB_LIB_WIDEN); - expand_fix (to, target, 0); - target = expand_binop (to_mode, xor_optab, to, - gen_int_mode - (HOST_WIDE_INT_1 << (bitsize - 1), - to_mode), - to, 1, OPTAB_LIB_WIDEN); - - if (target != to) - emit_move_insn (to, target); - - emit_label (lab2); - - if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing) - { - /* Make a place for a REG_NOTE and add it. */ - insn = emit_move_insn (to, to); - set_dst_reg_note (insn, REG_EQUAL, - gen_rtx_fmt_e (UNSIGNED_FIX, to_mode, - copy_rtx (from)), - to); - } + FOR_EACH_MODE_FROM (fmode_iter, as_a <scalar_mode> (GET_MODE (from))) + { + scalar_mode fmode = fmode_iter.require (); + if (CODE_FOR_nothing != can_fix_p (to_mode, fmode, + 0, &must_trunc) + && (!DECIMAL_FLOAT_MODE_P (fmode) + || (GET_MODE_BITSIZE (fmode) > GET_MODE_PRECISION (to_mode)))) + { + int bitsize; + REAL_VALUE_TYPE offset; + rtx limit; + rtx_code_label *lab1, *lab2; + rtx_insn *insn; + + bitsize = GET_MODE_PRECISION (to_mode); + real_2expN (&offset, bitsize - 1, fmode); + limit = const_double_from_real_value (offset, fmode); + lab1 = gen_label_rtx (); + lab2 = gen_label_rtx (); - return; - } + if (fmode != GET_MODE (from)) + from = convert_to_mode (fmode, from, 0); + + /* See if we need to do the subtraction. */ + do_pending_stack_adjust (); + emit_cmp_and_jump_insns (from, limit, GE, NULL_RTX, + GET_MODE (from), 0, lab1); + + /* If not, do the signed "fix" and branch around fixup code. */ + expand_fix (to, from, 0); + emit_jump_insn (targetm.gen_jump (lab2)); + emit_barrier (); + + /* Otherwise, subtract 2**(N-1), convert to signed number, + then add 2**(N-1). Do the addition using XOR since this + will often generate better code. */ + emit_label (lab1); + target = expand_binop (GET_MODE (from), sub_optab, from, limit, + NULL_RTX, 0, OPTAB_LIB_WIDEN); + expand_fix (to, target, 0); + target = expand_binop (to_mode, xor_optab, to, + gen_int_mode + (HOST_WIDE_INT_1 << (bitsize - 1), + to_mode), + to, 1, OPTAB_LIB_WIDEN); + + if (target != to) + emit_move_insn (to, target); + + emit_label (lab2); + + if (optab_handler (mov_optab, to_mode) != CODE_FOR_nothing) + { + /* Make a place for a REG_NOTE and add it. */ + insn = emit_move_insn (to, to); + set_dst_reg_note (insn, REG_EQUAL, + gen_rtx_fmt_e (UNSIGNED_FIX, to_mode, + copy_rtx (from)), + to); + } + + return; + } + } /* We can't do it with an insn, so use a library call. But first ensure that the mode of TO is at least as wide as SImode, since those are the |