Hi all,
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.
Bootstrapped and tested on aarch64-none-linux-gnu.
Ok for trunk?
Thanks,
Kyrill
[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
2019-09-02 Kyrylo Tkachov <kyrylo.tkac...@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-02 Kyrylo Tkachov <kyrylo.tkac...@arm.com>
* gcc.target/aarch64/acle/jcvt_1.c: New test.
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index a20a2ae1acc1ea8951d899431b57be3bd8c9ad3e..9424916d2466aa9f014ce7c0a13667ccc8eeb9ed 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -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,
@@ -1150,6 +1152,12 @@ aarch64_init_builtins (void)
aarch64_init_builtin_rsqrt ();
aarch64_init_rng_builtins ();
+ 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.
@@ -1739,6 +1747,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:
diff --git a/gcc/config/aarch64/aarch64-c.c b/gcc/config/aarch64/aarch64-c.c
index c05efeda820f4428eace6e57020eed1b288032e9..137aa18af4620d4cefce1dfe5d92e4df67a278ba 100644
--- a/gcc/config/aarch64/aarch64-c.c
+++ b/gcc/config/aarch64/aarch64-c.c
@@ -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__");
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 67279b44198be1ea0e950c80504e948d3af504f9..de270e3bf818ea0a2096abc3529abf129d822e88 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -289,6 +289,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)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index d933916e519feac38b79e6d42ff4f0a340de67c6..13e09e0a40aae9993b7a2f8f6c6e10a929994677 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -141,6 +141,7 @@
UNSPEC_CRC32X
UNSPEC_FCVTZS
UNSPEC_FCVTZU
+ UNSPEC_FJCVTZS
UNSPEC_FRINT32Z
UNSPEC_FRINT32X
UNSPEC_FRINT64Z
@@ -6925,6 +6926,15 @@
[(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
diff --git a/gcc/config/aarch64/arm_acle.h b/gcc/config/aarch64/arm_acle.h
index 0347d1d36a39d65ff264e2fbda45c4daad33a2c9..aa8f649e32da27bb514fd9cd969587244f1f5cb1 100644
--- a/gcc/config/aarch64/arm_acle.h
+++ b/gcc/config/aarch64/arm_acle.h
@@ -130,6 +130,16 @@ __ttest (void)
#pragma GCC pop_options
#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__))
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
index 0000000000000000000000000000000000000000..0c900b1b57c7f1416ed1e0355a5722228262ea99
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/jcvt_1.c
@@ -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 } } */