Commit 85729229 by Eric Botcazou Committed by Eric Botcazou

sparc-modes.def (CCV): New.

	* config/sparc/sparc-modes.def (CCV): New.
	(CCXV): Likewise.
	* config/sparc/predicates.md (v_comparison_operator): New.
	(icc_comparison_operator): Add support for CCV/CCXV.
	(xcc_comparison_operator): Likewise.
	* config/sparc/sparc.c (output_cbranch): Likewise.
	(sparc_print_operand): Likewise.
	* config/sparc/sparc.md (UNSPEC_{ADD,SUB,NEG}V): New constants.
	(uaddvdi4): New expander.
	(addvdi4): Likewise.
	(uaddvdi4_sp32): New instruction.
	(addvdi4_sp32): Likewise.
	(uaddvsi4): New expander.
	(addvsi4): Likewise.
	(cmp_ccc_plus_sltu_set): New instruction.
	(cmp_ccv_plus): Likewise.
	(cmp_ccxv_plus): Likewise.
	(cmp_ccv_plus_set): Likewise.
	(cmp_ccxv_plus_set): Likewise.
	(cmp_ccv_plus_sltu_set): Likewise.
	(uaddvdi4): New expander.
	(subvdi4): Likewise.
	(usubdi4_sp32): New instruction.
	(subvdi4_sp32): Likewise.
	(usubvsi4): New expander.
	(subvsi4): Likewise.
	(cmpsi_minus_sltu_set): New instruction.
	(cmp_ccv_minus): Likewise.
	(cmp_ccxv_minus): Likewise.
	(cmp_ccv_minus_set): Likewise.
	(cmp_ccxv_minus_set): Likewise.
	(cmp_ccv_minus_sltu_set): Likewise.
	(unegvdi3): New expander.
	(negvdi3): Likewise.
	(unegdi3_sp32): New instruction.
	(negvdi3_sp32): Likewise.
	(unegvsi3): New expander.
	(negvsi3): Likewise.
	(cmp_ccc_neg_sltu_set): New instruction.
	(cmp_ccv_neg): Likewise.
	(cmp_ccxv_neg): Likewise.
	(cmp_ccv_neg_set): Likewise.
	(cmp_ccxv_neg_set): Likewise.
	(cmp_ccv_neg_sltu_set): Likewise.

