re PR target/64180 (PowerPC carry bit improvements)
PR target/64180 * config/rs6000/predicates.md (unsigned_comparison_operator): New. (signed_comparison_operator): New. * config/rs6000/rs6000-protos.h (rs6000_emit_eqne): Declare. * config/rs6000/rs6000.c (rs6000_emit_eqne): New function. (rs6000_emit_sCOND): Remove ISEL test (move it to the expander). * config/rs6000/rs6000.md (add<mode>3 for SDI): Expand DImode add to addc,adde directly, if !TARGET_POWERPC64. (sub<mode>3 for SDI): Expand DImode sub to subfc,subfe directly, if !TARGET_POWERPC64. (neg<mode>2): Delete expander. (*neg<mode>2): Rename to "neg<mode>2". (addti3, subti3): Delete. (addti3, subti3): New expanders. (*adddi3_noppc64, *subdi3_noppc64, *negdi2_noppc64): Delete. (cstore<mode>4_unsigned): New expander. (cstore<mode>4): Allow GPR as output (not just SI). Rewrite. (cstore<mode>4 for FP): Remove superfluous quotes. (*eq<mode>, *eq<mode>_compare, *plus_eqsi and splitter, *compare_plus_eqsi and splitter, *plus_eqsi_compare and splitter, *neg_eq0<mode>, *neg_eq<mode>, *ne0_<mode>, plus_ne0_<mode>, compare_plus_ne0_<mode> and splitter, *compare_plus_ne0_<mode>_1 and splitter, *plus_ne0_<mode>_compare and splitter, *leu<mode>, *leu<mode>_compare and splitter, *plus_leu<mode>, *neg_leu<mode>, *and_neg_leu<mode>, *ltu<mode>, *ltu<mode>_compare, *plus_ltu<mode>, *plus_ltu<mode>_1, *plus_ltu<mode>compare, *neg_ltu<mode>, *geu<mode>, *geu<mode>_compare and splitter, *plus_geu<mode>, *neg_geu<mode>, *and_neg_geu<mode>, *plus_gt0<mode>, *gtu<mode>, *gtu<mode>_compare, *plus_gtu<mode>, *plus_gtu<mode>_1, *plus_gtu<mode>_compare, *neg_gtu<mode>, 12 anonymous insns, and 12 anonymous splitters): Delete. (eq<mode>3, ne<mode>3): New. (*neg_eq_<mode>, *neg_ne_<mode>): New. (*plus_eq_<mode>, *plus_ne_<mode>): New. (*minus_eq_<mode>, *minus_ne_<mode>): New. From-SVN: r218595
This commit is contained in:
parent
969ce0b0a6
commit
a935964dea
@ -1,3 +1,41 @@
|
||||
2014-12-10 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR target/64180
|
||||
* config/rs6000/predicates.md (unsigned_comparison_operator): New.
|
||||
(signed_comparison_operator): New.
|
||||
* config/rs6000/rs6000-protos.h (rs6000_emit_eqne): Declare.
|
||||
* config/rs6000/rs6000.c (rs6000_emit_eqne): New function.
|
||||
(rs6000_emit_sCOND): Remove ISEL test (move it to the expander).
|
||||
* config/rs6000/rs6000.md (add<mode>3 for SDI): Expand DImode
|
||||
add to addc,adde directly, if !TARGET_POWERPC64.
|
||||
(sub<mode>3 for SDI): Expand DImode sub to subfc,subfe directly,
|
||||
if !TARGET_POWERPC64.
|
||||
(neg<mode>2): Delete expander.
|
||||
(*neg<mode>2): Rename to "neg<mode>2".
|
||||
(addti3, subti3): Delete.
|
||||
(addti3, subti3): New expanders.
|
||||
(*adddi3_noppc64, *subdi3_noppc64, *negdi2_noppc64): Delete.
|
||||
(cstore<mode>4_unsigned): New expander.
|
||||
(cstore<mode>4): Allow GPR as output (not just SI). Rewrite.
|
||||
(cstore<mode>4 for FP): Remove superfluous quotes.
|
||||
(*eq<mode>, *eq<mode>_compare, *plus_eqsi and splitter,
|
||||
*compare_plus_eqsi and splitter, *plus_eqsi_compare and splitter,
|
||||
*neg_eq0<mode>, *neg_eq<mode>, *ne0_<mode>, plus_ne0_<mode>,
|
||||
compare_plus_ne0_<mode> and splitter, *compare_plus_ne0_<mode>_1 and
|
||||
splitter, *plus_ne0_<mode>_compare and splitter, *leu<mode>,
|
||||
*leu<mode>_compare and splitter, *plus_leu<mode>, *neg_leu<mode>,
|
||||
*and_neg_leu<mode>, *ltu<mode>, *ltu<mode>_compare, *plus_ltu<mode>,
|
||||
*plus_ltu<mode>_1, *plus_ltu<mode>compare, *neg_ltu<mode>, *geu<mode>,
|
||||
*geu<mode>_compare and splitter, *plus_geu<mode>, *neg_geu<mode>,
|
||||
*and_neg_geu<mode>, *plus_gt0<mode>, *gtu<mode>, *gtu<mode>_compare,
|
||||
*plus_gtu<mode>, *plus_gtu<mode>_1, *plus_gtu<mode>_compare,
|
||||
*neg_gtu<mode>, 12 anonymous insns, and 12 anonymous splitters):
|
||||
Delete.
|
||||
(eq<mode>3, ne<mode>3): New.
|
||||
(*neg_eq_<mode>, *neg_ne_<mode>): New.
|
||||
(*plus_eq_<mode>, *plus_ne_<mode>): New.
|
||||
(*minus_eq_<mode>, *minus_ne_<mode>): New.
|
||||
|
||||
2014-12-10 Segher Boessenkool <segher@kernel.crashing.org>
|
||||
|
||||
PR target/64180
|
||||
|
@ -1240,6 +1240,14 @@
|
||||
(match_code ("unlt,unle,ungt,unge"))))
|
||||
(match_operand 0 "comparison_operator")))
|
||||
|
||||
;; Return 1 if OP is an unsigned comparison operator.
|
||||
(define_predicate "unsigned_comparison_operator"
|
||||
(match_code "ltu,gtu,leu,geu"))
|
||||
|
||||
;; Return 1 if OP is a signed comparison operator.
|
||||
(define_predicate "signed_comparison_operator"
|
||||
(match_code "lt,gt,le,ge"))
|
||||
|
||||
;; Return 1 if OP is a comparison operation that is valid for an SCC insn --
|
||||
;; it must be a positive comparison.
|
||||
(define_predicate "scc_comparison_operator"
|
||||
|
@ -109,6 +109,7 @@ extern void print_operand (FILE *, rtx, int);
|
||||
extern void print_operand_address (FILE *, rtx);
|
||||
extern enum rtx_code rs6000_reverse_condition (machine_mode,
|
||||
enum rtx_code);
|
||||
extern rtx rs6000_emit_eqne (machine_mode, rtx, rtx, rtx);
|
||||
extern void rs6000_emit_sISEL (machine_mode, rtx[]);
|
||||
extern void rs6000_emit_sCOND (machine_mode, rtx[]);
|
||||
extern void rs6000_emit_cbranch (machine_mode, rtx[]);
|
||||
|
@ -19422,6 +19422,27 @@ rs6000_emit_sISEL (machine_mode mode ATTRIBUTE_UNUSED, rtx operands[])
|
||||
rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
|
||||
}
|
||||
|
||||
/* Emit RTL that sets a register to zero if OP1 and OP2 are equal. SCRATCH
|
||||
can be used as that dest register. Return the dest register. */
|
||||
|
||||
rtx
|
||||
rs6000_emit_eqne (machine_mode mode, rtx op1, rtx op2, rtx scratch)
|
||||
{
|
||||
if (op2 == const0_rtx)
|
||||
return op1;
|
||||
|
||||
if (GET_CODE (scratch) == SCRATCH)
|
||||
scratch = gen_reg_rtx (mode);
|
||||
|
||||
if (logical_operand (op2, mode))
|
||||
emit_insn (gen_rtx_SET (VOIDmode, scratch, gen_rtx_XOR (mode, op1, op2)));
|
||||
else
|
||||
emit_insn (gen_rtx_SET (VOIDmode, scratch,
|
||||
gen_rtx_PLUS (mode, op1, negate_rtx (mode, op2))));
|
||||
|
||||
return scratch;
|
||||
}
|
||||
|
||||
void
|
||||
rs6000_emit_sCOND (machine_mode mode, rtx operands[])
|
||||
{
|
||||
@ -19430,12 +19451,6 @@ rs6000_emit_sCOND (machine_mode mode, rtx operands[])
|
||||
enum rtx_code cond_code;
|
||||
rtx result = operands[0];
|
||||
|
||||
if (TARGET_ISEL && (mode == SImode || mode == DImode))
|
||||
{
|
||||
rs6000_emit_sISEL (mode, operands);
|
||||
return;
|
||||
}
|
||||
|
||||
condition_rtx = rs6000_generate_compare (operands[1], mode);
|
||||
cond_code = GET_CODE (condition_rtx);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user