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:
Segher Boessenkool 2014-12-10 19:37:58 +01:00 committed by Segher Boessenkool
parent 969ce0b0a6
commit a935964dea
5 changed files with 442 additions and 1199 deletions

View File

@ -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

View File

@ -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"

View File

@ -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[]);

View File

@ -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