aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>2019-11-07 10:41:21 +0000
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>2019-11-07 10:41:21 +0000
commite56d199b04fb7cde9b6ef423175883d852de78b4 (patch)
tree9fea645d7de95ba8bfa7ffa9492acee42a8c8b1f
parentcf16f980e5278c146f04587ea2a378fab950d7b3 (diff)
downloadgcc-e56d199b04fb7cde9b6ef423175883d852de78b4.zip
gcc-e56d199b04fb7cde9b6ef423175883d852de78b4.tar.gz
gcc-e56d199b04fb7cde9b6ef423175883d852de78b4.tar.bz2
[arm][2/X] Implement __qadd, __qsub, __qdbl intrinsics
This patch implements some more Q-bit-setting intrinsics from ACLE. With the plumbing from patch 1 in place they are a simple builtin->RTL affair. * config/arm/arm.md (arm_<ss_op>): New define_expand. (arm_<ss_op><add_clobber_q_name>_insn): New define_insn. * config/arm/arm_acle.h (__qadd, __qsub, __qdbl): Define. * config/arm/arm_acle_builtins.def: Add builtins for qadd, qsub. * config/arm/iterators.md (SSPLUSMINUS): New code iterator. (ss_op): New code_attr. * gcc.target/arm/acle/dsp_arith.c: New test. From-SVN: r277915
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/arm/arm.md26
-rw-r--r--gcc/config/arm/arm_acle.h23
-rw-r--r--gcc/config/arm/arm_acle_builtins.def2
-rw-r--r--gcc/config/arm/iterators.md5
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/arm/acle/dsp_arith.c27
7 files changed, 96 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 51a301e..53de082 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,14 @@
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+ * config/arm/arm.md (arm_<ss_op>): New define_expand.
+ (arm_<ss_op><add_clobber_q_name>_insn): New define_insn.
+ * config/arm/arm_acle.h (__qadd, __qsub, __qdbl): Define.
+ * config/arm/arm_acle_builtins.def: Add builtins for qadd, qsub.
+ * config/arm/iterators.md (SSPLUSMINUS): New code iterator.
+ (ss_op): New code_attr.
+
+2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
* config/arm/aout.h (REGISTER_NAMES): Add apsrq.
* config/arm/arm.md (APSRQ_REGNUM): Define.
(add_setq): New define_subst.
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 992d7b6..298b0be 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4076,6 +4076,32 @@
(set_attr "type" "multiple")]
)
+
+(define_expand "arm_<ss_op>"
+ [(set (match_operand:SI 0 "s_register_operand")
+ (SSPLUSMINUS:SI (match_operand:SI 1 "s_register_operand")
+ (match_operand:SI 2 "s_register_operand")))]
+ "TARGET_DSP_MULTIPLY"
+ {
+ if (ARM_Q_BIT_READ)
+ emit_insn (gen_arm_<ss_op>_setq_insn (operands[0],
+ operands[1], operands[2]));
+ else
+ emit_insn (gen_arm_<ss_op>_insn (operands[0], operands[1], operands[2]));
+ DONE;
+ }
+)
+
+(define_insn "arm_<ss_op><add_clobber_q_name>_insn"
+ [(set (match_operand:SI 0 "s_register_operand" "=r")
+ (SSPLUSMINUS:SI (match_operand:SI 1 "s_register_operand" "r")
+ (match_operand:SI 2 "s_register_operand" "r")))]
+ "TARGET_DSP_MULTIPLY && <add_clobber_q_pred>"
+ "<ss_op>%?\t%0, %1, %2"
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "alu_dsp_reg")]
+)
+
(define_code_iterator SAT [smin smax])
(define_code_attr SATrev [(smin "smax") (smax "smin")])
(define_code_attr SATlo [(smin "1") (smax "2")])
diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h
index 2564ad8..397653d 100644
--- a/gcc/config/arm/arm_acle.h
+++ b/gcc/config/arm/arm_acle.h
@@ -478,6 +478,29 @@ __ignore_saturation (void)
})
#endif
+#ifdef __ARM_FEATURE_DSP
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__qadd (int32_t __a, int32_t __b)
+{
+ return __builtin_arm_qadd (__a, __b);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__qsub (int32_t __a, int32_t __b)
+{
+ return __builtin_arm_qsub (__a, __b);
+}
+
+__extension__ extern __inline int32_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__qdbl (int32_t __x)
+{
+ return __qadd (__x, __x);
+}
+#endif
+
#pragma GCC push_options
#ifdef __ARM_FEATURE_CRC32
#ifdef __ARM_FP
diff --git a/gcc/config/arm/arm_acle_builtins.def b/gcc/config/arm/arm_acle_builtins.def
index c724803..def1a56 100644
--- a/gcc/config/arm/arm_acle_builtins.def
+++ b/gcc/config/arm/arm_acle_builtins.def
@@ -84,3 +84,5 @@ VAR1 (SAT_BINOP_UNSIGNED_IMM, ssat, si)
VAR1 (UNSIGNED_SAT_BINOP_UNSIGNED_IMM, usat, si)
VAR1 (SAT_OCCURRED, saturation_occurred, si)
VAR1 (SET_SAT, set_saturation, void)
+VAR1 (BINOP, qadd, si)
+VAR1 (BINOP, qsub, si)
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index e5cef68..ebb8218 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -264,6 +264,9 @@
;; Conversions.
(define_code_iterator FCVT [unsigned_float float])
+;; Saturating addition, subtraction
+(define_code_iterator SSPLUSMINUS [ss_plus ss_minus])
+
;; plus and minus are the only SHIFTABLE_OPS for which Thumb2 allows
;; a stack pointer operand. The minus operation is a candidate for an rsub
;; and hence only plus is supported.
@@ -282,6 +285,8 @@
(define_code_attr vfml_op [(plus "a") (minus "s")])
+(define_code_attr ss_op [(ss_plus "qadd") (ss_minus "qsub")])
+
;;----------------------------------------------------------------------------
;; Int iterators
;;----------------------------------------------------------------------------
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index f7318b0..05183b0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,9 @@
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+ * gcc.target/arm/acle/dsp_arith.c: New test.
+
+2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
* gcc.target/arm/acle/saturation.c: New test.
* gcc.target/arm/acle/sat_no_smlatb.c: Likewise.
* lib/target-supports.exp (check_effective_target_arm_qbit_ok_nocache):
diff --git a/gcc/testsuite/gcc.target/arm/acle/dsp_arith.c b/gcc/testsuite/gcc.target/arm/acle/dsp_arith.c
new file mode 100644
index 0000000..f0bf809
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/acle/dsp_arith.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_qbit_ok } */
+/* { dg-add-options arm_qbit } */
+
+#include <arm_acle.h>
+
+int32_t
+test_qadd (int32_t a, int32_t b)
+{
+ return __qadd (a, b);
+}
+
+int32_t
+test_qdbl (int32_t a)
+{
+ return __qdbl(a);
+}
+
+/* { dg-final { scan-assembler-times "qadd\t...?, ...?, ...?" 2 } } */
+
+int32_t
+test_qsub (int32_t a, int32_t b)
+{
+ return __qsub (a, b);
+}
+
+/* { dg-final { scan-assembler-times "qsub\t...?, ...?, ...?" 1 } } */