[arm] Implement DImode SIMD32 intrinsics
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Thu, 26 Sep 2019 10:48:02 +0000 (10:48 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Thu, 26 Sep 2019 10:48:02 +0000 (10:48 +0000)
This patch implements some more SIMD32, but these ones have a DImode result+addend.
Apart from that there's nothing too exciting about them.

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

* config/arm/arm.md (arm_<simd32_op>): New define_insn.
* config/arm/arm_acle.h (__smlald, __smlaldx, __smlsld, __smlsldx):
Define.
* config/arm/arm_acle.h: Define builtins for the above.
* config/arm/iterators.md (SIMD32_DIMODE): New int_iterator.
(simd32_op): Handle the above.
* config/arm/unspecs.md: Define unspecs for the above.

* gcc.target/arm/acle/simd32.c: Update test.

From-SVN: r276147

gcc/ChangeLog
gcc/config/arm/arm.md
gcc/config/arm/arm_acle.h
gcc/config/arm/arm_acle_builtins.def
gcc/config/arm/iterators.md
gcc/config/arm/unspecs.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arm/acle/simd32.c

index fad363b93db91b570d3b6e6d2b08aeabdb21c1bf..ac39c2f411341c0b7d7659fdba7d86a7995c62aa 100644 (file)
@@ -1,3 +1,13 @@
+2019-09-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/arm/arm.md (arm_<simd32_op>): New define_insn.
+       * config/arm/arm_acle.h (__smlald, __smlaldx, __smlsld, __smlsldx):
+       Define.
+       * config/arm/arm_acle.h: Define builtins for the above.
+       * config/arm/iterators.md (SIMD32_DIMODE): New int_iterator.
+       (simd32_op): Handle the above.
+       * config/arm/unspecs.md: Define unspecs for the above.
+
 2019-09-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/arm/arm.md (arm_<simd32_op>): New define_insn.
index 99e4acde55e1e7520d88abde6294b872e5210485..d3ee59a37ade9c2921fb8895543a143b74d7bbdf 100644 (file)
   [(set_attr "predicable" "yes")
    (set_attr "type" "alu_dsp_reg")])
 
+(define_insn "arm_<simd32_op>"
+  [(set (match_operand:DI 0 "s_register_operand" "=r")
+       (unspec:DI
+         [(match_operand:SI 1 "s_register_operand" "r")
+          (match_operand:SI 2 "s_register_operand" "r")
+          (match_operand:DI 3 "s_register_operand" "0")] SIMD32_DIMODE))]
+  "TARGET_INT_SIMD"
+  "<simd32_op>%?\\t%Q0, %R0, %1, %2"
+  [(set_attr "predicable" "yes")
+   (set_attr "type" "smlald")])
+
 (define_expand "extendsfdf2"
   [(set (match_operand:DF                  0 "s_register_operand")
        (float_extend:DF (match_operand:SF 1 "s_register_operand")))]
index 9c6f12d556654b094a23a327c030820172a03a4c..248a355d00239a8724e46b9203c818906a4d4908 100644 (file)
@@ -403,8 +403,37 @@ __usada8 (uint8x4_t __a, uint8x4_t __b, uint32_t __c)
   return __builtin_arm_usada8 (__a, __b, __c);
 }
 
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smlald (int16x2_t __a, int16x2_t __b, int64_t __c)
+{
+  return __builtin_arm_smlald (__a, __b, __c);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smlaldx (int16x2_t __a, int16x2_t __b, int64_t __c)
+{
+  return __builtin_arm_smlaldx (__a, __b, __c);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smlsld (int16x2_t __a, int16x2_t __b, int64_t __c)
+{
+  return __builtin_arm_smlsld (__a, __b, __c);
+}
+
+__extension__ extern __inline int64_t
+__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
+__smlsldx (int16x2_t __a, int16x2_t __b, int64_t __c)
+{
+  return __builtin_arm_smlsldx (__a, __b, __c);
+}
+
 #endif
 
+
 #pragma GCC push_options
 #ifdef __ARM_FEATURE_CRC32
 #ifdef __ARM_FP
index c675fc46dae6552b8762e9bbb6147d8a6d15133a..0021c0036ad7e1bddef6553a900c9eaf145037b6 100644 (file)
@@ -75,3 +75,7 @@ VAR1 (BINOP, smusd, si)
 VAR1 (BINOP, smusdx, si)
 VAR1 (UBINOP, usad8, si)
 VAR1 (UBINOP, usada8, si)
+VAR1 (TERNOP, smlald, di)
+VAR1 (TERNOP, smlaldx, di)
+VAR1 (TERNOP, smlsld, di)
+VAR1 (TERNOP, smlsldx, di)
index 538f5bf6b0116f49b27eef589b0140aa7792e976..8c9f7121951ba319fcb6cf4c73e186f3764917c2 100644 (file)
                                 UNSPEC_UQSUB16 UNSPEC_SMUSD UNSPEC_SMUSDX
                                 UNSPEC_SXTAB16 UNSPEC_UXTAB16 UNSPEC_USAD8])
 
+(define_int_iterator SIMD32_DIMODE [UNSPEC_SMLALD UNSPEC_SMLALDX
+                                   UNSPEC_SMLSLD UNSPEC_SMLSLDX])
+
 (define_int_iterator VQRDMLH_AS [UNSPEC_VQRDMLAH UNSPEC_VQRDMLSH])
 
 (define_int_iterator VFM_LANE_AS [UNSPEC_VFMA_LANE UNSPEC_VFMS_LANE])
                            (UNSPEC_UQSAX "uqsax") (UNSPEC_UQSUB16 "uqsub16")
                            (UNSPEC_SMUSD "smusd") (UNSPEC_SMUSDX "smusdx")
                            (UNSPEC_SXTAB16 "sxtab16") (UNSPEC_UXTAB16 "uxtab16")
-                           (UNSPEC_USAD8 "usad8")])
+                           (UNSPEC_USAD8 "usad8") (UNSPEC_SMLALD "smlald")
+                           (UNSPEC_SMLALDX "smlaldx") (UNSPEC_SMLSLD "smlsld")
+                           (UNSPEC_SMLSLDX "smlsldx")])
 
 ;; Both kinds of return insn.
 (define_code_iterator RETURNS [return simple_return])
index 08a6cd77ce08d8c9cf42abcf3c9277b769043cfd..78f88d5fa09f424a9ab638053cc4fe068aa19368 100644 (file)
   UNSPEC_SMUSDX                ; Represent the SMUSDX operation.
   UNSPEC_USAD8         ; Represent the USAD8 operation.
   UNSPEC_USADA8                ; Represent the USADA8 operation.
+  UNSPEC_SMLALD                ; Represent the SMLALD operation.
+  UNSPEC_SMLALDX       ; Represent the SMLALDX operation.
+  UNSPEC_SMLSLD                ; Represent the SMLSLD operation.
+  UNSPEC_SMLSLDX       ; Represent the SMLSLDX operation.
 ])
 
 
index d3a0af6ced1612794eb2ce8946c284a3fbd58ff0..2323593045023b6107e2ed794ea66eabeb7a4c16 100644 (file)
@@ -1,3 +1,7 @@
+2019-09-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/arm/acle/simd32.c: Update test.
+
 2019-09-26  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * lib/target-supports.exp
index f5c116d13968eefa42bea86b1e44bba8c66d7b77..e43ea96befdcbc581f61cb3fa798a49f13cd640a 100644 (file)
@@ -244,3 +244,35 @@ test_usada8 (uint8x4_t a, uint8x4_t b, uint32_t c)
 }
 
 /* { dg-final { scan-assembler-times "\tusada8\t...?, ...?, ...?, ...?" 1 } } */
+
+int64_t
+test_smlald (int16x2_t a, int16x2_t b, int64_t c)
+{
+  return __smlald (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmlald\t...?, ...?, ...?, ...?" 1 } } */
+
+int64_t
+test_smlaldx (int16x2_t a, int16x2_t b, int64_t c)
+{
+  return __smlaldx (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmlaldx\t...?, ...?, ...?, ...?" 1 } } */
+
+int64_t
+test_smlsld (int16x2_t a, int16x2_t b, int64_t c)
+{
+  return __smlsld (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmlsld\t...?, ...?, ...?, ...?" 1 } } */
+
+int64_t
+test_smlsldx (int16x2_t a, int16x2_t b, int64_t c)
+{
+  return __smlsldx (a, b, c);
+}
+
+/* { dg-final { scan-assembler-times "\tsmlsldx\t...?, ...?, ...?, ...?" 1 } } */