aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2020-01-09 15:15:17 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2020-01-09 15:15:17 +0000
commit694e6b194b584505e10e89d373eba095df960f26 (patch)
tree68f6b7d5ce669f197da6d34b766ae5e9d7ab6166
parent2e828dfe91a39a7a898ca6d8827048760e08b236 (diff)
downloadgcc-694e6b194b584505e10e89d373eba095df960f26.zip
gcc-694e6b194b584505e10e89d373eba095df960f26.tar.gz
gcc-694e6b194b584505e10e89d373eba095df960f26.tar.bz2
[AArch64] Tweak iterator usage for [SU]Q{ADD,SUB}
The pattern: ;; <su>q<addsub> (define_insn "aarch64_<su_optab><optab><mode>" [(set (match_operand:VSDQ_I 0 "register_operand" "=w") (BINQOPS:VSDQ_I (match_operand:VSDQ_I 1 "register_operand" "w") (match_operand:VSDQ_I 2 "register_operand" "w")))] "TARGET_SIMD" "<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>" [(set_attr "type" "neon_<optab><q>")] ) meant that we overloaded "optab" to be "qadd" for both SQADD and UQADD. Most other "optab" entries are instead the full optab name, which for these patterns would be "ssadd" and "usadd" respectively. (Unfortunately, the optabs don't extend to vectors yet, something that would be good to fix in GCC 11.) This patch therefore does what the comment implies and uses q<addsub> to distinguish qadd and qsub instead. 2020-01-09 Richard Sandiford <richard.sandiford@arm.com> gcc/ * config/aarch64/iterators.md (addsub): New code attribute. * config/aarch64/aarch64-simd.md (aarch64_<su_optab><optab><mode>): Re-express as... (aarch64_<su_optab>q<addsub><mode>): ...this, making the same change in the asm string and attributes. Fix indentation. * config/aarch64/aarch64-sve.md (@aarch64_<su_optab><optab><mode>): Re-express as... (@aarch64_sve_<optab><mode>): ...this. * config/aarch64/aarch64-sve-builtins.h (function_expander::expand_signed_unpred_op): Delete. * config/aarch64/aarch64-sve-builtins.cc (function_expander::expand_signed_unpred_op): Likewise. (function_expander::map_to_rtx_codes): If the optab isn't defined, try using code_for_aarch64_sve instead. * config/aarch64/aarch64-sve-builtins-base.cc (svqadd_impl): Delete. (svqsub_impl): Likewise. (svqadd, svqsub): Use rtx_code_function instead. From-SVN: r280050
-rw-r--r--gcc/ChangeLog20
-rw-r--r--gcc/config/aarch64/aarch64-simd.md8
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins-base.cc24
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins.cc31
-rw-r--r--gcc/config/aarch64/aarch64-sve-builtins.h1
-rw-r--r--gcc/config/aarch64/aarch64-sve.md4
-rw-r--r--gcc/config/aarch64/iterators.md13
7 files changed, 50 insertions, 51 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4c320ac..7efa28c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,25 @@
2020-01-09 Richard Sandiford <richard.sandiford@arm.com>
+ * config/aarch64/iterators.md (addsub): New code attribute.
+ * config/aarch64/aarch64-simd.md (aarch64_<su_optab><optab><mode>):
+ Re-express as...
+ (aarch64_<su_optab>q<addsub><mode>): ...this, making the same change
+ in the asm string and attributes. Fix indentation.
+ * config/aarch64/aarch64-sve.md (@aarch64_<su_optab><optab><mode>):
+ Re-express as...
+ (@aarch64_sve_<optab><mode>): ...this.
+ * config/aarch64/aarch64-sve-builtins.h
+ (function_expander::expand_signed_unpred_op): Delete.
+ * config/aarch64/aarch64-sve-builtins.cc
+ (function_expander::expand_signed_unpred_op): Likewise.
+ (function_expander::map_to_rtx_codes): If the optab isn't defined,
+ try using code_for_aarch64_sve instead.
+ * config/aarch64/aarch64-sve-builtins-base.cc (svqadd_impl): Delete.
+ (svqsub_impl): Likewise.
+ (svqadd, svqsub): Use rtx_code_function instead.
+
+2020-01-09 Richard Sandiford <richard.sandiford@arm.com>
+
* config/aarch64/iterators.md (SRHSUB, URHSUB): Delete.
(HADDSUB, sur, addsub): Remove them.
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 4e28cf9..b82d7b6 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -3696,13 +3696,13 @@
)
;; <su>q<addsub>
-(define_insn "aarch64_<su_optab><optab><mode>"
+(define_insn "aarch64_<su_optab>q<addsub><mode>"
[(set (match_operand:VSDQ_I 0 "register_operand" "=w")
(BINQOPS:VSDQ_I (match_operand:VSDQ_I 1 "register_operand" "w")
- (match_operand:VSDQ_I 2 "register_operand" "w")))]
+ (match_operand:VSDQ_I 2 "register_operand" "w")))]
"TARGET_SIMD"
- "<su_optab><optab>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
- [(set_attr "type" "neon_<optab><q>")]
+ "<su_optab>q<addsub>\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
+ [(set_attr "type" "neon_q<addsub><q>")]
)
;; suqadd and usqadd
diff --git a/gcc/config/aarch64/aarch64-sve-builtins-base.cc b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
index 556e9a2..48af479 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins-base.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins-base.cc
@@ -1727,16 +1727,6 @@ public:
}
};
-class svqadd_impl : public function_base
-{
-public:
- rtx
- expand (function_expander &e) const OVERRIDE
- {
- return e.expand_signed_unpred_op (SS_PLUS, US_PLUS);
- }
-};
-
/* Implements svqdec[bhwd]{,_pat} and svqinc[bhwd]{,_pat}. */
class svqdec_svqinc_bhwd_impl : public function_base
{
@@ -1838,16 +1828,6 @@ public:
rtx_code m_code_for_uint;
};
-class svqsub_impl : public function_base
-{
-public:
- rtx
- expand (function_expander &e) const OVERRIDE
- {
- return e.expand_signed_unpred_op (SS_MINUS, US_MINUS);
- }
-};
-
class svrdffr_impl : public function_base
{
public:
@@ -2661,7 +2641,7 @@ FUNCTION (svptest_first, svptest_impl, (LT))
FUNCTION (svptest_last, svptest_impl, (LTU))
FUNCTION (svptrue, svptrue_impl,)
FUNCTION (svptrue_pat, svptrue_pat_impl,)
-FUNCTION (svqadd, svqadd_impl,)
+FUNCTION (svqadd, rtx_code_function, (SS_PLUS, US_PLUS, -1))
FUNCTION (svqdecb, svqdec_bhwd_impl, (QImode))
FUNCTION (svqdecb_pat, svqdec_bhwd_impl, (QImode))
FUNCTION (svqdecd, svqdec_bhwd_impl, (DImode))
@@ -2680,7 +2660,7 @@ FUNCTION (svqinch_pat, svqinc_bhwd_impl, (HImode))
FUNCTION (svqincp, svqdecp_svqincp_impl, (SS_PLUS, US_PLUS))
FUNCTION (svqincw, svqinc_bhwd_impl, (SImode))
FUNCTION (svqincw_pat, svqinc_bhwd_impl, (SImode))
-FUNCTION (svqsub, svqsub_impl,)
+FUNCTION (svqsub, rtx_code_function, (SS_MINUS, US_MINUS, -1))
FUNCTION (svrbit, unspec_based_function, (UNSPEC_RBIT, UNSPEC_RBIT, -1))
FUNCTION (svrdffr, svrdffr_impl,)
FUNCTION (svrecpe, unspec_based_function, (-1, -1, UNSPEC_FRECPE))
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.cc b/gcc/config/aarch64/aarch64-sve-builtins.cc
index d62c50f..b09067c 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.cc
+++ b/gcc/config/aarch64/aarch64-sve-builtins.cc
@@ -2871,7 +2871,10 @@ function_expander::use_contiguous_store_insn (insn_code icode)
(3) a normal unpredicated optab for PRED_none and PRED_x functions,
dropping the predicate in the latter case
- (4) "cond_<optab><mode>" otherwise
+ (4) an unpredicated "aarch64_sve_<code_optab><mode>" for PRED_none and
+ PRED_x functions, again dropping the predicate for PRED_x
+
+ (5) "cond_<optab><mode>" otherwise
where <optab> corresponds to:
@@ -2879,6 +2882,9 @@ function_expander::use_contiguous_store_insn (insn_code icode)
- CODE_FOR_UINT for unsigned integers
- UNSPEC_FOR_FP for floating-point values
+ and where <code_optab> is like <optab>, but uses CODE_FOR_SINT instead
+ of UNSPEC_FOR_FP for floating-point values.
+
MERGE_ARGNO is the argument that provides the values of inactive lanes for
_m functions, or DEFAULT_MERGE_ARGNO if we should apply the usual rules. */
rtx
@@ -2913,7 +2919,12 @@ function_expander::map_to_rtx_codes (rtx_code code_for_sint,
/* Otherwise expand PRED_none and PRED_x operations without a predicate.
Floating-point operations conventionally use the signed rtx code. */
if (pred == PRED_none || pred == PRED_x)
- return use_unpred_insn (direct_optab_handler (code_to_optab (code), 0));
+ {
+ icode = direct_optab_handler (code_to_optab (code), 0);
+ if (icode == CODE_FOR_nothing)
+ icode = code_for_aarch64_sve (code, mode);
+ return use_unpred_insn (icode);
+ }
/* Don't use cond_*_optabs here, since not all codes have one yet. */
if (type_suffix (0).integer_p)
@@ -2964,22 +2975,6 @@ function_expander::map_to_unspecs (int unspec_for_sint, int unspec_for_uint,
return use_cond_insn (icode, merge_argno);
}
-/* Implement the call using an @aarch64 instruction and the
- instructions are parameterized by an rtx_code. CODE_FOR_SINT
- is the rtx_code for signed integer operations, CODE_FOR_UINT
- is the rtx_code for unsigned integer operations. */
-rtx
-function_expander::expand_signed_unpred_op (rtx_code code_for_sint,
- rtx_code code_for_uint)
-{
- insn_code icode;
- if (type_suffix (0).unsigned_p)
- icode = code_for_aarch64 (code_for_uint, code_for_uint, vector_mode (0));
- else
- icode = code_for_aarch64 (code_for_sint, code_for_sint, vector_mode (0));
- return use_unpred_insn (icode);
-}
-
/* Expand the call and return its lhs. */
rtx
function_expander::expand ()
diff --git a/gcc/config/aarch64/aarch64-sve-builtins.h b/gcc/config/aarch64/aarch64-sve-builtins.h
index 14ca7b1..7d07c10 100644
--- a/gcc/config/aarch64/aarch64-sve-builtins.h
+++ b/gcc/config/aarch64/aarch64-sve-builtins.h
@@ -554,7 +554,6 @@ public:
rtx map_to_rtx_codes (rtx_code, rtx_code, int,
unsigned int = DEFAULT_MERGE_ARGNO);
rtx map_to_unspecs (int, int, int, unsigned int = DEFAULT_MERGE_ARGNO);
- rtx expand_signed_unpred_op (rtx_code, rtx_code);
/* The function call expression. */
tree call_expr;
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index 59bf4a6..fb33260 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -3879,7 +3879,7 @@
;; -------------------------------------------------------------------------
;; Unpredicated saturating signed addition and subtraction.
-(define_insn "@aarch64_<su_optab><optab><mode>"
+(define_insn "@aarch64_sve_<optab><mode>"
[(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, w, ?&w, ?&w, w")
(SBINQOPS:SVE_FULL_I
(match_operand:SVE_FULL_I 1 "register_operand" "0, 0, w, w, w")
@@ -3895,7 +3895,7 @@
)
;; Unpredicated saturating unsigned addition and subtraction.
-(define_insn "@aarch64_<su_optab><optab><mode>"
+(define_insn "@aarch64_sve_<optab><mode>"
[(set (match_operand:SVE_FULL_I 0 "register_operand" "=w, ?&w, w")
(UBINQOPS:SVE_FULL_I
(match_operand:SVE_FULL_I 1 "register_operand" "0, w, w")
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 27cbda3..dab3e4d 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1577,10 +1577,10 @@
(mult "mul")
(div "div")
(udiv "udiv")
- (ss_plus "qadd")
- (us_plus "qadd")
- (ss_minus "qsub")
- (us_minus "qsub")
+ (ss_plus "ssadd")
+ (us_plus "usadd")
+ (ss_minus "sssub")
+ (us_minus "ussub")
(ss_neg "qneg")
(ss_abs "qabs")
(smin "smin")
@@ -1599,6 +1599,11 @@
(gtu "gtu")
(abs "abs")])
+(define_code_attr addsub [(ss_plus "add")
+ (us_plus "add")
+ (ss_minus "sub")
+ (us_minus "sub")])
+
;; For comparison operators we use the FCM* and CM* instructions.
;; As there are no CMLE or CMLT instructions which act on 3 vector
;; operands, we must use CMGE or CMGT and swap the order of the