[AArch64] Add support for __jcvt intrinsic
authorKyrylo Tkachov <kyrylo.tkachov@arm.com>
Tue, 3 Sep 2019 08:40:30 +0000 (08:40 +0000)
committerKyrylo Tkachov <ktkachov@gcc.gnu.org>
Tue, 3 Sep 2019 08:40:30 +0000 (08:40 +0000)
This patch implements the __jcvt ACLE intrinsic [1] that maps down to the FJCVTZS [2] instruction from Armv8.3-a.
No fancy mode iterators or nothing. Just a single builtin, UNSPEC and define_insn and the associate plumbing.
This patch also defines __ARM_FEATURE_JCVT to indicate when the intrinsic is available.

[1] https://developer.arm.com/docs/101028/latest/data-processing-intrinsics
[2] https://developer.arm.com/docs/ddi0596/latest/simd-and-floating-point-instructions-alphabetic-order/fjcvtzs-floating-point-javascript-convert-to-signed-fixed-point-rounding-toward-zero

* config/aarch64/aarch64.md (UNSPEC_FJCVTZS): Define.
(aarch64_fjcvtzs): New define_insn.
* config/aarch64/aarch64.h (TARGET_JSCVT): Define.
* config/aarch64/aarch64-builtins.c (aarch64_builtins):
Add AARCH64_JSCVT.
(aarch64_init_builtins): Initialize __builtin_aarch64_jcvtzs.
(aarch64_expand_builtin): Handle AARCH64_JSCVT.
* config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define
__ARM_FEATURE_JCVT where appropriate.
* config/aarch64/arm_acle.h (__jcvt): Define.

* gcc.target/aarch64/acle/jcvt_1.c: New test.

From-SVN: r275335

gcc/ChangeLog
gcc/config/aarch64/aarch64-builtins.c
gcc/config/aarch64/aarch64-c.c
gcc/config/aarch64/aarch64.h
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/arm_acle.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c [new file with mode: 0644]

index c6df07843fc2591d07216ed1ba593690cf97c320..401cfdae47187f51fb30de875f0ed8d142b9bb8f 100644 (file)
@@ -1,3 +1,16 @@
+2019-09-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * config/aarch64/aarch64.md (UNSPEC_FJCVTZS): Define.
+       (aarch64_fjcvtzs): New define_insn.
+       * config/aarch64/aarch64.h (TARGET_JSCVT): Define.
+       * config/aarch64/aarch64-builtins.c (aarch64_builtins):
+       Add AARCH64_JSCVT.
+       (aarch64_init_builtins): Initialize __builtin_aarch64_jcvtzs.
+       (aarch64_expand_builtin): Handle AARCH64_JSCVT.
+       * config/aarch64/aarch64-c.c (aarch64_update_cpp_builtins): Define
+       __ARM_FEATURE_JCVT where appropriate.
+       * config/aarch64/arm_acle.h (__jcvt): Define.
+
 2019-09-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * config/aarch64/aarch64.md ("unspec"): Add UNSPEC_FRINT32Z,
index 2fc5cf7d450fc3257f9eb33088fbb99ce885f428..9f261043e8aca48a088198ea7e1b09f3f89d575c 100644 (file)
@@ -438,6 +438,8 @@ enum aarch64_builtins
   /* Special cased Armv8.3-A Complex FMA by Lane quad Builtins.  */
   AARCH64_SIMD_FCMLA_LANEQ_BUILTIN_BASE,
   AARCH64_SIMD_FCMLA_LANEQ_BUILTINS
+  /* Builtin for Arm8.3-a Javascript conversion instruction.  */
+  AARCH64_JSCVT,
   /* TME builtins.  */
   AARCH64_TME_BUILTIN_TSTART,
   AARCH64_TME_BUILTIN_TCOMMIT,
@@ -1130,6 +1132,12 @@ aarch64_init_builtins (void)
   aarch64_init_crc32_builtins ();
   aarch64_init_builtin_rsqrt ();
 
+  tree ftype_jcvt
+    = build_function_type_list (intSI_type_node, double_type_node, NULL);
+  aarch64_builtin_decls[AARCH64_JSCVT]
+    = add_builtin_function ("__builtin_aarch64_jcvtzs", ftype_jcvt,
+                           AARCH64_JSCVT, BUILT_IN_MD, NULL, NULL_TREE);
+
   /* Initialize pointer authentication builtins which are backed by instructions
      in NOP encoding space.
 
@@ -1682,6 +1690,16 @@ aarch64_expand_builtin (tree exp,
 
       return target;
 
+    case AARCH64_JSCVT:
+      arg0 = CALL_EXPR_ARG (exp, 0);
+      op0 = force_reg (DFmode, expand_normal (arg0));
+      if (!target)
+       target = gen_reg_rtx (SImode);
+      else
+       target = force_reg (SImode, target);
+      emit_insn (GEN_FCN (CODE_FOR_aarch64_fjcvtzs) (target, op0));
+      return target;
+
     case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ0_V2SF:
     case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ90_V2SF:
     case AARCH64_SIMD_BUILTIN_FCMLA_LANEQ180_V2SF:
index c05efeda820f4428eace6e57020eed1b288032e9..137aa18af4620d4cefce1dfe5d92e4df67a278ba 100644 (file)
@@ -110,6 +110,7 @@ aarch64_update_cpp_builtins (cpp_reader *pfile)
   aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile);
   aarch64_def_or_undef (TARGET_DOTPROD, "__ARM_FEATURE_DOTPROD", pfile);
   aarch64_def_or_undef (TARGET_COMPLEX, "__ARM_FEATURE_COMPLEX", pfile);
+  aarch64_def_or_undef (TARGET_JSCVT, "__ARM_FEATURE_JCVT", pfile);
 
   cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
   cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
index e621238f13a8d1179e38e75fda6f56e7183c9ebe..7bbeed453cf87382b1776ff52991b5cf6ab9204e 100644 (file)
@@ -288,6 +288,9 @@ extern unsigned aarch64_architecture_version;
 /* ARMv8.3-A features.  */
 #define TARGET_ARMV8_3 (AARCH64_ISA_V8_3)
 
+/* Javascript conversion instruction from Armv8.3-a.  */
+#define TARGET_JSCVT   (TARGET_FLOAT && AARCH64_ISA_V8_3)
+
 /* Armv8.3-a Complex number extension to AdvSIMD extensions.  */
 #define TARGET_COMPLEX (TARGET_SIMD && TARGET_ARMV8_3)
 
index f1f9b2157da891dc9710edbfcb0c3bf3926af46e..e4f9005c27f6f57efba31004389dbed9fd91a360 100644 (file)
     UNSPEC_CRC32X
     UNSPEC_FCVTZS
     UNSPEC_FCVTZU
+    UNSPEC_FJCVTZS
     UNSPEC_FRINT32Z
     UNSPEC_FRINT32X
     UNSPEC_FRINT64Z
   [(set_attr "length" "0")]
 )
 
+(define_insn "aarch64_fjcvtzs"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand:DF 1 "register_operand" "w")]
+                  UNSPEC_FJCVTZS))]
+  "TARGET_JSCVT"
+  "fjcvtzs\\t%w0, %d1"
+  [(set_attr "type" "f_cvtf2i")]
+)
+
 ;; Pointer authentication patterns are always provided.  In architecture
 ;; revisions prior to ARMv8.3-A these HINT instructions operate as NOPs.
 ;; This lets the user write portable software which authenticates pointers
index 01a82be3e86add59390fd83c335abe562b26398d..147dfe0585cbae6b2d53ca3ead3edddf49d779a5 100644 (file)
 extern "C" {
 #endif
 
+#pragma GCC push_options
+#pragma GCC target ("arch=armv8.3-a")
+__extension__ static __inline int32_t __attribute__ ((__always_inline__))
+__jcvt (double __a)
+{
+  return __builtin_aarch64_jcvtzs (__a);
+}
+
+#pragma GCC pop_options
+
 #pragma GCC push_options
 #pragma GCC target ("arch=armv8.5-a")
 __extension__ static __inline float __attribute__ ((__always_inline__))
index 0189c42cdd885617a15ed588597ed5619945565f..40d11f9dfd853ddd4d316220373c25201fef8d40 100644 (file)
@@ -1,3 +1,7 @@
+2019-09-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
+
+       * gcc.target/aarch64/acle/jcvt_1.c: New test.
+
 2019-09-03  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * gcc.target/aarch64/acle/rintnzx_1.c: New test.
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c b/gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c
new file mode 100644 (file)
index 0000000..0c900b1
--- /dev/null
@@ -0,0 +1,15 @@
+/* Test the __jcvt ACLE intrinsic.  */
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv8.3-a" } */
+
+#include <arm_acle.h>
+
+#ifdef __ARM_FEATURE_JCVT
+int32_t
+test_jcvt (double a)
+{
+  return __jcvt (a);
+}
+#endif
+
+/* { dg-final { scan-assembler-times "fjcvtzs\tw\[0-9\]+, d\[0-9\]+\n" 1 } } */