aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/optabs.cc')
-rw-r--r--gcc/optabs.cc110
1 files changed, 65 insertions, 45 deletions
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 0a14b1e..5c9450f 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -1760,8 +1760,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
emit_move_insn (target_piece, x);
}
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
if (i == GET_MODE_BITSIZE (int_mode) / BITS_PER_WORD)
{
@@ -1839,8 +1838,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
outof_target, into_target,
unsignedp, next_methods, shift_mask))
{
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_insn (insns);
return target;
@@ -1962,8 +1960,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
emit_move_insn (outof_target, inter);
}
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
if (inter != 0)
{
@@ -2222,8 +2219,7 @@ expand_binop (machine_mode mode, optab binoptab, rtx op0, rtx op1,
NULL_RTX, LCT_CONST, mode,
op0, mode, op1x, op1_mode);
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
bool trapv = trapv_binoptab_p (binoptab);
target = gen_reg_rtx (mode);
@@ -2564,8 +2560,7 @@ expand_twoval_binop_libfunc (optab binoptab, rtx op0, rtx op1,
/* Get the part of VAL containing the value that we want. */
libval = simplify_gen_subreg (mode, libval, libval_mode,
targ0 ? 0 : GET_MODE_SIZE (mode));
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
/* Move the into the desired location. */
emit_libcall_block (insns, targ0 ? targ0 : targ1, libval,
gen_rtx_fmt_ee (code, mode, op0, op1));
@@ -2698,8 +2693,7 @@ expand_clrsb_using_clz (scalar_int_mode mode, rtx op0, rtx target)
goto fail;
}
- rtx_insn *seq = get_insns ();
- end_sequence ();
+ rtx_insn *seq = end_sequence ();
add_equal_note (seq, temp, CLRSB, op0, NULL_RTX, mode);
emit_insn (seq);
@@ -2797,8 +2791,7 @@ expand_doubleword_clz_ctz_ffs (scalar_int_mode mode, rtx op0, rtx target,
emit_label (after_label);
convert_move (target, result, true);
- seq = get_insns ();
- end_sequence ();
+ seq = end_sequence ();
add_equal_note (seq, target, optab_to_code (unoptab), xop0, NULL_RTX, mode);
emit_insn (seq);
@@ -2839,8 +2832,7 @@ expand_doubleword_popcount (scalar_int_mode mode, rtx op0, rtx target)
t = expand_binop (word_mode, add_optab, t0, t1, target, 0, OPTAB_DIRECT);
- seq = get_insns ();
- end_sequence ();
+ seq = end_sequence ();
add_equal_note (seq, t, POPCOUNT, op0, NULL_RTX, mode);
emit_insn (seq);
@@ -3010,8 +3002,7 @@ expand_ctz (scalar_int_mode mode, rtx op0, rtx target)
return 0;
}
- seq = get_insns ();
- end_sequence ();
+ seq = end_sequence ();
add_equal_note (seq, temp, CTZ, op0, NULL_RTX, mode);
emit_insn (seq);
@@ -3088,8 +3079,7 @@ expand_ffs (scalar_int_mode mode, rtx op0, rtx target)
if (!temp)
goto fail;
- seq = get_insns ();
- end_sequence ();
+ seq = end_sequence ();
add_equal_note (seq, temp, FFS, op0, NULL_RTX, mode);
emit_insn (seq);
@@ -3166,8 +3156,7 @@ expand_absneg_bit (rtx_code code, machine_mode mode,
emit_move_insn (targ_piece, op0_piece);
}
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_insn (insns);
}
@@ -3448,8 +3437,7 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
emit_move_insn (target_piece, x);
}
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_insn (insns);
return target;
@@ -3550,8 +3538,7 @@ expand_unop (machine_mode mode, optab unoptab, rtx op0, rtx target,
if the libcall is cse'd or moved. */
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, outmode,
op0, mode);
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
target = gen_reg_rtx (outmode);
bool trapv = trapv_unoptab_p (unoptab);
@@ -3999,8 +3986,7 @@ expand_copysign_bit (scalar_float_mode mode, rtx op0, rtx op1, rtx target,
emit_move_insn (targ_piece, op0_piece);
}
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_insn (insns);
}
@@ -4304,9 +4290,6 @@ can_compare_p (enum rtx_code code, machine_mode mode,
&& (icode = optab_handler (cstore_optab, mode)) != CODE_FOR_nothing
&& insn_operand_matches (icode, 1, test))
return true;
- if (purpose == ccp_cmov
- && optab_handler (cmov_optab, mode) != CODE_FOR_nothing)
- return true;
mode = GET_MODE_WIDER_MODE (mode).else_void ();
PUT_MODE (test, mode);
@@ -4954,8 +4937,7 @@ prepare_float_lib_cmp (rtx x, rtx y, enum rtx_code comparison,
start_sequence ();
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
cmp_mode, x, mode, y, mode);
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
target = gen_reg_rtx (cmp_mode);
emit_libcall_block (insns, target, value, equiv);
@@ -5693,8 +5675,7 @@ expand_float (rtx to, rtx from, int unsignedp)
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
GET_MODE (to), from, GET_MODE (from));
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_libcall_block (insns, target, value,
gen_rtx_fmt_e (unsignedp ? UNSIGNED_FLOAT : FLOAT,
@@ -5930,8 +5911,7 @@ expand_fix (rtx to, rtx from, int unsignedp)
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST,
GET_MODE (to), from, GET_MODE (from));
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_libcall_block (insns, target, value,
gen_rtx_fmt_e (unsignedp ? UNSIGNED_FIX : FIX,
@@ -6022,8 +6002,7 @@ expand_fixed_convert (rtx to, rtx from, int uintp, int satp)
start_sequence ();
value = emit_library_call_value (libfunc, NULL_RTX, LCT_CONST, to_mode,
from, from_mode);
- insns = get_insns ();
- end_sequence ();
+ insns = end_sequence ();
emit_libcall_block (insns, to, value,
gen_rtx_fmt_e (optab_to_code (tab), to_mode, from));
@@ -6165,8 +6144,7 @@ gen_cond_trap (enum rtx_code code, rtx op1, rtx op2, rtx tcode)
}
emit_insn (insn);
- insn = get_insns ();
- end_sequence ();
+ insn = end_sequence ();
return insn;
}
@@ -6384,6 +6362,50 @@ expand_vec_perm_1 (enum insn_code icode, rtx target,
return NULL_RTX;
}
+/* Check if vec_perm mask SEL is a constant equivalent to an and operation of
+ the non-zero vec_perm operand with some mask consisting of 0xffs and 0x00s,
+ assuming the other vec_perm operand is a constant vector of zeros. Return
+ the mask for the equivalent and operation, or NULL_RTX if the vec_perm can
+ not be modeled as an and. MODE is the mode of the value being anded.
+ ZERO_OP0_P is true if the first operand of the vec_perm is a constant vector
+ of zeros or false if the second operand of the vec_perm is a constant vector
+ of zeros. */
+rtx
+vec_perm_and_mask (machine_mode mode, const vec_perm_indices &sel,
+ bool zero_op0_p)
+{
+ unsigned int nelt;
+ if (!GET_MODE_NUNITS (mode).is_constant (&nelt))
+ return NULL_RTX;
+
+ rtx_vector_builder builder (mode, nelt, 1);
+ machine_mode emode = GET_MODE_INNER (mode);
+
+ for (unsigned int i = 0; i < nelt; i++)
+ {
+ if (zero_op0_p)
+ {
+ if (known_eq (sel[i], nelt + i))
+ builder.quick_push (CONSTM1_RTX (emode));
+ else if (known_lt (sel[i], nelt))
+ builder.quick_push (CONST0_RTX (emode));
+ else
+ return NULL_RTX;
+ }
+ else
+ {
+ if (known_eq (sel[i], i))
+ builder.quick_push (CONSTM1_RTX (emode));
+ else if (known_ge (sel[i], nelt))
+ builder.quick_push (CONST0_RTX (emode));
+ else
+ return NULL_RTX;
+ }
+ }
+
+ return builder.build ();
+}
+
/* Implement a permutation of vectors v0 and v1 using the permutation
vector in SEL and return the result. Use TARGET to hold the result
if nonnull and convenient.
@@ -7803,8 +7825,7 @@ expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
if (result)
{
/* PLUS worked so emit the insns and return. */
- tmp = get_insns ();
- end_sequence ();
+ tmp = end_sequence ();
emit_insn (tmp);
return result;
}
@@ -7883,8 +7904,7 @@ expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
/* For after, copy the value now. */
if (!unused_result && after)
emit_move_insn (target, t1);
- insn = get_insns ();
- end_sequence ();
+ insn = end_sequence ();
if (t1 != NULL && expand_compare_and_swap_loop (mem, t0, t1, insn))
return target;