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>
PR rtl-optimization/78038
......
......@@ -420,6 +420,10 @@
(define_predicate "c_comparison_operator"
(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
;; the use of MATCH_OPERATOR to recognize all the branch insns.
(define_predicate "icc_comparison_operator"
......@@ -436,6 +440,9 @@
case CCCmode:
case CCXCmode:
return c_comparison_operator (op, mode);
case CCVmode:
case CCXVmode:
return v_comparison_operator (op, mode);
default:
return false;
}
......
......@@ -34,6 +34,10 @@ FLOAT_MODE (TF, 16, ieee_quad_format);
they explicitly set the C flag (unsigned overflow). Only the unsigned
<,>= 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
in the floating-point condition code register. One for comparisons which
will generate an exception if the result is unordered (CCFPEmode) and
......@@ -46,6 +50,8 @@ CC_MODE (CCNZ);
CC_MODE (CCXNZ);
CC_MODE (CCC);
CC_MODE (CCXC);
CC_MODE (CCV);
CC_MODE (CCXV);
CC_MODE (CCFP);
CC_MODE (CCFPE);
......
......@@ -2784,8 +2784,9 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y)
gcc_unreachable ();
}
}
else if (GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|| GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT)
else if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS
|| GET_CODE (x) == NEG || GET_CODE (x) == ASHIFT)
&& y == const0_rtx)
{
if (TARGET_ARCH64 && GET_MODE (x) == DImode)
return CCXNZmode;
......@@ -2803,6 +2804,18 @@ select_cc_mode (enum rtx_code op, rtx x, rtx y)
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)
return CCXmode;
else
......@@ -7724,10 +7737,16 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
switch (code)
{
case NE:
branch = "bne";
if (mode == CCVmode || mode == CCXVmode)
branch = "bvs";
else
branch = "bne";
break;
case EQ:
branch = "be";
if (mode == CCVmode || mode == CCXVmode)
branch = "bvc";
else
branch = "be";
break;
case GE:
if (mode == CCNZmode || mode == CCXNZmode)
......@@ -7794,6 +7813,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
case CCmode:
case CCNZmode:
case CCCmode:
case CCVmode:
labelno = "%%icc, ";
if (v8)
labelno = "";
......@@ -7801,6 +7821,7 @@ output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
case CCXmode:
case CCXNZmode:
case CCXCmode:
case CCXVmode:
labelno = "%%xcc, ";
gcc_assert (!v8);
break;
......@@ -8804,11 +8825,13 @@ sparc_print_operand (FILE *file, rtx x, int code)
case CCmode:
case CCNZmode:
case CCCmode:
case CCVmode:
s = "%icc";
break;
case CCXmode:
case CCXNZmode:
case CCXCmode:
case CCXVmode:
s = "%xcc";
break;
default:
......@@ -8883,10 +8906,16 @@ sparc_print_operand (FILE *file, rtx x, int code)
switch (GET_CODE (x))
{
case NE:
s = "ne";
if (mode == CCVmode || mode == CCXVmode)
s = "vs";
else
s = "ne";
break;
case EQ:
s = "e";
if (mode == CCVmode || mode == CCXVmode)
s = "vc";
else
s = "e";
break;
case GE:
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>
* 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