Re: [PATCH][arm][2/X] Implement __qadd, __qsub, __qdbl intrinsics

2019-11-12 Thread Christophe Lyon
On Thu, 7 Nov 2019 at 11:27, Kyrill Tkachov  wrote:
>
> Hi all,
>
> 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.
>
> Bootstrapped and tested on arm-none-linux-gnueabihf.
>
> Committing to trunk.
> Thanks,
> Kyrill
>
> 2019-11-07  Kyrylo Tkachov  
>
>  * config/arm/arm.md (arm_): New define_expand.
>  (arm__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  
>
>  * gcc.target/arm/acle/dsp_arith.c: New test.
>

Hi Kyrill,

This new test fails when gcc is configured --with-cpu=cortex-m3:
FAIL: gcc.target/arm/acle/dsp_arith.c   -O0  (test for excess errors)
Excess errors:
/gcc/testsuite/gcc.target/arm/acle/dsp_arith.c:10:10: warning:
implicit declaration of function '__qadd'
[-Wimplicit-function-declaration]
/gcc/testsuite/gcc.target/arm/acle/dsp_arith.c:16:10: warning:
implicit declaration of function '__qdbl'
[-Wimplicit-function-declaration]
/gcc/testsuite/gcc.target/arm/acle/dsp_arith.c:24:10: warning:
implicit declaration of function '__qsub'
[-Wimplicit-function-declaration]

The new intrinsics are defined under __ARM_FEATURE_DSP but the
arm_qbit_flags effective target passes with "" as flags.

Christophe


[PATCH][arm][2/X] Implement __qadd, __qsub, __qdbl intrinsics

2019-11-07 Thread Kyrill Tkachov

Hi all,

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.


Bootstrapped and tested on arm-none-linux-gnueabihf.

Committing to trunk.
Thanks,
Kyrill

2019-11-07  Kyrylo Tkachov  

    * config/arm/arm.md (arm_): New define_expand.
    (arm__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  

    * gcc.target/arm/acle/dsp_arith.c: New test.

diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 09b632b5dbc8b38dcca22494468366c97a514bb6..db7a4006eb4f354e08f22c666fea8f1e87726085 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4076,6 +4076,32 @@
(set_attr "type" "multiple")]
 )
 
+
+(define_expand "arm_"
+  [(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__setq_insn (operands[0],
+	operands[1], operands[2]));
+else
+  emit_insn (gen_arm__insn (operands[0], operands[1], operands[2]));
+DONE;
+  }
+)
+
+(define_insn "arm__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 && "
+  "%?\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 2564ad849856610f9415586e386f85eea6947bf7..397653d3e8bf43cbcb82d98dd704bcd3a66cf782 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 c72480321faa952ac307418f9e4f7d5f5f9e3745..def1a569311e67194a323decc309ed92747c4c86 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 e5cef6852a2dfcef4cd3597c163a53a6c247afab..ebb8218f265023786730881ef0bc9f818e7235b0 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/gcc.target/arm/acle/dsp_arith.c b/gcc/testsuite/gcc.target/arm/acle/dsp_arith.c
new file mode 100644
index ..f0bf80993beb0007b0eb360878f0fd1811098d9e
--- /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 
+
+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...?,