Commit 44c3a8bb by Segher Boessenkool Committed by Segher Boessenkool

constraints.md ("S"): Require TARGET_POWERPC64.

2014-08-17  Segher Boessenkool  <segher@kernel.crashing.org>

	* config/rs6000/constraints.md ("S"): Require TARGET_POWERPC64.
	* config/rs6000/htm.md (ttest): Remove clobber.
	* config/rs6000/predicates.md (any_mask_operand): New predicate.
	(and_operand): Reformat.
	(and_2rld_operand): New predicate.
	* config/rs6000/rs6000-protos.h (rs6000_split_logical): Remove last
	parameter.
	* config/rs6000/rs6000.c (rs6000_split_logical_inner): Remove last
	parameter.  Handle AND directly.
	(rs6000_split_logical_di): Remove last parameter.
	(rs6000_split_logical): Remove last parameter.  Remove obsolete
	comment.
	* config/rs6000/rs6000.md (BOOL_REGS_AND_CR0): Delete.
	(one_cmpl<mode>2): Adjust call of rs6000_split_logical.
	(ctz<mode>2, ffs<mode>2): Delete clobber.  Reformat.
	(andsi3, andsi3_mc, andsi3_nomc, *andsi3_internal2_mc,
	*andsi3_internal3_mc, *andsi3_internal4, *andsi3_internal5_mc,
	and 5 anonymous splitters):  Delete.
	(and<mode>3): New expander.
	(*and<mode>3, *and<mode>3_dot, *and<mode>3_dot2): New.
	(and<mode>3_imm, *and<mode>3_imm_dot, *and<mode>3_imm_dot2): New.
	(*and<mode>3_mask, *and<mode>3_mask_dot, *and<mode>3_mask_dot2): New.
	(ior<mode>, xor<mode>3): Adjust call of rs6000_split_logical.
	(floatdisf2_internal1): Remove clobbers.
	(anddi3, anddi3_mc, anddi3_nomc, anddi3_internal2_mc,
	*anddi3_internal3_mc, and 4 anonymous splitters): Delete.
	(*anddi3_2rld, *anddi3_2rld_dot, *anddi3_2rld_dot2): New.
	(and<mode>3 for BOOL_128): Remove clobber.
	(*and<mode>3_internal for BOOL_128): Remove clobber.  Adjust call of
	rs6000_split_logical.
	(*bool<mode>3_internal for BOOL_128): Adjust call of
	rs6000_split_logical.
	(*boolc<mode>3_internal1 for BOOL_128,
	*boolc<mode>3_internal2 for BOOL_128,
	*boolcc<mode>3_internal1 for BOOL_128,
	*boolcc<mode>3_internal2 for BOOL_128,
	*eqv<mode>3_internal1 for BOOL_128,
	*eqv<mode>3_internal2 for BOOL_128,
	*one_cmpl<mode>3_internal for BOOL_128): Ditto.
	* config/rs6000/vector.md (*vec_reload_and_plus_<mptrsize): Remove
	clobber.
	(*vec_reload_and_reg_<mptrsize>): Delete.

