From: Kyrylo Tkachov Date: Thu, 26 Sep 2019 10:48:02 +0000 (+0000) Subject: [arm] Implement DImode SIMD32 intrinsics X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2b5b5e24149160e38ff3cd98c6a911f0eba4acc5;p=gcc.git [arm] Implement DImode SIMD32 intrinsics 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_): 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fad363b93db..ac39c2f4113 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-09-26 Kyrylo Tkachov + + * config/arm/arm.md (arm_): 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 * config/arm/arm.md (arm_): New define_insn. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 99e4acde55e..d3ee59a37ad 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -5088,6 +5088,17 @@ [(set_attr "predicable" "yes") (set_attr "type" "alu_dsp_reg")]) +(define_insn "arm_" + [(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" + "%?\\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")))] diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h index 9c6f12d5566..248a355d002 100644 --- a/gcc/config/arm/arm_acle.h +++ b/gcc/config/arm/arm_acle.h @@ -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 diff --git a/gcc/config/arm/arm_acle_builtins.def b/gcc/config/arm/arm_acle_builtins.def index c675fc46dae..0021c0036ad 100644 --- a/gcc/config/arm/arm_acle_builtins.def +++ b/gcc/config/arm/arm_acle_builtins.def @@ -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) diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 538f5bf6b01..8c9f7121951 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -443,6 +443,9 @@ 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]) @@ -1051,7 +1054,9 @@ (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]) diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index 08a6cd77ce0..78f88d5fa09 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -123,6 +123,10 @@ 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. ]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d3a0af6ced1..23235930450 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-09-26 Kyrylo Tkachov + + * gcc.target/arm/acle/simd32.c: Update test. + 2019-09-26 Kyrylo Tkachov * lib/target-supports.exp diff --git a/gcc/testsuite/gcc.target/arm/acle/simd32.c b/gcc/testsuite/gcc.target/arm/acle/simd32.c index f5c116d1396..e43ea96befd 100644 --- a/gcc/testsuite/gcc.target/arm/acle/simd32.c +++ b/gcc/testsuite/gcc.target/arm/acle/simd32.c @@ -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 } } */