From-SVN: r241397
parent d17f2c3b
2016-10-21 Eric Botcazou <ebotcazou@adacore.com>
* config/sparc/sparc-modes.def (CCV): New.
(CCXV): Likewise.
* config/sparc/predicates.md (v_comparison_operator): New.
(icc_comparison_operator): Add support for CCV/CCXV.
(xcc_comparison_operator): Likewise.
* config/sparc/sparc.c (output_cbranch): Likewise.
(sparc_print_operand): Likewise.
* config/sparc/sparc.md (UNSPEC_{ADD,SUB,NEG}V): New constants.
(uaddvdi4): New expander.
(addvdi4): Likewise.
(uaddvdi4_sp32): New instruction.
(addvdi4_sp32): Likewise.
(uaddvsi4): New expander.
(addvsi4): Likewise.
(cmp_ccc_plus_sltu_set): New instruction.
(cmp_ccv_plus): Likewise.
(cmp_ccxv_plus): Likewise.
(cmp_ccv_plus_set): Likewise.
(cmp_ccxv_plus_set): Likewise.
(cmp_ccv_plus_sltu_set): Likewise.
(uaddvdi4): New expander.
(subvdi4): Likewise.
(usubdi4_sp32): New instruction.
(subvdi4_sp32): Likewise.
(usubvsi4): New expander.
(subvsi4): Likewise.
(cmpsi_minus_sltu_set): New instruction.
(cmp_ccv_minus): Likewise.
(cmp_ccxv_minus): Likewise.
(cmp_ccv_minus_set): Likewise.
(cmp_ccxv_minus_set): Likewise.
(cmp_ccv_minus_sltu_set): Likewise.
(unegvdi3): New expander.
(negvdi3): Likewise.
(unegdi3_sp32): New instruction.
(negvdi3_sp32): Likewise.
(unegvsi3): New expander.
(negvsi3): Likewise.
(cmp_ccc_neg_sltu_set): New instruction.
(cmp_ccv_neg): Likewise.
(cmp_ccxv_neg): Likewise.
(cmp_ccv_neg_set): Likewise.
(cmp_ccxv_neg_set): Likewise.
(cmp_ccv_neg_sltu_set): Likewise.
2016-10-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2016-10-21 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
PR rtl-optimization/78038 PR rtl-optimization/78038
......
...@@ -420,6 +420,10 @@ ...@@ -420,6 +420,10 @@
(define_predicate "c_comparison_operator" (define_predicate "c_comparison_operator"
(match_code "ltu,geu")) (match_code "ltu,geu"))
;; Return true if OP is a valid comparison operator for CCVmode.
(define_predicate "v_comparison_operator"
(match_code "eq,ne"))
;; Return true if OP is an integer comparison operator. This allows ;; Return true if OP is an integer comparison operator. This allows
;; the use of MATCH_OPERATOR to recognize all the branch insns. ;; the use of MATCH_OPERATOR to recognize all the branch insns.
(define_predicate "icc_comparison_operator" (define_predicate "icc_comparison_operator"
...@@ -436,6 +440,9 @@ ...@@ -436,6 +440,9 @@
case CCCmode: case CCCmode:
case CCXCmode: case CCXCmode:
return c_comparison_operator (op, mode); return c_comparison_operator (op, mode);
case CCVmode:
case CCXVmode:
return v_comparison_operator (op, mode);
default: default:
return false; return false;
} }
......
...@@ -34,6 +34,10 @@ FLOAT_MODE (TF, 16, ieee_quad_format); ...@@ -34,6 +34,10 @@ FLOAT_MODE (TF, 16, ieee_quad_format);
they explicitly set the C flag (unsigned overflow). Only the unsigned they explicitly set the C flag (unsigned overflow). Only the unsigned
<,>= operators can be used in conjunction with it. <,>= operators can be used in conjunction with it.
We also have a CCVmode which is used by the arithmetic instructions when
they explicitly set the V flag (signed overflow). Only the =,!= operators
can be used in conjunction with it.
We also have two modes to indicate that the relevant condition code is We also have two modes to indicate that the relevant condition code is
in the floating-point condition code register. One for comparisons which in the floating-point condition code register. One for comparisons which
will generate an exception if the result is unordered (CCFPEmode) and will generate an exception if the result is unordered (CCFPEmode) and
...@@ -46,6 +50,8 @@ CC_MODE (CCNZ); ...@@ -46,6 +50,8 @@ CC_MODE (CCNZ);
CC_MODE (CCXNZ); CC_MODE (CCXNZ);
CC_MODE (CCC); CC_MODE (CCC);
CC_MODE (CCXC); CC_MODE (CCXC);
CC_MODE (CCV);
CC_MODE (CCXV);
CC_MODE (CCFP); CC_MODE (CCFP);
CC_MODE (CCFPE); CC_MODE (CCFPE);
......
...@@ -2784,8 +2784,9 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y) ...@@ -2784,8 +2784,9 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y)
gcc_unreachable (); gcc_unreachable ();
} }
} }
else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS else if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|| GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT) || GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT)
&& y == const0_rtx)
{ {
if (TARGET_ARCH64 && GET_MODE (x) == DImode) if (TARGET_ARCH64 && GET_MODE (x) == DImode)
return CCXNZmode; return CCXNZmode;
...@@ -2803,6 +2804,18 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y) ...@@ -2803,6 +2804,18 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y)
return CCCmode; return CCCmode;
} }
/* This is for the [u]addvdi4_sp32 and [u]subvdi4_sp32 patterns. */
if (!TARGET_ARCH64 && GET_MODE (x) == DImode)
{
if (GET_CODE (y) == UNSPEC
&& (XINT (y, 1) == UNSPEC_ADDV
|| XINT (y, 1) == UNSPEC_SUBV
|| XINT (y, 1) == UNSPEC_NEGV))
return CCVmode;
else
return CCCmode;
}
if (TARGET_ARCH64 && GET_MODE (x) == DImode) if (TARGET_ARCH64 && GET_MODE (x) == DImode)
return CCXmode; return CCXmode;
else else
...@@ -7724,10 +7737,16 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul, ...@@ -7724,10 +7737,16 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
switch (code) switch (code)
{ {
case NE: case NE:
branch = "bne"; if (mode == CCVmode || mode == CCXVmode)
branch = "bvs";
else
branch = "bne";
break; break;
case EQ: case EQ:
branch = "be"; if (mode == CCVmode || mode == CCXVmode)
branch = "bvc";
else
branch = "be";
break; break;
case GE: case GE:
if (mode == CCNZmode || mode == CCXNZmode) if (mode == CCNZmode || mode == CCXNZmode)
...@@ -7794,6 +7813,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul, ...@@ -7794,6 +7813,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
case CCmode: case CCmode:
case CCNZmode: case CCNZmode:
case CCCmode: case CCCmode:
case CCVmode:
labelno = "%%icc, "; labelno = "%%icc, ";
if (v8) if (v8)
labelno = ""; labelno = "";
...@@ -7801,6 +7821,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul, ...@@ -7801,6 +7821,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
case CCXmode: case CCXmode:
case CCXNZmode: case CCXNZmode:
case CCXCmode: case CCXCmode:
case CCXVmode:
labelno = "%%xcc, "; labelno = "%%xcc, ";
gcc_assert (!v8); gcc_assert (!v8);
break; break;
...@@ -8804,11 +8825,13 @@ sparc_print_operand (FILE *file, rtx x, int code) ...@@ -8804,11 +8825,13 @@ sparc_print_operand (FILE *file, rtx x, int code)
case CCmode: case CCmode:
case CCNZmode: case CCNZmode:
case CCCmode: case CCCmode:
case CCVmode:
s = "%icc"; s = "%icc";
break; break;
case CCXmode: case CCXmode:
case CCXNZmode: case CCXNZmode:
case CCXCmode: case CCXCmode:
case CCXVmode:
s = "%xcc"; s = "%xcc";
break; break;
default: default:
...@@ -8883,10 +8906,16 @@ sparc_print_operand (FILE *file, rtx x, int code) ...@@ -8883,10 +8906,16 @@ sparc_print_operand (FILE *file, rtx x, int code)
switch (GET_CODE (x)) switch (GET_CODE (x))
{ {
case NE: case NE:
s = "ne"; if (mode == CCVmode || mode == CCXVmode)
s = "vs";
else
s = "ne";
break; break;
case EQ: case EQ:
s = "e"; if (mode == CCVmode || mode == CCXVmode)
s = "vc";
else
s = "e";
break; break;
case GE: case GE:
if (mode == CCNZmode || mode == CCXNZmode) if (mode == CCNZmode || mode == CCXNZmode)
......
2016-10-21 Eric Botcazou <ebotcazou@adacore.com>
* gcc.target/sparc/overflow-1.c: New test.
* gcc.target/sparc/overflow-2.c: Likewise.
* gcc.target/sparc/overflow-3.c: Likewise.
2016-10-21 Andre Vieira <andre.simoesdiasvieira@arm.com> 2016-10-21 Andre Vieira <andre.simoesdiasvieira@arm.com>
* gcc.target/arm/pure-code/pure-code.exp: Require arm_cortex_m * gcc.target/arm/pure-code/pure-code.exp: Require arm_cortex_m
......
/* { dg-do compile } */
/* { dg-options "-O -mcpu=v8" } */
/* { dg-require-effective-target ilp32 } */
#include <stdbool.h>
#include <stdint.h>
bool my_uadd_overflow (uint32_t a, uint32_t b, uint32_t *res)
{
return __builtin_add_overflow (a, b, res);
}
bool my_usub_overflow (uint32_t a, uint32_t b, uint32_t *res)
{
return __builtin_sub_overflow (a, b, res);
}
bool my_uneg_overflow (uint32_t a, uint32_t *res)
{
return __builtin_sub_overflow (0, a, res);
}
bool my_add_overflow (int32_t a, int32_t b, int32_t *res)
{
return __builtin_add_overflow (a, b, res);
}
bool my_sub_overflow (int32_t a, int32_t b, int32_t *res)
{
return __builtin_sub_overflow (a, b, res);
}
bool my_neg_overflow (int32_t a, int32_t *res)
{
return __builtin_sub_overflow (0, a, res);
}
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
/* { dg-final { scan-assembler-times "addx\t%" 3 } } */
/* { dg-final { scan-assembler-times "bvs" 3 } } */
/* { dg-final { scan-assembler-not "cmp\t%" } } */
/* { dg-final { scan-assembler-not "save\t%" } } */
/* { dg-do compile } */
/* { dg-options "-O -mcpu=v8" } */
/* { dg-require-effective-target ilp32 } */
#include <stdbool.h>
#include <stdint.h>
bool my_uadd_overflow (uint64_t a, uint64_t b, uint64_t *res)
{
return __builtin_add_overflow (a, b, res);
}
bool my_usub_overflow (uint64_t a, uint64_t b, uint64_t *res)
{
return __builtin_sub_overflow (a, b, res);
}
bool my_uneg_overflow (uint64_t a, uint64_t *res)
{
return __builtin_sub_overflow (0, a, res);
}
bool my_add_overflow (int64_t a, int64_t b, int64_t *res)
{
return __builtin_add_overflow (a, b, res);
}
bool my_sub_overflow (int64_t a, int64_t b, int64_t *res)
{
return __builtin_sub_overflow (a, b, res);
}
bool my_neg_overflow (int64_t a, int64_t *res)
{
return __builtin_sub_overflow (0, a, res);
}
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "addxcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
/* { dg-final { scan-assembler-times "subxcc\t%" 4 } } */
/* { dg-final { scan-assembler-times "addx\t%" 2 } } */
/* { dg-final { scan-assembler-times "blu" 1 } } */
/* { dg-final { scan-assembler-times "bvs" 3 } } */
/* { dg-final { scan-assembler-not "cmp\t%" } } */
/* { dg-final { scan-assembler-not "save\t%" } } */
/* { dg-do compile } */
/* { dg-options "-O" } */
/* { dg-require-effective-target lp64 } */
#include <stdbool.h>
#include <stdint.h>
bool my_uadd_overflow (uint64_t a, uint64_t b, uint64_t *res)
{
return __builtin_add_overflow (a, b, res);
}
bool my_usub_overflow (uint64_t a, uint64_t b, uint64_t *res)
{
return __builtin_sub_overflow (a, b, res);
}
bool my_uneg_overflow (uint64_t a, uint64_t *res)
{
return __builtin_sub_overflow (0, a, res);
}
bool my_add_overflow (int64_t a, int64_t b, int64_t *res)
{
return __builtin_add_overflow (a, b, res);
}
bool my_sub_overflow (int64_t a, int64_t b, int64_t *res)
{
return __builtin_sub_overflow (a, b, res);
}
bool my_neg_overflow (int64_t a, int64_t *res)
{
return __builtin_sub_overflow (0, a, res);
}
/* { dg-final { scan-assembler-times "addcc\t%" 2 } } */
/* { dg-final { scan-assembler-times "subcc\t%" 4 } } */
/* { dg-final { scan-assembler-times "movlu\t%" 1 } } */
/* { dg-final { scan-assembler-times "blu" 2 } } */
/* { dg-final { scan-assembler-times "bvs" 3 } } */
/* { dg-final { scan-assembler-not "cmp\t%" } } */
/* { dg-final { scan-assembler-not "save\t%" } } */
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