mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-01-11 23:45:12 +08:00
rs6000.c (scc_comparison_operator): Make equivalent to branch_positive_comparison_operator.
* config/rs6000/rs6000.c (scc_comparison_operator): Make equivalent to branch_positive_comparison_operator. (ccr_bit): Check that sCOND conditions are actually a positive bit. (print_operand): Remove %D substitution. (rs6000_emit_sCOND): Generate complement operation to ensure that sCOND input is a positive bit. * config/rs6000/rs6000.md: Rearrange sCOND templates to be in the same order as bCOND, and add the missing ones. Remove the %D substitutions from the scc patterns. From-SVN: r66441
This commit is contained in:
parent
8d90f9c029
commit
b7053a3fde
@ -1,5 +1,15 @@
|
|||||||
2003-05-03 Geoffrey Keating <geoffk@apple.com>
|
2003-05-03 Geoffrey Keating <geoffk@apple.com>
|
||||||
|
|
||||||
|
* config/rs6000/rs6000.c (scc_comparison_operator): Make equivalent
|
||||||
|
to branch_positive_comparison_operator.
|
||||||
|
(ccr_bit): Check that sCOND conditions are actually a positive bit.
|
||||||
|
(print_operand): Remove %D substitution.
|
||||||
|
(rs6000_emit_sCOND): Generate complement operation to ensure that
|
||||||
|
sCOND input is a positive bit.
|
||||||
|
* config/rs6000/rs6000.md: Rearrange sCOND templates to be in the
|
||||||
|
same order as bCOND, and add the missing ones. Remove the %D
|
||||||
|
substitutions from the scc patterns.
|
||||||
|
|
||||||
* simplify-rtx.c (simplify_relational_operation): Add case for
|
* simplify-rtx.c (simplify_relational_operation): Add case for
|
||||||
! (fabs(x) < 0.0).
|
! (fabs(x) < 0.0).
|
||||||
|
|
||||||
|
@ -7049,34 +7049,15 @@ branch_positive_comparison_operator (op, mode)
|
|||||||
|| code == UNORDERED);
|
|| code == UNORDERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return 1 if OP is a comparison operation that is valid for an scc insn.
|
/* Return 1 if OP is a comparison operation that is valid for an scc
|
||||||
We check the opcode against the mode of the CC value and disallow EQ or
|
insn: it must be a positive comparison. */
|
||||||
NE comparisons for integers. */
|
|
||||||
|
|
||||||
int
|
int
|
||||||
scc_comparison_operator (op, mode)
|
scc_comparison_operator (op, mode)
|
||||||
rtx op;
|
rtx op;
|
||||||
enum machine_mode mode;
|
enum machine_mode mode;
|
||||||
{
|
{
|
||||||
enum rtx_code code = GET_CODE (op);
|
return branch_positive_comparison_operator (op, mode);
|
||||||
enum machine_mode cc_mode;
|
|
||||||
|
|
||||||
if (GET_MODE (op) != mode && mode != VOIDmode)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (GET_RTX_CLASS (code) != '<')
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cc_mode = GET_MODE (XEXP (op, 0));
|
|
||||||
if (GET_MODE_CLASS (cc_mode) != MODE_CC)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
validate_condition_mode (code, cc_mode);
|
|
||||||
|
|
||||||
if (code == NE && cc_mode != CCFPmode)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -7501,6 +7482,12 @@ ccr_bit (op, scc_p)
|
|||||||
|
|
||||||
validate_condition_mode (code, cc_mode);
|
validate_condition_mode (code, cc_mode);
|
||||||
|
|
||||||
|
/* When generating a sCOND operation, only positive conditions are
|
||||||
|
allowed. */
|
||||||
|
if (scc_p && code != EQ && code != GT && code != LT && code != UNORDERED
|
||||||
|
&& code != GTU && code != LTU)
|
||||||
|
abort ();
|
||||||
|
|
||||||
switch (code)
|
switch (code)
|
||||||
{
|
{
|
||||||
case NE:
|
case NE:
|
||||||
@ -7697,42 +7684,6 @@ print_operand (file, x, code)
|
|||||||
/* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
|
/* %c is output_addr_const if a CONSTANT_ADDRESS_P, otherwise
|
||||||
output_operand. */
|
output_operand. */
|
||||||
|
|
||||||
case 'D':
|
|
||||||
/* There used to be a comment for 'C' reading "This is an
|
|
||||||
optional cror needed for certain floating-point
|
|
||||||
comparisons. Otherwise write nothing." */
|
|
||||||
|
|
||||||
/* Similar, except that this is for an scc, so we must be able to
|
|
||||||
encode the test in a single bit that is one. We do the above
|
|
||||||
for any LE, GE, GEU, or LEU and invert the bit for NE. */
|
|
||||||
if (GET_CODE (x) == LE || GET_CODE (x) == GE
|
|
||||||
|| GET_CODE (x) == LEU || GET_CODE (x) == GEU)
|
|
||||||
{
|
|
||||||
int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
|
|
||||||
|
|
||||||
fprintf (file, "cror %d,%d,%d\n\t", base_bit + 3,
|
|
||||||
base_bit + 2,
|
|
||||||
base_bit + (GET_CODE (x) == GE || GET_CODE (x) == GEU));
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (GET_CODE (x) == NE)
|
|
||||||
{
|
|
||||||
int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
|
|
||||||
|
|
||||||
fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 3,
|
|
||||||
base_bit + 2, base_bit + 2);
|
|
||||||
}
|
|
||||||
else if (TARGET_E500 && !TARGET_FPRS && TARGET_HARD_FLOAT
|
|
||||||
&& GET_CODE (x) == EQ
|
|
||||||
&& GET_MODE (XEXP (x, 0)) == CCFPmode)
|
|
||||||
{
|
|
||||||
int base_bit = 4 * (REGNO (XEXP (x, 0)) - CR0_REGNO);
|
|
||||||
|
|
||||||
fprintf (file, "crnor %d,%d,%d\n\t", base_bit + 1,
|
|
||||||
base_bit + 1, base_bit + 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
case 'E':
|
case 'E':
|
||||||
/* X is a CR register. Print the number of the EQ bit of the CR */
|
/* X is a CR register. Print the number of the EQ bit of the CR */
|
||||||
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
|
if (GET_CODE (x) != REG || ! CR_REGNO_P (REGNO (x)))
|
||||||
@ -8686,8 +8637,28 @@ rs6000_emit_sCOND (code, result)
|
|||||||
{
|
{
|
||||||
rtx condition_rtx;
|
rtx condition_rtx;
|
||||||
enum machine_mode op_mode;
|
enum machine_mode op_mode;
|
||||||
|
enum rtx_code cond_code;
|
||||||
|
|
||||||
condition_rtx = rs6000_generate_compare (code);
|
condition_rtx = rs6000_generate_compare (code);
|
||||||
|
cond_code = GET_CODE (condition_rtx);
|
||||||
|
|
||||||
|
if (cond_code == NE
|
||||||
|
|| cond_code == GE || cond_code == LE
|
||||||
|
|| cond_code == GEU || cond_code == LEU
|
||||||
|
|| cond_code == ORDERED || cond_code == UNGE || cond_code == UNLE)
|
||||||
|
{
|
||||||
|
rtx not_result = gen_reg_rtx (CCEQmode);
|
||||||
|
rtx not_op, rev_cond_rtx;
|
||||||
|
enum machine_mode cc_mode;
|
||||||
|
|
||||||
|
cc_mode = GET_MODE (XEXP (condition_rtx, 0));
|
||||||
|
|
||||||
|
rev_cond_rtx = gen_rtx (rs6000_reverse_condition (cc_mode, cond_code),
|
||||||
|
SImode, XEXP (condition_rtx, 0), const0_rtx);
|
||||||
|
not_op = gen_rtx_COMPARE (CCEQmode, rev_cond_rtx, const0_rtx);
|
||||||
|
emit_insn (gen_rtx_SET (VOIDmode, not_result, not_op));
|
||||||
|
condition_rtx = gen_rtx_EQ (VOIDmode, not_result, const0_rtx);
|
||||||
|
}
|
||||||
|
|
||||||
op_mode = GET_MODE (rs6000_compare_op0);
|
op_mode = GET_MODE (rs6000_compare_op0);
|
||||||
if (op_mode == VOIDmode)
|
if (op_mode == VOIDmode)
|
||||||
|
@ -10919,34 +10919,6 @@
|
|||||||
DONE;
|
DONE;
|
||||||
}")
|
}")
|
||||||
|
|
||||||
;; A > 0 is best done using the portable sequence, so fail in that case.
|
|
||||||
(define_expand "sgt"
|
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
|
||||||
""
|
|
||||||
"
|
|
||||||
{
|
|
||||||
if (! rs6000_compare_fp_p
|
|
||||||
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
|
|
||||||
FAIL;
|
|
||||||
|
|
||||||
rs6000_emit_sCOND (GT, operands[0]);
|
|
||||||
DONE;
|
|
||||||
}")
|
|
||||||
|
|
||||||
;; A < 0 is best done in the portable way for A an integer.
|
|
||||||
(define_expand "slt"
|
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
|
||||||
""
|
|
||||||
"
|
|
||||||
{
|
|
||||||
if (! rs6000_compare_fp_p
|
|
||||||
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
|
|
||||||
FAIL;
|
|
||||||
|
|
||||||
rs6000_emit_sCOND (LT, operands[0]);
|
|
||||||
DONE;
|
|
||||||
}")
|
|
||||||
|
|
||||||
;; A >= 0 is best done the portable way for A an integer.
|
;; A >= 0 is best done the portable way for A an integer.
|
||||||
(define_expand "sge"
|
(define_expand "sge"
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
@ -10961,6 +10933,20 @@
|
|||||||
DONE;
|
DONE;
|
||||||
}")
|
}")
|
||||||
|
|
||||||
|
;; A > 0 is best done using the portable sequence, so fail in that case.
|
||||||
|
(define_expand "sgt"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"
|
||||||
|
{
|
||||||
|
if (! rs6000_compare_fp_p
|
||||||
|
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
|
||||||
|
FAIL;
|
||||||
|
|
||||||
|
rs6000_emit_sCOND (GT, operands[0]);
|
||||||
|
DONE;
|
||||||
|
}")
|
||||||
|
|
||||||
;; A <= 0 is best done the portable way for A an integer.
|
;; A <= 0 is best done the portable way for A an integer.
|
||||||
(define_expand "sle"
|
(define_expand "sle"
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
@ -10975,25 +10961,80 @@
|
|||||||
DONE;
|
DONE;
|
||||||
}")
|
}")
|
||||||
|
|
||||||
(define_expand "sgtu"
|
;; A < 0 is best done in the portable way for A an integer.
|
||||||
|
(define_expand "slt"
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
""
|
""
|
||||||
"{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
|
"
|
||||||
|
{
|
||||||
|
if (! rs6000_compare_fp_p
|
||||||
|
&& (! TARGET_POWER || rs6000_compare_op1 == const0_rtx))
|
||||||
|
FAIL;
|
||||||
|
|
||||||
(define_expand "sltu"
|
rs6000_emit_sCOND (LT, operands[0]);
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
DONE;
|
||||||
""
|
}")
|
||||||
"{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
|
|
||||||
|
|
||||||
(define_expand "sgeu"
|
(define_expand "sgeu"
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
""
|
""
|
||||||
"{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
|
"{ rs6000_emit_sCOND (GEU, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sgtu"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (GTU, operands[0]); DONE; }")
|
||||||
|
|
||||||
(define_expand "sleu"
|
(define_expand "sleu"
|
||||||
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
""
|
""
|
||||||
"{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
|
"{ rs6000_emit_sCOND (LEU, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sltu"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (LTU, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sunordered"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (UNORDERED, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sordered"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (ORDERED, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "suneq"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (UNEQ, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sunge"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (UNGE, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sungt"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (UNGT, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sunle"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (UNLE, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sunlt"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (UNLT, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
(define_expand "sltgt"
|
||||||
|
[(clobber (match_operand:SI 0 "gpc_reg_operand" ""))]
|
||||||
|
""
|
||||||
|
"{ rs6000_emit_sCOND (LTGT, operands[0]); DONE; }")
|
||||||
|
|
||||||
|
|
||||||
;; Here are the actual compare insns.
|
;; Here are the actual compare insns.
|
||||||
(define_insn "*cmpsi_internal1"
|
(define_insn "*cmpsi_internal1"
|
||||||
@ -11141,7 +11182,7 @@
|
|||||||
[(match_operand 2 "cc_reg_operand" "y")
|
[(match_operand 2 "cc_reg_operand" "y")
|
||||||
(const_int 0)]))]
|
(const_int 0)]))]
|
||||||
""
|
""
|
||||||
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
|
"mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
|
||||||
[(set_attr "type" "mfcr")
|
[(set_attr "type" "mfcr")
|
||||||
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
||||||
|
|
||||||
@ -11150,7 +11191,7 @@
|
|||||||
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
[(set (match_operand:SI 0 "gpc_reg_operand" "=r")
|
||||||
(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
|
(unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_OV))]
|
||||||
"TARGET_ISEL"
|
"TARGET_ISEL"
|
||||||
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
|
"mfcr %0\;{rlinm|rlwinm} %0,%0,%t1,1"
|
||||||
[(set_attr "type" "mfcr")
|
[(set_attr "type" "mfcr")
|
||||||
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
||||||
|
|
||||||
@ -11160,7 +11201,7 @@
|
|||||||
[(match_operand 2 "cc_reg_operand" "y")
|
[(match_operand 2 "cc_reg_operand" "y")
|
||||||
(const_int 0)]))]
|
(const_int 0)]))]
|
||||||
"TARGET_POWERPC64"
|
"TARGET_POWERPC64"
|
||||||
"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
|
"mfcr %0\;{rlinm|rlwinm} %0,%0,%J1,1"
|
||||||
[(set_attr "type" "mfcr")
|
[(set_attr "type" "mfcr")
|
||||||
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
||||||
|
|
||||||
@ -11174,7 +11215,7 @@
|
|||||||
(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
|
(match_op_dup 1 [(match_dup 2) (const_int 0)]))]
|
||||||
"! TARGET_POWERPC64"
|
"! TARGET_POWERPC64"
|
||||||
"@
|
"@
|
||||||
%D1mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1
|
mfcr %3\;{rlinm.|rlwinm.} %3,%3,%J1,1
|
||||||
#"
|
#"
|
||||||
[(set_attr "type" "delayed_compare")
|
[(set_attr "type" "delayed_compare")
|
||||||
(set_attr "length" "12,16")])
|
(set_attr "length" "12,16")])
|
||||||
@ -11216,7 +11257,7 @@
|
|||||||
operands[4] = GEN_INT (count);
|
operands[4] = GEN_INT (count);
|
||||||
operands[5] = GEN_INT (put_bit);
|
operands[5] = GEN_INT (put_bit);
|
||||||
|
|
||||||
return \"%D1mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
|
return \"mfcr %0\;{rlinm|rlwinm} %0,%0,%4,%5,%5\";
|
||||||
}"
|
}"
|
||||||
[(set_attr "type" "mfcr")
|
[(set_attr "type" "mfcr")
|
||||||
(set_attr "length" "12")])
|
(set_attr "length" "12")])
|
||||||
@ -11251,7 +11292,7 @@
|
|||||||
operands[5] = GEN_INT (count);
|
operands[5] = GEN_INT (count);
|
||||||
operands[6] = GEN_INT (put_bit);
|
operands[6] = GEN_INT (put_bit);
|
||||||
|
|
||||||
return \"%D1mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
|
return \"mfcr %4\;{rlinm.|rlwinm.} %4,%4,%5,%6,%6\";
|
||||||
}"
|
}"
|
||||||
[(set_attr "type" "delayed_compare")
|
[(set_attr "type" "delayed_compare")
|
||||||
(set_attr "length" "12,16")])
|
(set_attr "length" "12,16")])
|
||||||
@ -11289,7 +11330,7 @@
|
|||||||
[(match_operand 5 "cc_reg_operand" "y")
|
[(match_operand 5 "cc_reg_operand" "y")
|
||||||
(const_int 0)]))]
|
(const_int 0)]))]
|
||||||
"REGNO (operands[2]) != REGNO (operands[5])"
|
"REGNO (operands[2]) != REGNO (operands[5])"
|
||||||
"%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
|
"mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
|
||||||
[(set_attr "type" "mfcr")
|
[(set_attr "type" "mfcr")
|
||||||
(set_attr "length" "20")])
|
(set_attr "length" "20")])
|
||||||
|
|
||||||
@ -11303,7 +11344,7 @@
|
|||||||
[(match_operand 5 "cc_reg_operand" "y")
|
[(match_operand 5 "cc_reg_operand" "y")
|
||||||
(const_int 0)]))]
|
(const_int 0)]))]
|
||||||
"TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
|
"TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])"
|
||||||
"%D1%D4mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
|
"mfcr %3\;{rlinm|rlwinm} %0,%3,%J1,1\;{rlinm|rlwinm} %3,%3,%J4,1"
|
||||||
[(set_attr "type" "mfcr")
|
[(set_attr "type" "mfcr")
|
||||||
(set_attr "length" "20")])
|
(set_attr "length" "20")])
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user