From-SVN: r214080
parent e7ee9a58
2014-08-17 Segher Boessenkool <segher@kernel.crashing.org> 2014-08-17 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/constraints.md ("S"): Require TARGET_POWERPC64.
* config/rs6000/htm.md (ttest): Remove clobber.
* config/rs6000/predicates.md (any_mask_operand): New predicate.
(and_operand): Reformat.
(and_2rld_operand): New predicate.
* config/rs6000/rs6000-protos.h (rs6000_split_logical): Remove last
parameter.
* config/rs6000/rs6000.c (rs6000_split_logical_inner): Remove last
parameter. Handle AND directly.
(rs6000_split_logical_di): Remove last parameter.
(rs6000_split_logical): Remove last parameter. Remove obsolete
comment.
* config/rs6000/rs6000.md (BOOL_REGS_AND_CR0): Delete.
(one_cmpl<mode>2): Adjust call of rs6000_split_logical.
(ctz<mode>2, ffs<mode>2): Delete clobber. Reformat.
(andsi3, andsi3_mc, andsi3_nomc, *andsi3_internal2_mc,
*andsi3_internal3_mc, *andsi3_internal4, *andsi3_internal5_mc,
and 5 anonymous splitters): Delete.
(and<mode>3): New expander.
(*and<mode>3, *and<mode>3_dot, *and<mode>3_dot2): New.
(and<mode>3_imm, *and<mode>3_imm_dot, *and<mode>3_imm_dot2): New.
(*and<mode>3_mask, *and<mode>3_mask_dot, *and<mode>3_mask_dot2): New.
(ior<mode>, xor<mode>3): Adjust call of rs6000_split_logical.
(floatdisf2_internal1): Remove clobbers.
(anddi3, anddi3_mc, anddi3_nomc, anddi3_internal2_mc,
*anddi3_internal3_mc, and 4 anonymous splitters): Delete.
(*anddi3_2rld, *anddi3_2rld_dot, *anddi3_2rld_dot2): New.
(and<mode>3 for BOOL_128): Remove clobber.
(*and<mode>3_internal for BOOL_128): Remove clobber. Adjust call of
rs6000_split_logical.
(*bool<mode>3_internal for BOOL_128): Adjust call of
rs6000_split_logical.
(*boolc<mode>3_internal1 for BOOL_128,
*boolc<mode>3_internal2 for BOOL_128,
*boolcc<mode>3_internal1 for BOOL_128,
*boolcc<mode>3_internal2 for BOOL_128,
*eqv<mode>3_internal1 for BOOL_128,
*eqv<mode>3_internal2 for BOOL_128,
*one_cmpl<mode>3_internal for BOOL_128): Ditto.
* config/rs6000/vector.md (*vec_reload_and_plus_<mptrsize): Remove
clobber.
(*vec_reload_and_reg_<mptrsize>): Delete.
2014-08-17 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/rs6000.md (*boolccsi3_internal1, *boolccsi3_internal2 * config/rs6000/rs6000.md (*boolccsi3_internal1, *boolccsi3_internal2
and split, *boolccsi3_internal3 and split): Delete. and split, *boolccsi3_internal3 and split): Delete.
(*boolccdi3_internal1, *boolccdi3_internal2 and split, (*boolccdi3_internal1, *boolccdi3_internal2 and split,
......
...@@ -232,7 +232,8 @@ usually better to use @samp{m} or @samp{es} in @code{asm} statements)" ...@@ -232,7 +232,8 @@ usually better to use @samp{m} or @samp{es} in @code{asm} statements)"
(define_constraint "S" (define_constraint "S"
"Constant that can be placed into a 64-bit mask operand" "Constant that can be placed into a 64-bit mask operand"
(match_operand 0 "mask64_operand")) (and (match_test "TARGET_POWERPC64")
(match_operand 0 "mask64_operand")))
(define_constraint "T" (define_constraint "T"
"Constant that can be placed into a 32-bit mask operand" "Constant that can be placed into a 32-bit mask operand"
......
...@@ -180,9 +180,9 @@ ...@@ -180,9 +180,9 @@
UNSPECV_HTM_TABORTWCI)) UNSPECV_HTM_TABORTWCI))
(set (subreg:CC (match_dup 2) 0) (match_dup 1)) (set (subreg:CC (match_dup 2) 0) (match_dup 1))
(set (match_dup 3) (lshiftrt:SI (match_dup 2) (const_int 28))) (set (match_dup 3) (lshiftrt:SI (match_dup 2) (const_int 28)))
(parallel [(set (match_operand:SI 0 "int_reg_operand" "") (set (match_operand:SI 0 "int_reg_operand" "")
(and:SI (match_dup 3) (const_int 15))) (and:SI (match_dup 3)
(clobber (scratch:CC))])] (const_int 15)))]
"TARGET_HTM" "TARGET_HTM"
{ {
operands[1] = gen_rtx_REG (CCmode, CR0_REGNO); operands[1] = gen_rtx_REG (CCmode, CR0_REGNO);
......
...@@ -940,6 +940,12 @@ ...@@ -940,6 +940,12 @@
return c == -lsb; return c == -lsb;
}) })
;; Match a mask_operand or a mask64_operand.
(define_predicate "any_mask_operand"
(ior (match_operand 0 "mask_operand")
(and (match_test "TARGET_POWERPC64 && mode == DImode")
(match_operand 0 "mask64_operand"))))
;; Like and_operand, but also match constants that can be implemented ;; Like and_operand, but also match constants that can be implemented
;; with two rldicl or rldicr insns. ;; with two rldicl or rldicr insns.
(define_predicate "and64_2_operand" (define_predicate "and64_2_operand"
...@@ -952,11 +958,18 @@ ...@@ -952,11 +958,18 @@
;; constant that can be used as the operand of a logical AND. ;; constant that can be used as the operand of a logical AND.
(define_predicate "and_operand" (define_predicate "and_operand"
(ior (match_operand 0 "mask_operand") (ior (match_operand 0 "mask_operand")
(ior (and (match_test "TARGET_POWERPC64 && mode == DImode") (and (match_test "TARGET_POWERPC64 && mode == DImode")
(match_operand 0 "mask64_operand")) (match_operand 0 "mask64_operand"))
(if_then_else (match_test "fixed_regs[CR0_REGNO]") (if_then_else (match_test "fixed_regs[CR0_REGNO]")
(match_operand 0 "gpc_reg_operand") (match_operand 0 "gpc_reg_operand")
(match_operand 0 "logical_operand"))))) (match_operand 0 "logical_operand"))))
;; Return 1 if the operand is a constant that can be used as the operand
;; of a logical AND, implemented with two rld* insns, and it cannot be done
;; using just one insn.
(define_predicate "and_2rld_operand"
(and (match_operand 0 "and64_2_operand")
(not (match_operand 0 "and_operand"))))
;; Return 1 if the operand is either a logical operand or a short cint operand. ;; Return 1 if the operand is either a logical operand or a short cint operand.
(define_predicate "scc_eq_operand" (define_predicate "scc_eq_operand"
......
...@@ -150,7 +150,7 @@ extern rtx rs6000_address_for_fpconvert (rtx); ...@@ -150,7 +150,7 @@ extern rtx rs6000_address_for_fpconvert (rtx);
extern rtx rs6000_address_for_altivec (rtx); extern rtx rs6000_address_for_altivec (rtx);
extern rtx rs6000_allocate_stack_temp (enum machine_mode, bool, bool); extern rtx rs6000_allocate_stack_temp (enum machine_mode, bool, bool);
extern int rs6000_loop_align (rtx); extern int rs6000_loop_align (rtx);
extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool, rtx); extern void rs6000_split_logical (rtx [], enum rtx_code, bool, bool, bool);
#endif /* RTX_CODE */ #endif /* RTX_CODE */
#ifdef TREE_CODE #ifdef TREE_CODE
......
...@@ -32795,9 +32795,7 @@ rs6000_set_up_by_prologue (struct hard_reg_set_container *set) ...@@ -32795,9 +32795,7 @@ rs6000_set_up_by_prologue (struct hard_reg_set_container *set)
MODE is the machine mode. MODE is the machine mode.
If COMPLEMENT_FINAL_P is true, wrap the whole operation with NOT. If COMPLEMENT_FINAL_P is true, wrap the whole operation with NOT.
If COMPLEMENT_OP1_P is true, wrap operand1 with NOT. If COMPLEMENT_OP1_P is true, wrap operand1 with NOT.
If COMPLEMENT_OP2_P is true, wrap operand2 with NOT. If COMPLEMENT_OP2_P is true, wrap operand2 with NOT. */
CLOBBER_REG is either NULL or a scratch register of type CC to allow
formation of the AND instructions. */
static void static void
rs6000_split_logical_inner (rtx dest, rs6000_split_logical_inner (rtx dest,
...@@ -32807,11 +32805,9 @@ rs6000_split_logical_inner (rtx dest, ...@@ -32807,11 +32805,9 @@ rs6000_split_logical_inner (rtx dest,
enum machine_mode mode, enum machine_mode mode,
bool complement_final_p, bool complement_final_p,
bool complement_op1_p, bool complement_op1_p,
bool complement_op2_p, bool complement_op2_p)
rtx clobber_reg)
{ {
rtx bool_rtx; rtx bool_rtx;
rtx set_rtx;
/* Optimize AND of 0/0xffffffff and IOR/XOR of 0. */ /* Optimize AND of 0/0xffffffff and IOR/XOR of 0. */
if (op2 && GET_CODE (op2) == CONST_INT if (op2 && GET_CODE (op2) == CONST_INT
...@@ -32851,6 +32847,13 @@ rs6000_split_logical_inner (rtx dest, ...@@ -32851,6 +32847,13 @@ rs6000_split_logical_inner (rtx dest,
} }
} }
if (code == AND && mode == SImode
&& !complement_final_p && !complement_op1_p && !complement_op2_p)
{
emit_insn (gen_andsi3 (dest, op1, op2));
return;
}
if (complement_op1_p) if (complement_op1_p)
op1 = gen_rtx_NOT (mode, op1); op1 = gen_rtx_NOT (mode, op1);
...@@ -32864,17 +32867,7 @@ rs6000_split_logical_inner (rtx dest, ...@@ -32864,17 +32867,7 @@ rs6000_split_logical_inner (rtx dest,
if (complement_final_p) if (complement_final_p)
bool_rtx = gen_rtx_NOT (mode, bool_rtx); bool_rtx = gen_rtx_NOT (mode, bool_rtx);
set_rtx = gen_rtx_SET (VOIDmode, dest, bool_rtx); emit_insn (gen_rtx_SET (VOIDmode, dest, bool_rtx));
/* Is this AND with an explicit clobber? */
if (clobber_reg)
{
rtx clobber = gen_rtx_CLOBBER (VOIDmode, clobber_reg);
set_rtx = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set_rtx, clobber));
}
emit_insn (set_rtx);
return;
} }
/* Split a DImode AND/IOR/XOR with a constant on a 32-bit system. These /* Split a DImode AND/IOR/XOR with a constant on a 32-bit system. These
...@@ -32895,8 +32888,7 @@ rs6000_split_logical_di (rtx operands[3], ...@@ -32895,8 +32888,7 @@ rs6000_split_logical_di (rtx operands[3],
enum rtx_code code, enum rtx_code code,
bool complement_final_p, bool complement_final_p,
bool complement_op1_p, bool complement_op1_p,
bool complement_op2_p, bool complement_op2_p)
rtx clobber_reg)
{ {
const HOST_WIDE_INT lower_32bits = HOST_WIDE_INT_C(0xffffffff); const HOST_WIDE_INT lower_32bits = HOST_WIDE_INT_C(0xffffffff);
const HOST_WIDE_INT upper_32bits = ~ lower_32bits; const HOST_WIDE_INT upper_32bits = ~ lower_32bits;
...@@ -32957,7 +32949,6 @@ rs6000_split_logical_di (rtx operands[3], ...@@ -32957,7 +32949,6 @@ rs6000_split_logical_di (rtx operands[3],
&& !complement_final_p && !complement_final_p
&& !complement_op1_p && !complement_op1_p
&& !complement_op2_p && !complement_op2_p
&& clobber_reg == NULL_RTX
&& !logical_const_operand (op2_hi_lo[i], SImode)) && !logical_const_operand (op2_hi_lo[i], SImode))
{ {
HOST_WIDE_INT value = INTVAL (op2_hi_lo[i]); HOST_WIDE_INT value = INTVAL (op2_hi_lo[i]);
...@@ -32970,18 +32961,15 @@ rs6000_split_logical_di (rtx operands[3], ...@@ -32970,18 +32961,15 @@ rs6000_split_logical_di (rtx operands[3],
hi_16bits |= upper_32bits; hi_16bits |= upper_32bits;
rs6000_split_logical_inner (tmp, op1_hi_lo[i], GEN_INT (hi_16bits), rs6000_split_logical_inner (tmp, op1_hi_lo[i], GEN_INT (hi_16bits),
code, SImode, false, false, false, code, SImode, false, false, false);
NULL_RTX);
rs6000_split_logical_inner (op0_hi_lo[i], tmp, GEN_INT (lo_16bits), rs6000_split_logical_inner (op0_hi_lo[i], tmp, GEN_INT (lo_16bits),
code, SImode, false, false, false, code, SImode, false, false, false);
NULL_RTX);
} }
else else
rs6000_split_logical_inner (op0_hi_lo[i], op1_hi_lo[i], op2_hi_lo[i], rs6000_split_logical_inner (op0_hi_lo[i], op1_hi_lo[i], op2_hi_lo[i],
code, SImode, complement_final_p, code, SImode, complement_final_p,
complement_op1_p, complement_op2_p, complement_op1_p, complement_op2_p);
clobber_reg);
} }
return; return;
...@@ -32993,20 +32981,16 @@ rs6000_split_logical_di (rtx operands[3], ...@@ -32993,20 +32981,16 @@ rs6000_split_logical_di (rtx operands[3],
OPERANDS is an array containing the destination and two input operands. OPERANDS is an array containing the destination and two input operands.
CODE is the base operation (AND, IOR, XOR, NOT). CODE is the base operation (AND, IOR, XOR, NOT).
MODE is the machine mode.
If COMPLEMENT_FINAL_P is true, wrap the whole operation with NOT. If COMPLEMENT_FINAL_P is true, wrap the whole operation with NOT.
If COMPLEMENT_OP1_P is true, wrap operand1 with NOT. If COMPLEMENT_OP1_P is true, wrap operand1 with NOT.
If COMPLEMENT_OP2_P is true, wrap operand2 with NOT. If COMPLEMENT_OP2_P is true, wrap operand2 with NOT. */
CLOBBER_REG is either NULL or a scratch register of type CC to allow
formation of the AND instructions. */
void void
rs6000_split_logical (rtx operands[3], rs6000_split_logical (rtx operands[3],
enum rtx_code code, enum rtx_code code,
bool complement_final_p, bool complement_final_p,
bool complement_op1_p, bool complement_op1_p,
bool complement_op2_p, bool complement_op2_p)
rtx clobber_reg)
{ {
enum machine_mode mode = GET_MODE (operands[0]); enum machine_mode mode = GET_MODE (operands[0]);
enum machine_mode sub_mode; enum machine_mode sub_mode;
...@@ -33018,8 +33002,7 @@ rs6000_split_logical (rtx operands[3], ...@@ -33018,8 +33002,7 @@ rs6000_split_logical (rtx operands[3],
if (mode == DImode && !TARGET_POWERPC64) if (mode == DImode && !TARGET_POWERPC64)
{ {
rs6000_split_logical_di (operands, code, complement_final_p, rs6000_split_logical_di (operands, code, complement_final_p,
complement_op1_p, complement_op2_p, complement_op1_p, complement_op2_p);
clobber_reg);
return; return;
} }
...@@ -33052,7 +33035,7 @@ rs6000_split_logical (rtx operands[3], ...@@ -33052,7 +33035,7 @@ rs6000_split_logical (rtx operands[3],
rs6000_split_logical_inner (sub_op0, sub_op1, sub_op2, code, sub_mode, rs6000_split_logical_inner (sub_op0, sub_op1, sub_op2, code, sub_mode,
complement_final_p, complement_op1_p, complement_final_p, complement_op1_p,
complement_op2_p, clobber_reg); complement_op2_p);
} }
return; return;
......
...@@ -224,25 +224,9 @@ ...@@ -224,25 +224,9 @@
[(set (match_dup 0) [(set (match_dup 0)
(plus:P (match_dup 1) (plus:P (match_dup 1)
(match_dup 2))) (match_dup 2)))
(parallel [(set (match_dup 0) (set (match_dup 0)
(and:P (match_dup 0) (and:P (match_dup 0)
(const_int -16))) (const_int -16)))])
(clobber:CC (scratch:CC))])])
;; The normal ANDSI3/ANDDI3 won't match if reload decides to move an AND -16
;; address to a register because there is no clobber of a (scratch), so we add
;; it here.
(define_insn_and_split "*vec_reload_and_reg_<mptrsize>"
[(set (match_operand:P 0 "gpc_reg_operand" "=b")
(and:P (match_operand:P 1 "gpc_reg_operand" "r")
(const_int -16)))]
"(TARGET_ALTIVEC || TARGET_VSX) && (reload_in_progress || reload_completed)"
"#"
"&& reload_completed"
[(parallel [(set (match_dup 0)
(and:P (match_dup 1)
(const_int -16)))
(clobber:CC (scratch:CC))])])
;; Generic floating point vector arithmetic support ;; Generic floating point vector arithmetic support
(define_expand "add<mode>3" (define_expand "add<mode>3"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment