https://gcc.gnu.org/g:e87b4d0280685c691a56698b40d665eeae41dda3

commit r17-1427-ge87b4d0280685c691a56698b40d665eeae41dda3
Author: Alfie Richards <[email protected]>
Date:   Mon Jan 5 17:08:15 2026 +0000

    aarch64: Add FEAT_FPRCVT support.
    
    gcc/ChangeLog:
    
            * config/aarch64/aarch64.h (TARGET_FPRCVT): New macro definition.
            * config/aarch64/aarch64.md (arches): Add fprcvt.
            (arch_enabled): Add fprcvt.
            (l<fcvt_pattern><su_optab><GPF_F16:mode><GPI:mode>2): Add
            FEAT_FPRCVT variant.
            (<optab>_trunchf<GPI:mode>2): Likewise.
            (<optab>_trunc<fcvt_change_mode><GPI:mode>2): Likewise.
            (fix_to_zero_extend<mode>di2): Likewise.
            (<optab><fcvt_iesize><GPF:mode>2): Likewise.
            (define_insn "aarch64_fp16_<optab><mode>hf2): Likewise.
            * config/aarch64/iterators.md (fpw): Add SF and DF variants.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.target/aarch64/acle/fprcvt.c: New test.
            * gcc.target/aarch64/fprcvt.c: New test.
            * gcc.target/aarch64/fprcvt.x: New test.
            * gcc.target/aarch64/fprcvt_float32_int32.c: New test.
            * gcc.target/aarch64/fprcvt_float32_int64.c: New test.
            * gcc.target/aarch64/fprcvt_float32_uint32.c: New test.
            * gcc.target/aarch64/fprcvt_float32_uint64.c: New test.
            * gcc.target/aarch64/fprcvt_float64_int32.c: New test.
            * gcc.target/aarch64/fprcvt_float64_int64.c: New test.
            * gcc.target/aarch64/fprcvt_float64_uint32.c: New test.
            * gcc.target/aarch64/fprcvt_float64_uint64.c: New test.

Diff:
---
 gcc/config/aarch64/aarch64.h                       |   2 +
 gcc/config/aarch64/aarch64.md                      |  74 ++-
 gcc/config/aarch64/iterators.md                    |   2 +-
 gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c     | 651 +++++++++++++++++++++
 gcc/testsuite/gcc.target/aarch64/fprcvt.c          | 147 +++++
 gcc/testsuite/gcc.target/aarch64/fprcvt.x          |  87 +++
 .../gcc.target/aarch64/fprcvt_float32_int32.c      |  18 +
 .../gcc.target/aarch64/fprcvt_float32_int64.c      |  16 +
 .../gcc.target/aarch64/fprcvt_float32_uint32.c     |  18 +
 .../gcc.target/aarch64/fprcvt_float32_uint64.c     |  18 +
 .../gcc.target/aarch64/fprcvt_float64_int32.c      |  18 +
 .../gcc.target/aarch64/fprcvt_float64_int64.c      |  16 +
 .../gcc.target/aarch64/fprcvt_float64_uint32.c     |  18 +
 .../gcc.target/aarch64/fprcvt_float64_uint64.c     |  18 +
 14 files changed, 1073 insertions(+), 30 deletions(-)

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 45467991f26c..c3c61c6939c0 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -583,6 +583,8 @@ through +ssve-fp8dot2.  */
                           && (AARCH64_HAVE_ISA (SSVE_FEXPA) \
                               || TARGET_NON_STREAMING))
 
+#define TARGET_FPRCVT (AARCH64_HAVE_ISA (FPRCVT))
+
 /* Standard register usage.  */
 
 /* 31 64-bit general purpose registers R0-R30:
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 6c141df40a4b..2cc5b93082cc 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -503,7 +503,7 @@
 ;; Q registers and is equivalent to "simd".
 
 (define_enum "arches" [any rcpc8_4 fp fp_q base_simd nobase_simd
-                      simd nosimd sve fp16 sme cssc sve2p2_or_sme2p2])
+                      simd nosimd sve fp16 sme cssc fprcvt sve2p2_or_sme2p2])
 
 (define_enum_attr "arch" "arches" (const_string "any"))
 
@@ -585,7 +585,10 @@
             (match_test "TARGET_SME"))
 
        (and (eq_attr "arch" "sve2p2_or_sme2p2")
-            (match_test "TARGET_SVE2p2_OR_SME2p2"))))
+            (match_test "TARGET_SVE2p2_OR_SME2p2"))
+
+       (and (eq_attr "arch" "fprcvt")
+            (match_test "TARGET_FPRCVT"))))
     (const_string "yes")
     (const_string "no")))
 
@@ -3156,8 +3159,8 @@
 (define_insn "*adds_<optab><ALLX:mode>_shift_<GPI:mode>"
   [(set (reg:CC_NZ CC_REGNUM)
        (compare:CC_NZ
-        (plus:GPI (ashift:GPI 
-                   (ANY_EXTEND:GPI 
+        (plus:GPI (ashift:GPI
+                   (ANY_EXTEND:GPI
                     (match_operand:ALLX 1 "register_operand" "r"))
                    (match_operand 2 "aarch64_imm3" "Ui3"))
                   (match_operand:GPI 3 "register_operand" "rk"))
@@ -3175,7 +3178,7 @@
   [(set (reg:CC_NZ CC_REGNUM)
        (compare:CC_NZ
         (minus:GPI (match_operand:GPI 1 "register_operand" "rk")
-                   (ashift:GPI 
+                   (ashift:GPI
                     (ANY_EXTEND:GPI
                      (match_operand:ALLX 2 "register_operand" "r"))
                     (match_operand 3 "aarch64_imm3" "Ui3")))
@@ -7101,13 +7104,15 @@
 ;; frcvt floating-point round to integer and convert standard patterns.
 ;; Expands to lbtrunc, lceil, lfloor, lround.
 (define_insn "l<fcvt_pattern><su_optab><GPF_F16:mode><GPI:mode>2"
-  [(set (match_operand:GPI 0 "register_operand" "=r")
+  [(set (match_operand:GPI 0 "register_operand")
        (FIXUORS:GPI
-         (unspec:GPF_F16 [(match_operand:GPF_F16 1 "register_operand" "w")]
+         (unspec:GPF_F16 [(match_operand:GPF_F16 1 "register_operand")]
           FCVT)))]
-  "TARGET_FLOAT"
-  "fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF_F16:s>1"
-  [(set_attr "type" "f_cvtf2i")]
+  ""
+  {@ [ cons: =0 , 1 ; attrs: type , arch   ]
+     [ r        , w ; f_cvtf2i    , fp     ] 
fcvt<frint_suffix><su>\t%<GPI:w>0, %<GPF_F16:s>1
+     [ w        , w ; f_cvtf2i    , fprcvt ] 
fcvt<frint_suffix><su>\t%<GPI:v>0, %<GPF_F16:s>1
+  }
 )
 
 (define_insn "*aarch64_fcvt<su_optab><GPF:mode><GPI:mode>2_mult"
@@ -7288,32 +7293,38 @@
 ;; Convert HF -> SI or DI
 
 (define_insn "<optab>_trunchf<GPI:mode>2"
-  [(set (match_operand:GPI 0 "register_operand" "=r")
-       (FIXUORS:GPI (match_operand:HF 1 "register_operand" "w")))]
+  [(set (match_operand:GPI 0 "register_operand")
+       (FIXUORS:GPI (match_operand:HF 1 "register_operand")))]
   "TARGET_FP_F16INST"
-  "fcvtz<su>\t%<w>0, %h1"
-  [(set_attr "type" "f_cvtf2i")]
+  {@ [ cons: =0 , 1 ; attrs: type , arch   ]
+     [ r        , w ; f_cvtf2i    , fp     ] fcvtz<su>\t%<w>0, %h1
+     [ w        , w ; f_cvtf2i    , fprcvt ] fcvtz<su>\t%<s>0, %h1
+  }
 )
 
 ;; Convert DF -> SI or SF -> DI which can only be accomplished with
 ;; input in a fp register and output in a integer register
 
 (define_insn "<optab>_trunc<fcvt_change_mode><GPI:mode>2"
-  [(set (match_operand:GPI 0 "register_operand" "=r")
-       (FIXUORS:GPI (match_operand:<FCVT_CHANGE_MODE> 1 "register_operand" 
"w")))]
+  [(set (match_operand:GPI 0 "register_operand")
+       (FIXUORS:GPI (match_operand:<FCVT_CHANGE_MODE> 1 "register_operand")))]
   "TARGET_FLOAT"
-  "fcvtz<su>\t%<w>0, %<fpw>1"
-  [(set_attr "type" "f_cvtf2i")]
+  {@ [ cons: =0 , 1 ; attrs: type      , arch   ]
+     [ r        , w ; f_cvtf2i         , fp     ] fcvtz<su>\t%<w>0, %<fpw>1
+     [ w        , w ; f_cvtf2i         , fprcvt ] fcvtz<su>\t%<s>0, %<fpw>1
+  }
 )
 
 (define_insn "*fix_to_zero_extend<mode>di2"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (match_operand:DI 0 "register_operand")
        (zero_extend:DI
         (unsigned_fix:SI
-         (match_operand:GPF 1 "register_operand" "w"))))]
+         (match_operand:GPF 1 "register_operand"))))]
   "TARGET_FLOAT"
-  "fcvtzu\t%w0, %<s>1"
-  [(set_attr "type" "f_cvtf2i")]
+  {@ [ cons: =0 , 1 ; attrs: type      , arch   ]
+     [ r        , w ; f_cvtf2i         , fp     ] fcvtzu\t%w0, %<s>1
+     [ w        , w ; f_cvtf2i         , fprcvt ] fcvtzu\t%s0, %<s>1
+  }
 )
 
 ;; Equal width integer to fp and multiply combine.
@@ -7366,10 +7377,13 @@
 
 ;; Unequal width integer to fp conversions.
 (define_insn "<optab><fcvt_iesize><GPF:mode>2"
-  [(set (match_operand:GPF 0 "register_operand" "=w")
-        (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand" 
"r")))]
+  [(set (match_operand:GPF 0 "register_operand")
+       (FLOATUORS:GPF (match_operand:<FCVT_IESIZE> 1 "register_operand")))]
   "TARGET_FLOAT"
-  "<su_optab>cvtf\t%<GPF:s>0, %<w2>1"
+  {@ [ cons: =0 , 1 ; attrs: type      , arch   ]
+     [ w        , r ; f_cvti2f         , fp     ] <su_optab>cvtf\t%<GPF:s>0, 
%<w2>1
+     [ w        , w ; f_cvti2f         , fprcvt ] <su_optab>cvtf\t%<GPF:s>0, 
%<fpw>1
+  }
   [(set_attr "type" "f_cvti2f")]
 )
 
@@ -7381,11 +7395,13 @@
 ;; of the mid-end logic.
 
 (define_insn "aarch64_fp16_<optab><mode>hf2"
-  [(set (match_operand:HF 0 "register_operand" "=w")
-       (FLOATUORS:HF (match_operand:GPI 1 "register_operand" "r")))]
+  [(set (match_operand:HF 0 "register_operand")
+       (FLOATUORS:HF (match_operand:GPI 1 "register_operand")))]
   "TARGET_FP_F16INST"
-  "<su_optab>cvtf\t%h0, %<w>1"
-  [(set_attr "type" "f_cvti2f")]
+  {@ [ cons: =0 , 1 ; attrs: type , arch   ]
+     [ w        , r ; f_cvti2f    , fp     ] <su_optab>cvtf\t%h0, %<w>1
+     [ w        , w ; f_cvti2f    , fprcvt ] <su_optab>cvtf\t%h0, %<v>1
+  }
 )
 
 (define_expand "<optab>sihf2"
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 948dcefa63e9..2d1522a348ac 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -1427,7 +1427,7 @@
 (define_mode_attr w2 [(HF "x") (SF "x") (DF "w")])
 
 ;; For width of fp registers in fcvt instruction
-(define_mode_attr fpw [(DI "s") (SI "d")])
+(define_mode_attr fpw [(DI "s") (SI "d") (DF "s") (SF "d")])
 
 (define_mode_attr short_mask [(HI "65535") (QI "255")])
 
diff --git a/gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c 
b/gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c
new file mode 100644
index 000000000000..603e72d8c5a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/acle/fprcvt.c
@@ -0,0 +1,651 @@
+/* { dg-do compile } */
+/* { dg-options "-save-temps -fno-inline -O1 -march=armv9-a+fprcvt" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdint.h>
+#include <arm_fp16.h>
+#include <arm_acle.h>
+#include <arm_neon.h>
+
+#define FORCE_FP_REG(a) asm volatile("fmov %d0, %d1" : "=w"(a) : "w"(a) :)
+#define CONVERT_INTRINSIC(T_FROM, T_TO, INTRINSIC)                             
\
+  void convert_##INTRINSIC (T_FROM *from, T_TO *to)        \
+  {                                                                            
\
+    T_FROM from_val = *from;                                                   
\
+    FORCE_FP_REG (from_val);                                                   
\
+    T_TO to_val = INTRINSIC (from_val);                                        
\
+    FORCE_FP_REG (to_val);                                                     
\
+    *to = to_val;                                                              
\
+  }
+
+CONVERT_INTRINSIC (float32_t, int32_t, vcvts_s32_f32)
+/*
+** convert_vcvts_s32_f32:
+**...
+**     fcvtzs  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvts_s64_f32)
+/*
+** convert_vcvts_s64_f32:
+**...
+**     fcvtzs  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint32_t, vcvts_u32_f32)
+/*
+** convert_vcvts_u32_f32:
+**...
+**     fcvtzu  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvts_u64_f32)
+/*
+** convert_vcvts_u64_f32:
+**...
+**     fcvtzu  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int32_t, vcvtns_s32_f32)
+/*
+** convert_vcvtns_s32_f32:
+**...
+**     fcvtns  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtns_s64_f32)
+/*
+** convert_vcvtns_s64_f32:
+**...
+**     fcvtns  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint32_t, vcvtns_u32_f32)
+/*
+** convert_vcvtns_u32_f32:
+**...
+**     fcvtnu  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtns_u64_f32)
+/*
+** convert_vcvtns_u64_f32:
+**...
+**     fcvtnu  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int32_t, vcvtms_s32_f32)
+/*
+** convert_vcvtms_s32_f32:
+**...
+**     fcvtms  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtms_s64_f32)
+/*
+** convert_vcvtms_s64_f32:
+**...
+**     fcvtms  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint32_t, vcvtms_u32_f32)
+/*
+** convert_vcvtms_u32_f32:
+**...
+**     fcvtmu  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtms_u64_f32)
+/*
+** convert_vcvtms_u64_f32:
+**...
+**     fcvtmu  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int32_t, vcvtps_s32_f32)
+/*
+** convert_vcvtps_s32_f32:
+**...
+**     fcvtps  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtps_s64_f32)
+/*
+** convert_vcvtps_s64_f32:
+**...
+**     fcvtps  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint32_t, vcvtps_u32_f32)
+/*
+** convert_vcvtps_u32_f32:
+**...
+**     fcvtpu  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtps_u64_f32)
+/*
+** convert_vcvtps_u64_f32:
+**...
+**     fcvtpu  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int32_t, vcvtas_s32_f32)
+/*
+** convert_vcvtas_s32_f32:
+**...
+**     fcvtas  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, int64_t, vcvtas_s64_f32)
+/*
+** convert_vcvtas_s64_f32:
+**...
+**     fcvtas  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint32_t, vcvtas_u32_f32)
+/*
+** convert_vcvtas_u32_f32:
+**...
+**     fcvtau  s[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float32_t, uint64_t, vcvtas_u64_f32)
+/*
+** convert_vcvtas_u64_f32:
+**...
+**     fcvtau  d[0-9]+, s[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtd_s32_f64)
+/*
+** convert_vcvtd_s32_f64:
+**...
+**     fcvtzs  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int64_t, vcvtd_s64_f64)
+/*
+** convert_vcvtd_s64_f64:
+**...
+**     fcvtzs  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtd_u32_f64)
+/*
+** convert_vcvtd_u32_f64:
+**...
+**     fcvtzu  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint64_t, vcvtd_u64_f64)
+/*
+** convert_vcvtd_u64_f64:
+**...
+**     fcvtzu  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtnd_s32_f64)
+/*
+** convert_vcvtnd_s32_f64:
+**...
+**     fcvtns  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int64_t, vcvtnd_s64_f64)
+/*
+** convert_vcvtnd_s64_f64:
+**...
+**     fcvtns  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtnd_u32_f64)
+/*
+** convert_vcvtnd_u32_f64:
+**...
+**     fcvtnu  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint64_t, vcvtnd_u64_f64)
+/*
+** convert_vcvtnd_u64_f64:
+**...
+**     fcvtnu  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtmd_s32_f64)
+/*
+** convert_vcvtmd_s32_f64:
+**...
+**     fcvtms  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int64_t, vcvtmd_s64_f64)
+/*
+** convert_vcvtmd_s64_f64:
+**...
+**     fcvtms  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtmd_u32_f64)
+/*
+** convert_vcvtmd_u32_f64:
+**...
+**     fcvtmu  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint64_t, vcvtmd_u64_f64)
+/*
+** convert_vcvtmd_u64_f64:
+**...
+**     fcvtmu  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtpd_s32_f64)
+/*
+** convert_vcvtpd_s32_f64:
+**...
+**     fcvtps  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int64_t, vcvtpd_s64_f64)
+/*
+** convert_vcvtpd_s64_f64:
+**...
+**     fcvtps  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtpd_u32_f64)
+/*
+** convert_vcvtpd_u32_f64:
+**...
+**     fcvtpu  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint64_t, vcvtpd_u64_f64)
+/*
+** convert_vcvtpd_u64_f64:
+**...
+**     fcvtpu  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int32_t, vcvtad_s32_f64)
+/*
+** convert_vcvtad_s32_f64:
+**...
+**     fcvtas  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, int64_t, vcvtad_s64_f64)
+/*
+** convert_vcvtad_s64_f64:
+**...
+**     fcvtas  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint32_t, vcvtad_u32_f64)
+/*
+** convert_vcvtad_u32_f64:
+**...
+**     fcvtau  s[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float64_t, uint64_t, vcvtad_u64_f64)
+/*
+** convert_vcvtad_u64_f64:
+**...
+**     fcvtau  d[0-9]+, d[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int16_t, vcvth_s16_f16)
+/*
+** convert_vcvth_s16_f16:
+**...
+**     fcvtzs  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int32_t, vcvth_s32_f16)
+/*
+** convert_vcvth_s32_f16:
+**...
+**     fcvtzs  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int64_t, vcvth_s64_f16)
+/*
+** convert_vcvth_s64_f16:
+**...
+**     fcvtzs  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint16_t, vcvth_u16_f16)
+/*
+** convert_vcvth_u16_f16:
+**...
+**     fcvtzu  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint32_t, vcvth_u32_f16)
+/*
+** convert_vcvth_u32_f16:
+**...
+**     fcvtzu  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint64_t, vcvth_u64_f16)
+/*
+** convert_vcvth_u64_f16:
+**...
+**     fcvtzu  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int16_t, vcvtah_s16_f16)
+/*
+** convert_vcvtah_s16_f16:
+**...
+**     fcvtas  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int32_t, vcvtah_s32_f16)
+/*
+** convert_vcvtah_s32_f16:
+**...
+**     fcvtas  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int64_t, vcvtah_s64_f16)
+/*
+** convert_vcvtah_s64_f16:
+**...
+**     fcvtas  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint16_t, vcvtah_u16_f16)
+/*
+** convert_vcvtah_u16_f16:
+**...
+**     fcvtau  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint32_t, vcvtah_u32_f16)
+/*
+** convert_vcvtah_u32_f16:
+**...
+**     fcvtau  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint64_t, vcvtah_u64_f16)
+/*
+** convert_vcvtah_u64_f16:
+**...
+**     fcvtau  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int16_t, vcvtmh_s16_f16)
+/*
+** convert_vcvtmh_s16_f16:
+**...
+**     fcvtms  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int32_t, vcvtmh_s32_f16)
+/*
+** convert_vcvtmh_s32_f16:
+**...
+**     fcvtms  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int64_t, vcvtmh_s64_f16)
+/*
+** convert_vcvtmh_s64_f16:
+**...
+**     fcvtms  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint16_t, vcvtmh_u16_f16)
+/*
+** convert_vcvtmh_u16_f16:
+**...
+**     fcvtmu  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint32_t, vcvtmh_u32_f16)
+/*
+** convert_vcvtmh_u32_f16:
+**...
+**     fcvtmu  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint64_t, vcvtmh_u64_f16)
+/*
+** convert_vcvtmh_u64_f16:
+**...
+**     fcvtmu  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int16_t, vcvtnh_s16_f16)
+/*
+** convert_vcvtnh_s16_f16:
+**...
+**     fcvtns  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int32_t, vcvtnh_s32_f16)
+/*
+** convert_vcvtnh_s32_f16:
+**...
+**     fcvtns  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int64_t, vcvtnh_s64_f16)
+/*
+** convert_vcvtnh_s64_f16:
+**...
+**     fcvtns  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint16_t, vcvtnh_u16_f16)
+/*
+** convert_vcvtnh_u16_f16:
+**...
+**     fcvtnu  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint32_t, vcvtnh_u32_f16)
+/*
+** convert_vcvtnh_u32_f16:
+**...
+**     fcvtnu  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint64_t, vcvtnh_u64_f16)
+/*
+** convert_vcvtnh_u64_f16:
+**...
+**     fcvtnu  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int16_t, vcvtph_s16_f16)
+/*
+** convert_vcvtph_s16_f16:
+**...
+**     fcvtps  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int32_t, vcvtph_s32_f16)
+/*
+** convert_vcvtph_s32_f16:
+**...
+**     fcvtps  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, int64_t, vcvtph_s64_f16)
+/*
+** convert_vcvtph_s64_f16:
+**...
+**     fcvtps  d[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint16_t, vcvtph_u16_f16)
+/*
+** convert_vcvtph_u16_f16:
+**...
+**     fcvtpu  h[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint32_t, vcvtph_u32_f16)
+/*
+** convert_vcvtph_u32_f16:
+**...
+**     fcvtpu  s[0-9]+, h[0-9]+
+**...
+*/
+
+CONVERT_INTRINSIC (float16_t, uint64_t, vcvtph_u64_f16)
+/*
+** convert_vcvtph_u64_f16:
+**...
+**     fcvtpu  d[0-9]+, h[0-9]+
+**...
+*/
+
+
+CONVERT_INTRINSIC (int32_t, float32_t, vcvts_f32_s32)
+/*
+** convert_vcvts_f32_s32:
+**...
+**     scvtf   s[0-9]+, s[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (uint32_t, float32_t, vcvts_f32_u32)
+/*
+** convert_vcvts_f32_u32:
+**...
+**     ucvtf   s[0-9]+, s[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (int64_t, float64_t, vcvtd_f64_s64)
+/*
+** convert_vcvtd_f64_s64:
+**...
+**     scvtf   d[0-9]+, d[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (uint64_t, float64_t, vcvtd_f64_u64)
+/*
+** convert_vcvtd_f64_u64:
+**...
+**     ucvtf   d[0-9]+, d[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (int16_t, float16_t, vcvth_f16_s16)
+/*
+** convert_vcvth_f16_s16:
+**...
+**     scvtf   h[0-9]+, h[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (int32_t, float16_t, vcvth_f16_s32)
+/*
+** convert_vcvth_f16_s32:
+**...
+**     scvtf   h[0-9]+, s[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (int64_t, float16_t, vcvth_f16_s64)
+/*
+** convert_vcvth_f16_s64:
+**...
+**     scvtf   h[0-9]+, d[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (uint16_t, float16_t, vcvth_f16_u16)
+/*
+** convert_vcvth_f16_u16:
+**...
+**     ucvtf   h[0-9]+, h[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (uint32_t, float16_t, vcvth_f16_u32)
+/*
+** convert_vcvth_f16_u32:
+**...
+**     ucvtf   h[0-9]+, s[0-9]+
+**...
+*/
+CONVERT_INTRINSIC (uint64_t, float16_t, vcvth_f16_u64)
+/*
+** convert_vcvth_f16_u64:
+**...
+**     ucvtf   h[0-9]+, d[0-9]+
+**...
+*/
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt.c
new file mode 100644
index 000000000000..1bca48b9a153
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt.c
@@ -0,0 +1,147 @@
+/* { dg-do compile } */
+/* { dg-options "-save-temps -fno-inline -O2 -march=armv9-a+fprcvt" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+#include <stdint.h>
+#include <arm_fp16.h>
+#include <arm_acle.h>
+#include <arm_neon.h>
+
+#define FORCE_FP_REG(a) asm volatile("fmov %d0, %d1" : "=w"(a) : "w"(a) :)
+#define CONVERT(T_FROM, T_TO)                                                  
\
+  void convert_##T_FROM##_to_##T_TO (T_FROM *from, T_TO *to)                   
   \
+  {                                                                            
\
+    T_FROM from_val = *from;                                                   
\
+    FORCE_FP_REG (from_val);                                                   
    \
+    T_TO to_val = (T_TO) from_val;                                             
\
+    FORCE_FP_REG (to_val);                                                     
    \
+    *to = to_val;                                                              
\
+  }
+
+/*
+** convert_float16_t_to_int32_t:
+**...
+**     fcvtzs  s[0-9]+, h[0-9]+
+**...
+*/
+CONVERT (float16_t, int32_t)
+
+/*
+** convert_float64_t_to_int32_t:
+**...
+**     fcvtzs  s[0-9]+, d[0-9]+
+**...
+*/
+CONVERT (float64_t, int32_t)
+
+/*
+** convert_float16_t_to_int64_t:
+**...
+**     fcvtzs  d[0-9]+, h[0-9]+
+**...
+*/
+CONVERT (float16_t, int64_t)
+
+/*
+** convert_float32_t_to_int64_t:
+**...
+**     fcvtzs  d[0-9]+, s[0-9]+
+**...
+*/
+CONVERT (float32_t, int64_t)
+
+/*
+** convert_float16_t_to_uint32_t:
+**...
+**     fcvtzu  s[0-9]+, h[0-9]+
+**...
+*/
+CONVERT (float16_t, uint32_t)
+
+/*
+** convert_float64_t_to_uint32_t:
+**...
+**     fcvtzu  s[0-9]+, d[0-9]+
+**...
+*/
+CONVERT (float64_t, uint32_t)
+
+/*
+** convert_float16_t_to_uint64_t:
+**...
+**     fcvtzu  d[0-9]+, h[0-9]+
+**...
+*/
+CONVERT (float16_t, uint64_t)
+
+/*
+** convert_float32_t_to_uint64_t:
+**...
+**     fcvtzu  d[0-9]+, s[0-9]+
+**...
+*/
+CONVERT (float32_t, uint64_t)
+
+/*
+** convert_int32_t_to_float16_t:
+**...
+**     scvtf   h[0-9]+, s[0-9]+
+**...
+*/
+CONVERT (int32_t, float16_t)
+
+/*
+** convert_int32_t_to_float64_t:
+**...
+**     scvtf   d[0-9]+, s[0-9]+
+**...
+*/
+CONVERT (int32_t, float64_t)
+
+/*
+** convert_int64_t_to_float16_t:
+**...
+**     scvtf   h[0-9]+, d[0-9]+
+**...
+*/
+CONVERT (int64_t, float16_t)
+
+/*
+** convert_int64_t_to_float32_t:
+**...
+**     scvtf   s[0-9]+, d[0-9]+
+**...
+*/
+CONVERT (int64_t, float32_t)
+
+/*
+** convert_uint32_t_to_float16_t:
+**...
+**     ucvtf   h[0-9]+, s[0-9]+
+**...
+*/
+CONVERT (uint32_t, float16_t)
+
+/*
+** convert_uint32_t_to_float64_t:
+**...
+**     ucvtf   d[0-9]+, s[0-9]+
+**...
+*/
+CONVERT (uint32_t, float64_t)
+
+/*
+** convert_uint64_t_to_float16_t:
+**...
+**     ucvtf   h[0-9]+, d[0-9]+
+**...
+*/
+CONVERT (uint64_t, float16_t)
+
+/*
+** convert_uint64_t_to_float32_t:
+**...
+**     ucvtf   s[0-9]+, d[0-9]+
+**...
+*/
+CONVERT (uint64_t, float32_t)
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt.x 
b/gcc/testsuite/gcc.target/aarch64/fprcvt.x
new file mode 100644
index 000000000000..a4e8fc395058
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt.x
@@ -0,0 +1,87 @@
+extern GPF SUFFIX(trunc) (GPF);
+extern GPF SUFFIX(ceil) (GPF);
+extern GPF SUFFIX(floor) (GPF);
+extern GPF SUFFIX(round) (GPF);
+
+#define FORCE_FP_REG(a) asm volatile("fmov %d0, %d1" : "=w"(a) : "w"(a) :)
+
+GPI test1a (GPF x) {
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(__builtin_trunc)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test1b (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(trunc)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test2a (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(__builtin_lceil)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test2b (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(ceil)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test2c (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(__builtin_ceil)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test3a (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(__builtin_lfloor)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test3b (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(floor)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test3c (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(__builtin_floor)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test4a (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(__builtin_round)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+GPI test4b (GPF x)
+{
+  FORCE_FP_REG(x);
+  GPI res = SUFFIX(round)(x);
+  FORCE_FP_REG(res);
+  return res;
+}
+
+
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int32.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int32.c
new file mode 100644
index 000000000000..6a086339e1b1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int32.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float32_t
+#define SUFFIX(x) x##f
+#define GPI int32_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzs\ts\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtps\ts\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtms\ts\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtas\ts\[0-9\]+, *s\[0-9\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int64.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int64.c
new file mode 100644
index 000000000000..22464157d2fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_int64.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float32_t
+#define SUFFIX(x) x##f
+#define GPI int64_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzs\td\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 3 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 3 } } */
+/* { dg-final { scan-assembler-times "fcvtas\td\[0-9\]+, *s\[0-9\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint32.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint32.c
new file mode 100644
index 000000000000..87e4686edd33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint32.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float32_t
+#define SUFFIX(x) x##f
+#define GPI uint32_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzu\ts\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtpu\ts\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtmu\ts\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtau\ts\[0-9\]+, *s\[0-9\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint64.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint64.c
new file mode 100644
index 000000000000..76922b33edf2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float32_uint64.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float32_t
+#define SUFFIX(x) x##f
+#define GPI uint64_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzu\td\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *s\[0-9\]" 1 } } *
+/* { dg-final { scan-assembler-times "fcvtpu\td\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *s\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtmu\td\[0-9\]+, *s\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtau\td\[0-9\]+, *s\[0-9\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int32.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int32.c
new file mode 100644
index 000000000000..dd772600e0d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int32.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float64_t
+#define SUFFIX(x) x
+#define GPI int32_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzs\ts\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtps\ts\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtms\ts\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtas\ts\[0-9\]+, *d\[0-9\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int64.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int64.c
new file mode 100644
index 000000000000..c28960a46014
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_int64.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float64_t
+#define SUFFIX(x) x
+#define GPI int64_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzs\td\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 3 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 3 } } */
+/* { dg-final { scan-assembler-times "fcvtas\td\[0-9\]+, *d\[0-9\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint32.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint32.c
new file mode 100644
index 000000000000..7dcd0cc41f61
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint32.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float64_t
+#define SUFFIX(x) x
+#define GPI uint32_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzu\ts\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 1 } } *
+/* { dg-final { scan-assembler-times "fcvtpu\ts\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtmu\ts\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtau\ts\[0-9\]+, *d\[0-9\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint64.c 
b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint64.c
new file mode 100644
index 000000000000..f0d385d44c1d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/fprcvt_float64_uint64.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=armv9-a+fprcvt" } */
+
+#include <stdint.h>
+#include <arm_neon.h>
+
+#define GPF float64_t
+#define SUFFIX(x) x
+#define GPI uint64_t
+
+#include "fprcvt.x"
+
+/* { dg-final { scan-assembler-times "fcvtzu\td\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtpu\td\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtps\td\[0-9\]+, *d\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtmu\td\[0-9\]+, *d\[0-9\]" 2 } } */
+/* { dg-final { scan-assembler-times "fcvtms\td\[0-9\]+, *d\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-times "fcvtau\td\[0-9\]+, *d\[0-9\]" 2 } } */

Reply via email to