aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-08-30 11:20:19 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-08-30 11:20:19 +0000
commit16d2200070f49ed71053b81699e37bd539a0ee69 (patch)
treec89eef6816d81c30d7695888167b3345c11aae26 /gcc/optabs.c
parentf4f6058097d99812ee3eda98d09c23fccdc7ba94 (diff)
downloadgcc-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.c137
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