aboutsummaryrefslogtreecommitdiff
path: root/gcc/optabs.c
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2015-11-10 09:35:11 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2015-11-10 09:35:11 +0000
commitce68b5cfb9d12cb55345bd26ee9114aee925d46a (patch)
treef7660813bbcbf78ce1bf2c64cd6933e5e449b3b0 /gcc/optabs.c
parentdf554b0e49e59c974e45ab21a3a2b4295ce348b2 (diff)
downloadgcc-ce68b5cfb9d12cb55345bd26ee9114aee925d46a.zip
gcc-ce68b5cfb9d12cb55345bd26ee9114aee925d46a.tar.gz
gcc-ce68b5cfb9d12cb55345bd26ee9114aee925d46a.tar.bz2
[optabs][ifcvt][1/3] Define negcc, notcc optabs
* ifcvt.c (noce_try_inverse_constants): New function. (noce_process_if_block): Call it. * optabs.h (emit_conditional_neg_or_complement): Declare prototype. * optabs.def (negcc_optab, notcc_optab): Declare. * optabs.c (emit_conditional_neg_or_complement): New function. * doc/tm.texi (Standard Names): Document negcc, notcc names. From-SVN: r230089
Diffstat (limited to 'gcc/optabs.c')
-rw-r--r--gcc/optabs.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/gcc/optabs.c b/gcc/optabs.c
index 79c5873..1e328a6 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -4210,6 +4210,56 @@ emit_conditional_move (rtx target, enum rtx_code code, rtx op0, rtx op1,
return NULL_RTX;
}
+
+/* Emit a conditional negate or bitwise complement using the
+ negcc or notcc optabs if available. Return NULL_RTX if such operations
+ are not available. Otherwise return the RTX holding the result.
+ TARGET is the desired destination of the result. COMP is the comparison
+ on which to negate. If COND is true move into TARGET the negation
+ or bitwise complement of OP1. Otherwise move OP2 into TARGET.
+ CODE is either NEG or NOT. MODE is the machine mode in which the
+ operation is performed. */
+
+rtx
+emit_conditional_neg_or_complement (rtx target, rtx_code code,
+ machine_mode mode, rtx cond, rtx op1,
+ rtx op2)
+{
+ optab op = unknown_optab;
+ if (code == NEG)
+ op = negcc_optab;
+ else if (code == NOT)
+ op = notcc_optab;
+ else
+ gcc_unreachable ();
+
+ insn_code icode = direct_optab_handler (op, mode);
+
+ if (icode == CODE_FOR_nothing)
+ return NULL_RTX;
+
+ if (!target)
+ target = gen_reg_rtx (mode);
+
+ rtx_insn *last = get_last_insn ();
+ struct expand_operand ops[4];
+
+ create_output_operand (&ops[0], target, mode);
+ create_fixed_operand (&ops[1], cond);
+ create_input_operand (&ops[2], op1, mode);
+ create_input_operand (&ops[3], op2, mode);
+
+ if (maybe_expand_insn (icode, 4, ops))
+ {
+ if (ops[0].value != target)
+ convert_move (target, ops[0].value, false);
+
+ return target;
+ }
+ delete_insns_since (last);
+ return NULL_RTX;
+}
+
/* Emit a conditional addition instruction if the machine supports one for that
condition and machine mode.