aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2020-07-06 01:10:54 +0200
committerHans-Peter Nilsson <hp@axis.com>2020-07-06 01:17:54 +0200
commit9596eccb9c64faa13750692b46dd0779aac0d57c (patch)
treeebcde04d5354812ffed4ce05c1e54f2a5f8cdab3
parent65f8403f1a99f965ad3ed36adc4f889cf95ee1eb (diff)
downloadgcc-9596eccb9c64faa13750692b46dd0779aac0d57c.zip
gcc-9596eccb9c64faa13750692b46dd0779aac0d57c.tar.gz
gcc-9596eccb9c64faa13750692b46dd0779aac0d57c.tar.bz2
cris: update recent patterns. Simplify cris_select_cc_mode.
The code in cris_select_cc_mode for selecting CC_NZmode was partly inconsistent with the comment and partly seemed ambiguous. I couldn't find a reason why I qualified selection of CC_NZmode on the setting operation once a matching user was spotted, so I just removed that. The cris.c update was due to observing the new test-case failing; the CC_NZmode compare wasn't eliminated. The recently re-instated adds/addu/subs/subu/bound patterns are rewritten to replace the use of match_operator with iterators. gcc: * config/cris/cris.c (cris_select_cc_mode): Always return CC_NZmode for matching comparisons. Clarify comments. * config/cris/cris-modes.def: Clarify mode comment. * config/cris/cris.md (plusminus, plusminusumin, plusumin): New code iterators. (addsub, addsubbo, nd): New code iterator attributes. ("*<addsub><su>qihi"): Rename from "*extopqihi". Use code iterator constructs instead of match_operator constructs. ("*<addsubbo><su><nd><mode>si<setnz>"): Similar from "*extop<mode>si<setnz>". ("*add<su>qihi_swap"): Similar from "*addxqihi_swap". ("*<addsubbo><su><nd><mode>si<setnz>_swap"): Similar from "*extop<mode>si<setnz>_swap". gcc/testsuite: * gcc.target/cris/pr93372-39.c: New test.
-rw-r--r--gcc/config/cris/cris-modes.def17
-rw-r--r--gcc/config/cris/cris.c16
-rw-r--r--gcc/config/cris/cris.md105
-rw-r--r--gcc/testsuite/gcc.target/cris/pr93372-39.c19
4 files changed, 90 insertions, 67 deletions
diff --git a/gcc/config/cris/cris-modes.def b/gcc/config/cris/cris-modes.def
index 1aaf12a..874e4c1 100644
--- a/gcc/config/cris/cris-modes.def
+++ b/gcc/config/cris/cris-modes.def
@@ -25,9 +25,10 @@ along with GCC; see the file COPYING3. If not see
have ordinary compares and incidental condition-code settings from
preceding instructions, setting a subset of N, Z, V and C to usable
values, from the perspective of comparing the result against zero
- (fpcraz). The two subsets meaningful to gcc are all of N, Z, V, C
- versus just N, Z; some CC-users care only about N and/or Z and some
- that care about at least one of those flags together with V and/or C.
+ (referred to below as "fpcraz"). The two subsets meaningful to gcc are
+ all of N, Z, V, C versus just N, Z; some CC-users care only about N
+ and/or Z and some that care about at least one of those flags together
+ with V and/or C.
The plain "CC_MODE (CC)" (which is always present in gcc), is used to
reflect the "unoptimized" state, where the CC-setter is a compare
@@ -37,9 +38,13 @@ along with GCC; see the file COPYING3. If not see
or if optimization of CC-setter and CC-users, when CCmode setters can
be changed or replaced by either CC_NZmode or CC_NZVCmode. To wit, all
users that require CC_NZVCmode must match only that mode at any time.
- All other users must match all CCmodes. All setters that set only
- CC_NZmode must set only that mode. All other setters must match
- setting all CCmodes. */
+ All other users must match all of CCmode, CC_NZmode, and CC_NZVCmode.
+ All setters that set only CC_NZmode must match setting only that mode.
+ All other setters must match setting all of CCmode, CC_NZmode, and
+ CC_NZVCmode.
+
+ There's also other modes (i.e. CC_ZnNmode) with a separate set of
+ setters and users not matched by the others. */
/* Z and N flags only. For a condition-code setter: only the Z and N
flags are set to usable values, fpcraz. For a condition-code user: the
diff --git a/gcc/config/cris/cris.c b/gcc/config/cris/cris.c
index 2bad939..b26b9f2 100644
--- a/gcc/config/cris/cris.c
+++ b/gcc/config/cris/cris.c
@@ -1530,21 +1530,11 @@ cris_select_cc_mode (enum rtx_code op, rtx x, rtx y)
if (GET_MODE_CLASS (GET_MODE (x)) != MODE_INT || y != const0_rtx)
return CCmode;
- /* If we have a comparison that doesn't have to look at V or C, check
- operand x; if it's a valid operator, return CC_NZmode, else CCmode,
- so we only use CC_NZmode for the cases where we don't actually have
- both V and C valid. */
+ /* If we have a comparison that doesn't have to look at V or C, return
+ CC_NZmode. */
if (op == EQ || op == NE || op == GTU || op == LEU
|| op == LT || op == GE)
- {
- enum rtx_code e = GET_CODE (x);
-
- /* Mentioning the rtx_code here is required but not sufficient: the
- insn also needs to be decorated with <setnz> (and the
- anonymization prefix <anz> for a named pattern). */
- return e == PLUS || e == MINUS || e == MULT || e == NOT || e == NEG
- ? CC_NZmode : CCmode;
- }
+ return CC_NZmode;
/* We should only get here for comparison operators. */
gcc_assert (op == GEU || op == LTU || op == GT || op == LE);
diff --git a/gcc/config/cris/cris.md b/gcc/config/cris/cris.md
index e700819..ae6a27f 100644
--- a/gcc/config/cris/cris.md
+++ b/gcc/config/cris/cris.md
@@ -183,6 +183,25 @@
(define_code_attr u [(sign_extend "") (zero_extend "u")])
(define_code_attr su [(sign_extend "s") (zero_extend "u")])
+;; For extended-operand variants.
+(define_code_iterator plusminus [plus minus])
+(define_code_attr addsub [(plus "add") (minus "sub")])
+
+;; Similar, other cases also matching bound/umin.
+(define_code_iterator plusminusumin [plus minus umin])
+
+;; Ditto, commutative operators (i.e. not minus).
+(define_code_iterator plusumin [plus umin])
+
+;; The addsubbo and nd code-attributes form a hack. We need to output
+;; "addu.b", "subu.b" but "bound.b" (no "u"-suffix) which means we'd
+;; need to refer to one iterator from the next. But, that can't be
+;; done. Instead output the "u" for unsigned as the "u" in "bound",
+;; i.e. the mnemonic as three parts including the extend-letter, and
+;; with an empty third part for "add" and "sub".
+(define_code_attr addsubbo [(plus "add") (minus "sub") (umin "bo")])
+(define_code_attr nd [(plus "") (minus "") (umin "nd")])
+
;; For the shift variants.
(define_code_iterator shift [ashiftrt lshiftrt ashift])
(define_code_iterator shiftrt [ashiftrt lshiftrt])
@@ -1113,42 +1132,37 @@
;; QImode to HImode
;; FIXME: GCC should widen.
-(define_insn "*extopqihi"
+(define_insn "*<addsub><su>qihi"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
- (match_operator:HI
- 3 "cris_additive_operand_extend_operator"
- [(match_operand:HI 1 "register_operand" "0,0,0,r")
- (match_operator:HI
- 4 "cris_extend_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])]))
+ (plusminus:HI
+ (match_operand:HI 1 "register_operand" "0,0,0,r")
+ (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To"))))
(clobber (reg:CC CRIS_CC0_REGNUM))]
"GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
- && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
+ && (operands[1] != frame_pointer_rtx || <plusminus:CODE> != PLUS)"
"@
- %x3%E4.%m4 %2,%0
- %x3%E4.%m4 %2,%0
- %x3%E4.%m4 %2,%0
- %x3%E4.%m4 %2,%1,%0"
+ <addsub><su>.b %2,%0
+ <addsub><su>.b %2,%0
+ <addsub><su>.b %2,%0
+ <addsub><su>.b %2,%1,%0"
[(set_attr "slottable" "yes,yes,no,no")
(set_attr "cc" "clobber")])
-(define_insn "*extop<mode>si<setnz>"
+;; FIXME: bound is actually also <setnzvc>, but is so rarely used in this
+;; form that it's not worthwhile to make that distinction.
+(define_insn "*<addsubbo><su><nd><mode>si<setnz>"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (match_operator:SI
- 3 "cris_operand_extend_operator"
- [(match_operand:SI 1 "register_operand" "0,0,0,r")
- (match_operator:SI
- 4 "cris_extend_operator"
- [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])]))
- (clobber (reg:CC CRIS_CC0_REGNUM))]
- "(GET_CODE (operands[3]) != UMIN || GET_CODE (operands[4]) == ZERO_EXTEND)
- && GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
- && (operands[1] != frame_pointer_rtx || GET_CODE (operands[3]) != PLUS)"
+ (plusminusumin:SI
+ (match_operand:SI 1 "register_operand" "0,0,0,r")
+ (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To"))))
+ (clobber (reg:CC CRIS_CC0_REGNUM))]
+ "(<plusminusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND)
+ && (operands[1] != frame_pointer_rtx || <plusminusumin:CODE> != PLUS)"
"@
- %x3%E4<m> %2,%0
- %x3%E4<m> %2,%0
- %x3%E4<m> %2,%0
- %x3%E4<m> %2,%1,%0"
+ <addsubbo><su><nd><m> %2,%0
+ <addsubbo><su><nd><m> %2,%0
+ <addsubbo><su><nd><m> %2,%0
+ <addsubbo><su><nd><m> %2,%1,%0"
[(set_attr "slottable" "yes,yes,no,no")])
;; We may have swapped operands for add or bound.
@@ -1156,39 +1170,34 @@
;; QImode to HImode
-(define_insn "*addxqihi_swap"
+(define_insn "*add<su>qihi_swap"
[(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
(plus:HI
- (match_operator:HI
- 3 "cris_extend_operator"
- [(match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To")])
+ (szext:HI (match_operand:QI 2 "nonimmediate_operand" "r,Q>,m,!To"))
(match_operand:HI 1 "register_operand" "0,0,0,r")))
(clobber (reg:CC CRIS_CC0_REGNUM))]
"operands[1] != frame_pointer_rtx"
"@
- add%e3.b %2,%0
- add%e3.b %2,%0
- add%e3.b %2,%0
- add%e3.b %2,%1,%0"
+ add<su>.b %2,%0
+ add<su>.b %2,%0
+ add<su>.b %2,%0
+ add<su>.b %2,%1,%0"
[(set_attr "slottable" "yes,yes,no,no")
(set_attr "cc" "clobber")])
-(define_insn "*extop<mode>si<setnz>_swap"
+(define_insn "*<addsubbo><su><nd><mode>si<setnz>_swap"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
- (match_operator:SI
- 4 "cris_plus_or_bound_operator"
- [(match_operator:SI
- 3 "cris_extend_operator"
- [(match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To")])
- (match_operand:SI 1 "register_operand" "0,0,0,r")]))
- (clobber (reg:CC CRIS_CC0_REGNUM))]
- "(GET_CODE (operands[4]) != UMIN || GET_CODE (operands[3]) == ZERO_EXTEND)
+ (plusumin:SI
+ (szext:SI (match_operand:BW 2 "nonimmediate_operand" "r,Q>,m,!To"))
+ (match_operand:SI 1 "register_operand" "0,0,0,r")))
+ (clobber (reg:CC CRIS_CC0_REGNUM))]
+ "(<plusumin:CODE> != UMIN || <szext:CODE> == ZERO_EXTEND)
&& operands[1] != frame_pointer_rtx"
"@
- %x4%E3<m> %2,%0
- %x4%E3<m> %2,%0
- %x4%E3<m> %2,%0
- %x4%E3<m> %2,%1,%0"
+ <addsubbo><su><nd><m> %2,%0
+ <addsubbo><su><nd><m> %2,%0
+ <addsubbo><su><nd><m> %2,%0
+ <addsubbo><su><nd><m> %2,%1,%0"
[(set_attr "slottable" "yes,yes,no,no")])
;; This is the special case when we use what corresponds to the
diff --git a/gcc/testsuite/gcc.target/cris/pr93372-39.c b/gcc/testsuite/gcc.target/cris/pr93372-39.c
new file mode 100644
index 0000000..6cc387f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/cris/pr93372-39.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not {\tcmp|\ttest|\tmovu|\tmovs} } } */
+/* { dg-final { scan-assembler-times "\tbound.b" 1 } } */
+/* { dg-final { scan-assembler-times "\tbound.w" 1 } } */
+
+unsigned int ub (unsigned int a, unsigned char *b, int *c)
+{
+ unsigned int d = a < *b ? a : *b;
+ *c = d == 0;
+ return d;
+}
+
+unsigned int us (unsigned int a, unsigned short *b, int *c)
+{
+ unsigned int d = a < *b ? a : *b;
+ *c = d == 0;
+ return d;
+}