[v2] aarch64: Add 64 bits fpcr fpsr getter/setter builtins

Message ID gkrzh8jzlxg.fsf_-_@arm.com
State New
Headers show
Series
  • [v2] aarch64: Add 64 bits fpcr fpsr getter/setter builtins
Related show

Commit Message

Andrea Corallo July 1, 2020, 8:20 a.m.
Hi all,

Second version of the patch addressing comments.

This introduces the following 64bit builtins variants as FPCR and FPSR
registers getter/setter:

unsigned long long __builtin_aarch64_get_fpcr64 ()
void __builtin_aarch64_set_fpcr64 (unsigned long long)
unsigned long long __builtin_aarch64_get_fpsr64 ()
void __builtin_aarch64_set_fpsr64 (unsigned long long)

aarch64-unknown-linux-gnu bootstrapped and regresssioned.

Regards
  Andrea

gcc/ChangeLog

2020-??-??  Andrea Corallo  <andrea.corallo@arm.com>

	* config/aarch64/aarch64-builtins.c (aarch64_builtins): Add enums
	for 64bits fpsr/fpcr getter setters builtin variants.
	(aarch64_init_fpsr_fpcr_builtins): New function.
	(aarch64_general_init_builtins): Modify to make use of the later.
	(aarch64_expand_fpsr_fpcr_setter): New function.
	(aarch64_general_expand_builtin): Modify to make use of the later.
	* config/aarch64/aarch64.md (@aarch64_set_<fpscr_name><GPI:mode>)
	(@aarch64_get_<fpscr_name><GPI:mode>): New patterns replacing and
	generalizing 'get_fpcr', 'set_fpsr'.
	* config/aarch64/iterators.md (GET_FPSCR, SET_FPSCR): New int
	iterators.
	(fpscr_name): New int attribute.
	* doc/extend.texi (__builtin_aarch64_get_fpcr64)
	(__builtin_aarch64_set_fpcr64, __builtin_aarch64_get_fpsr64)
	(__builtin_aarch64_set_fpsr64): Add into AArch64 Built-in
	Functions.

gcc/testsuite/ChangeLog

2020-??-??  Andrea Corallo  <andrea.corallo@arm.com>

	* gcc.target/aarch64/get_fpcr64.c: New test.
	* gcc.target/aarch64/set_fpcr64.c: New test.
	* gcc.target/aarch64/get_fpsr64.c: New test.
	* gcc.target/aarch64/set_fpsr64.c: New test.

Comments

Richard Sandiford July 1, 2020, 8:49 a.m. | #1
Andrea Corallo <andrea.corallo@arm.com> writes:
> +/* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group.  */

> +

> +void

> +aarch64_general_init_builtins (void)

> +{

> +


Excess blank line here.

> +  aarch64_init_fpsr_fpcr_builtins ();

> +

>    aarch64_init_fp16_types ();

>  

>    aarch64_init_bf16_types ();

> @@ -1876,6 +1913,14 @@ aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target)

>    return target;

>  }

>  

> +static void

> +aarch64_expand_fpsr_fpcr_setter (int unspec, machine_mode mode, tree exp)


Should have a function comment here, even though the function is tiny.

> +{

> +  tree arg = CALL_EXPR_ARG (exp, 0);

> +  rtx op = force_reg (mode, expand_normal (arg));

> +  emit_insn (gen_aarch64_set (unspec, mode, op));

> +}

> +

>  /* Expand an expression EXP that calls built-in function FCODE,

>     with result going to TARGET if that's convenient.  IGNORE is true

>     if the result of the builtin is ignored.  */

> […]

> diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md

> index deca0004fedc..75f9e9e97e8b 100644

> --- a/gcc/config/aarch64/aarch64.md

> +++ b/gcc/config/aarch64/aarch64.md

> @@ -7230,37 +7230,21 @@

>    [(set_attr "length" "12")

>     (set_attr "type" "multiple")])

>  

> -;; Write Floating-point Control Register.

> -(define_insn "set_fpcr"

> -  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]

> +;; Write into Floating-point Status Register.


“Status or Control”.  IMO reads better with “the” added.

> +(define_insn "@aarch64_set_<fpscr_name><GPI:mode>"

> +  [(unspec_volatile [(match_operand:GPI 0 "register_operand" "r")] SET_FPSCR)]

>    ""

> -  "msr\\tfpcr, %0"

> +  "msr\\t<fpscr_name>, %0"

>    [(set_attr "type" "mrs")])

>  

>  ;; Read Floating-point Control Register.


Same here.

> -(define_insn "get_fpcr"

> -  [(set (match_operand:SI 0 "register_operand" "=r")

> -        (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]

> -  ""

> -  "mrs\\t%0, fpcr"

> -  [(set_attr "type" "mrs")])

> -

> -;; Write Floating-point Status Register.

> -(define_insn "set_fpsr"

> -  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]

> -  ""

> -  "msr\\tfpsr, %0"

> -  [(set_attr "type" "mrs")])

> -

> -;; Read Floating-point Status Register.

> -(define_insn "get_fpsr"

> -  [(set (match_operand:SI 0 "register_operand" "=r")

> -        (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]

> +(define_insn "@aarch64_get_<fpscr_name><GPI:mode>"

> +  [(set (match_operand:GPI 0 "register_operand" "=r")

> +        (unspec_volatile:GPI [(const_int 0)] GET_FPSCR))]

>    ""

> -  "mrs\\t%0, fpsr"

> +  "mrs\\t%0, <fpscr_name>"

>    [(set_attr "type" "mrs")])

>  

> -

>  ;; Define the subtract-one-and-jump insns so loop.c

>  ;; knows what to generate.

>  (define_expand "doloop_end"

> diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md

> index a568cf21b99d..9a5191689634 100644

> --- a/gcc/config/aarch64/iterators.md

> +++ b/gcc/config/aarch64/iterators.md

> @@ -3453,3 +3453,17 @@

>  

>  (define_int_attr unspec [(UNSPEC_WHILERW "UNSPEC_WHILERW")

>  			 (UNSPEC_WHILEWR "UNSPEC_WHILEWR")])

> +

> +;; Iterators and attributes for fpcr fpsr getter setters

> +

> +(define_int_iterator GET_FPSCR

> +  [UNSPECV_GET_FPSR UNSPECV_GET_FPCR])

> +

> +(define_int_iterator SET_FPSCR

> +  [UNSPECV_SET_FPSR UNSPECV_SET_FPCR])

> +

> +(define_int_attr fpscr_name

> +  [(UNSPECV_GET_FPSR "fpsr")

> +   (UNSPECV_SET_FPSR "fpsr")

> +   (UNSPECV_GET_FPCR "fpcr")

> +   (UNSPECV_SET_FPCR "fpcr")])

> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi

> index 10dc32e6d2d4..29a6635ad134 100644

> --- a/gcc/doc/extend.texi

> +++ b/gcc/doc/extend.texi

> @@ -13880,6 +13880,12 @@ unsigned int __builtin_aarch64_get_fpcr ()

>  void __builtin_aarch64_set_fpcr (unsigned int)

>  unsigned int __builtin_aarch64_get_fpsr ()

>  void __builtin_aarch64_set_fpsr (unsigned int)

> +

> +unsigned long long __builtin_aarch64_get_fpcr64 ()

> +void __builtin_aarch64_set_fpcr64 (unsigned long long)

> +unsigned long long __builtin_aarch64_get_fpsr64 ()

> +void __builtin_aarch64_set_fpsr64 (unsigned long long)

> +


Excess blank line.

>  @end smallexample

>  

>  @node Alpha Built-in Functions

> diff --git a/gcc/testsuite/gcc.target/aarch64/get_fpcr64.c b/gcc/testsuite/gcc.target/aarch64/get_fpcr64.c


Very minor, but it's probably more future-proof to add _1 to the filenames
of the tests.

> new file mode 100644

> index 000000000000..9fed91fe2053

> --- /dev/null

> +++ b/gcc/testsuite/gcc.target/aarch64/get_fpcr64.c

> @@ -0,0 +1,10 @@

> +/* { dg-do compile } */

> +/* { dg-options "-O2" } */

> +

> +long long unsigned

> +get_fpcr64 ()

> +{

> +  return __builtin_aarch64_get_fpcr64 ();

> +}

> +

> +/* { dg-final { scan-assembler-times "mrs.*fpcr" 1 } } */


Probably safer as: {\tmrs\t[^\n]*fpcr}

(“.” matches newlines in this context.)

Although since the test is running at -O2, we should be able to rely on
x0 being chosen, so I think we should just use: {\tmrs\tx0, fpcr\n}

Same idea for the other tests.

OK with those changes, thanks.

Richard
Andrea Corallo July 1, 2020, 3:39 p.m. | #2
Richard Sandiford <richard.sandiford@arm.com> writes:

> OK with those changes, thanks.

>

> Richard


Hi Richard,

thanks for the quick review.

I've installed the patch with the suggested changes as:

0d7e5fa655e aarch64: Add 64 bit setter getter fpsr fpcr

Regards

  Andrea

gcc/ChangeLog

        * config/aarch64/aarch64-builtins.c (aarch64_builtins): Add enums
        for 64bits fpsr/fpcr getter setters builtin variants.
        (aarch64_init_fpsr_fpcr_builtins): New function.
        (aarch64_general_init_builtins): Modify to make use of the later.
        (aarch64_expand_fpsr_fpcr_setter): New function.
        (aarch64_general_expand_builtin): Modify to make use of the later.
        * config/aarch64/aarch64.md (@aarch64_set_<fpscr_name><GPI:mode>)
        (@aarch64_get_<fpscr_name><GPI:mode>): New patterns replacing and
        generalizing 'get_fpcr', 'set_fpsr'.
        * config/aarch64/iterators.md (GET_FPSCR, SET_FPSCR): New int
        iterators.
        (fpscr_name): New int attribute.
        * doc/extend.texi (__builtin_aarch64_get_fpcr64)
        (__builtin_aarch64_set_fpcr64, __builtin_aarch64_get_fpsr64)
        (__builtin_aarch64_set_fpsr64): Add into AArch64 Built-in
        Functions.

gcc/testsuite/ChangeLog

        * gcc.target/aarch64/get_fpcr64_1.c: New test.
        * gcc.target/aarch64/set_fpcr64_1.c: New test.
        * gcc.target/aarch64/get_fpsr64_1.c: New test.
        * gcc.target/aarch64/set_fpsr64_1.c: New test.

Patch

From 96a285d0a80cbf3e1e06d7c5a6d4d2e37dd28c65 Mon Sep 17 00:00:00 2001
From: Andrea Corallo <andrea.corallo@arm.com>
Date: Thu, 28 May 2020 08:49:42 +0100
Subject: [PATCH] aarch64: Add 64 bit setter getter fpsr fpcr

gcc/ChangeLog

	* config/aarch64/aarch64-builtins.c (aarch64_builtins): Add enums
	for 64bits fpsr/fpcr getter setters builtin variants.
	(aarch64_init_fpsr_fpcr_builtins): New function.
	(aarch64_general_init_builtins): Modify to make use of the later.
	(aarch64_expand_fpsr_fpcr_setter): New function.
	(aarch64_general_expand_builtin): Modify to make use of the later.
	* config/aarch64/aarch64.md (@aarch64_set_<fpscr_name><GPI:mode>)
	(@aarch64_get_<fpscr_name><GPI:mode>): New patterns replacing and
	generalizing 'get_fpcr', 'set_fpsr'.
	* config/aarch64/iterators.md (GET_FPSCR, SET_FPSCR): New int
	iterators.
	(fpscr_name): New int attribute.
	* doc/extend.texi (__builtin_aarch64_get_fpcr64)
	(__builtin_aarch64_set_fpcr64, __builtin_aarch64_get_fpsr64)
	(__builtin_aarch64_set_fpsr64): Add into AArch64 Built-in
	Functions.

gcc/testsuite/ChangeLog

2020-05-28  Andrea Corallo  <andrea.corallo@arm.com>

	* gcc.target/aarch64/get_fpcr64.c: New test.
	* gcc.target/aarch64/set_fpcr64.c: New test.
	* gcc.target/aarch64/get_fpsr64.c: New test.
	* gcc.target/aarch64/set_fpsr64.c: New test.
---
 gcc/config/aarch64/aarch64-builtins.c         | 103 +++++++++++++-----
 gcc/config/aarch64/aarch64.md                 |  32 ++----
 gcc/config/aarch64/iterators.md               |  14 +++
 gcc/doc/extend.texi                           |   6 +
 gcc/testsuite/gcc.target/aarch64/get_fpcr64.c |  10 ++
 gcc/testsuite/gcc.target/aarch64/get_fpsr64.c |  10 ++
 gcc/testsuite/gcc.target/aarch64/set_fpcr64.c |  10 ++
 gcc/testsuite/gcc.target/aarch64/set_fpsr64.c |  10 ++
 8 files changed, 142 insertions(+), 53 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/get_fpcr64.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/get_fpsr64.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/set_fpcr64.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/set_fpsr64.c

diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c
index 95213cd70c84..2990026cfb73 100644
--- a/gcc/config/aarch64/aarch64-builtins.c
+++ b/gcc/config/aarch64/aarch64-builtins.c
@@ -448,6 +448,11 @@  enum aarch64_builtins
   AARCH64_BUILTIN_GET_FPSR,
   AARCH64_BUILTIN_SET_FPSR,
 
+  AARCH64_BUILTIN_GET_FPCR64,
+  AARCH64_BUILTIN_SET_FPCR64,
+  AARCH64_BUILTIN_GET_FPSR64,
+  AARCH64_BUILTIN_SET_FPSR64,
+
   AARCH64_BUILTIN_RSQRT_DF,
   AARCH64_BUILTIN_RSQRT_SF,
   AARCH64_BUILTIN_RSQRT_V2DF,
@@ -1245,33 +1250,65 @@  aarch64_init_memtag_builtins (void)
 #undef AARCH64_INIT_MEMTAG_BUILTINS_DECL
 }
 
-/* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group.  */
+/* Initialize fpsr fpcr getters and setters.  */
 
-void
-aarch64_general_init_builtins (void)
+static void
+aarch64_init_fpsr_fpcr_builtins (void)
 {
-  tree ftype_set_fpr
+  tree ftype_set
     = build_function_type_list (void_type_node, unsigned_type_node, NULL);
-  tree ftype_get_fpr
+  tree ftype_get
     = build_function_type_list (unsigned_type_node, NULL);
 
   aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPCR]
     = aarch64_general_add_builtin ("__builtin_aarch64_get_fpcr",
-				   ftype_get_fpr,
+				   ftype_get,
 				   AARCH64_BUILTIN_GET_FPCR);
   aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR]
     = aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr",
-				   ftype_set_fpr,
+				   ftype_set,
 				   AARCH64_BUILTIN_SET_FPCR);
   aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR]
     = aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr",
-				   ftype_get_fpr,
+				   ftype_get,
 				   AARCH64_BUILTIN_GET_FPSR);
   aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR]
     = aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr",
-				   ftype_set_fpr,
+				   ftype_set,
 				   AARCH64_BUILTIN_SET_FPSR);
 
+  ftype_set
+    = build_function_type_list (void_type_node, long_long_unsigned_type_node,
+				NULL);
+  ftype_get
+    = build_function_type_list (long_long_unsigned_type_node, NULL);
+
+  aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPCR64]
+    = aarch64_general_add_builtin ("__builtin_aarch64_get_fpcr64",
+				   ftype_get,
+				   AARCH64_BUILTIN_GET_FPCR64);
+  aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR64]
+    = aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr64",
+				   ftype_set,
+				   AARCH64_BUILTIN_SET_FPCR64);
+  aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR64]
+    = aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr64",
+				   ftype_get,
+				   AARCH64_BUILTIN_GET_FPSR64);
+  aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR64]
+    = aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr64",
+				   ftype_set,
+				   AARCH64_BUILTIN_SET_FPSR64);
+}
+
+/* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group.  */
+
+void
+aarch64_general_init_builtins (void)
+{
+
+  aarch64_init_fpsr_fpcr_builtins ();
+
   aarch64_init_fp16_types ();
 
   aarch64_init_bf16_types ();
@@ -1876,6 +1913,14 @@  aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target)
   return target;
 }
 
+static void
+aarch64_expand_fpsr_fpcr_setter (int unspec, machine_mode mode, tree exp)
+{
+  tree arg = CALL_EXPR_ARG (exp, 0);
+  rtx op = force_reg (mode, expand_normal (arg));
+  emit_insn (gen_aarch64_set (unspec, mode, op));
+}
+
 /* Expand an expression EXP that calls built-in function FCODE,
    with result going to TARGET if that's convenient.  IGNORE is true
    if the result of the builtin is ignored.  */
@@ -1884,35 +1929,35 @@  aarch64_general_expand_builtin (unsigned int fcode, tree exp, rtx target,
 				int ignore)
 {
   int icode;
-  rtx pat, op0;
+  rtx op0;
   tree arg0;
 
   switch (fcode)
     {
     case AARCH64_BUILTIN_GET_FPCR:
+      emit_insn (gen_aarch64_get (UNSPECV_GET_FPCR, SImode, target));
+      return target;
     case AARCH64_BUILTIN_SET_FPCR:
+      aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPCR, SImode, exp);
+      return target;
     case AARCH64_BUILTIN_GET_FPSR:
+      emit_insn (gen_aarch64_get (UNSPECV_GET_FPSR, SImode, target));
+      return target;
     case AARCH64_BUILTIN_SET_FPSR:
-      if ((fcode == AARCH64_BUILTIN_GET_FPCR)
-	  || (fcode == AARCH64_BUILTIN_GET_FPSR))
-	{
-	  icode = (fcode == AARCH64_BUILTIN_GET_FPSR) ?
-	    CODE_FOR_get_fpsr : CODE_FOR_get_fpcr;
-	  target = gen_reg_rtx (SImode);
-	  pat = GEN_FCN (icode) (target);
-	}
-      else
-	{
-	  target = NULL_RTX;
-	  icode = (fcode == AARCH64_BUILTIN_SET_FPSR) ?
-	    CODE_FOR_set_fpsr : CODE_FOR_set_fpcr;
-	  arg0 = CALL_EXPR_ARG (exp, 0);
-	  op0 = force_reg (SImode, expand_normal (arg0));
-	  pat = GEN_FCN (icode) (op0);
-	}
-      emit_insn (pat);
+      aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, SImode, exp);
+      return target;
+    case AARCH64_BUILTIN_GET_FPCR64:
+      emit_insn (gen_aarch64_get (UNSPECV_GET_FPCR, DImode, target));
+      return target;
+    case AARCH64_BUILTIN_SET_FPCR64:
+      aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPCR, DImode, exp);
+      return target;
+    case AARCH64_BUILTIN_GET_FPSR64:
+      emit_insn (gen_aarch64_get (UNSPECV_GET_FPSR, DImode, target));
+      return target;
+    case AARCH64_BUILTIN_SET_FPSR64:
+      aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, DImode, exp);
       return target;
-
     case AARCH64_PAUTH_BUILTIN_AUTIA1716:
     case AARCH64_PAUTH_BUILTIN_PACIA1716:
     case AARCH64_PAUTH_BUILTIN_AUTIB1716:
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index deca0004fedc..75f9e9e97e8b 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -7230,37 +7230,21 @@ 
   [(set_attr "length" "12")
    (set_attr "type" "multiple")])
 
-;; Write Floating-point Control Register.
-(define_insn "set_fpcr"
-  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPCR)]
+;; Write into Floating-point Status Register.
+(define_insn "@aarch64_set_<fpscr_name><GPI:mode>"
+  [(unspec_volatile [(match_operand:GPI 0 "register_operand" "r")] SET_FPSCR)]
   ""
-  "msr\\tfpcr, %0"
+  "msr\\t<fpscr_name>, %0"
   [(set_attr "type" "mrs")])
 
 ;; Read Floating-point Control Register.
-(define_insn "get_fpcr"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-        (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPCR))]
-  ""
-  "mrs\\t%0, fpcr"
-  [(set_attr "type" "mrs")])
-
-;; Write Floating-point Status Register.
-(define_insn "set_fpsr"
-  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")] UNSPECV_SET_FPSR)]
-  ""
-  "msr\\tfpsr, %0"
-  [(set_attr "type" "mrs")])
-
-;; Read Floating-point Status Register.
-(define_insn "get_fpsr"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-        (unspec_volatile:SI [(const_int 0)] UNSPECV_GET_FPSR))]
+(define_insn "@aarch64_get_<fpscr_name><GPI:mode>"
+  [(set (match_operand:GPI 0 "register_operand" "=r")
+        (unspec_volatile:GPI [(const_int 0)] GET_FPSCR))]
   ""
-  "mrs\\t%0, fpsr"
+  "mrs\\t%0, <fpscr_name>"
   [(set_attr "type" "mrs")])
 
-
 ;; Define the subtract-one-and-jump insns so loop.c
 ;; knows what to generate.
 (define_expand "doloop_end"
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index a568cf21b99d..9a5191689634 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -3453,3 +3453,17 @@ 
 
 (define_int_attr unspec [(UNSPEC_WHILERW "UNSPEC_WHILERW")
 			 (UNSPEC_WHILEWR "UNSPEC_WHILEWR")])
+
+;; Iterators and attributes for fpcr fpsr getter setters
+
+(define_int_iterator GET_FPSCR
+  [UNSPECV_GET_FPSR UNSPECV_GET_FPCR])
+
+(define_int_iterator SET_FPSCR
+  [UNSPECV_SET_FPSR UNSPECV_SET_FPCR])
+
+(define_int_attr fpscr_name
+  [(UNSPECV_GET_FPSR "fpsr")
+   (UNSPECV_SET_FPSR "fpsr")
+   (UNSPECV_GET_FPCR "fpcr")
+   (UNSPECV_SET_FPCR "fpcr")])
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 10dc32e6d2d4..29a6635ad134 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -13880,6 +13880,12 @@  unsigned int __builtin_aarch64_get_fpcr ()
 void __builtin_aarch64_set_fpcr (unsigned int)
 unsigned int __builtin_aarch64_get_fpsr ()
 void __builtin_aarch64_set_fpsr (unsigned int)
+
+unsigned long long __builtin_aarch64_get_fpcr64 ()
+void __builtin_aarch64_set_fpcr64 (unsigned long long)
+unsigned long long __builtin_aarch64_get_fpsr64 ()
+void __builtin_aarch64_set_fpsr64 (unsigned long long)
+
 @end smallexample
 
 @node Alpha Built-in Functions
diff --git a/gcc/testsuite/gcc.target/aarch64/get_fpcr64.c b/gcc/testsuite/gcc.target/aarch64/get_fpcr64.c
new file mode 100644
index 000000000000..9fed91fe2053
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/get_fpcr64.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long long unsigned
+get_fpcr64 ()
+{
+  return __builtin_aarch64_get_fpcr64 ();
+}
+
+/* { dg-final { scan-assembler-times "mrs.*fpcr" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/get_fpsr64.c b/gcc/testsuite/gcc.target/aarch64/get_fpsr64.c
new file mode 100644
index 000000000000..f5d8f76d9382
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/get_fpsr64.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+long long unsigned
+get_fpsr64 ()
+{
+  return __builtin_aarch64_get_fpsr64 ();
+}
+
+/* { dg-final { scan-assembler-times "mrs.*fpsr" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/set_fpcr64.c b/gcc/testsuite/gcc.target/aarch64/set_fpcr64.c
new file mode 100644
index 000000000000..2390abff4d17
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/set_fpcr64.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+set_fpcr64 (long long unsigned x)
+{
+  return __builtin_aarch64_set_fpcr64 (x);
+}
+
+/* { dg-final { scan-assembler-times "msr.*fpcr" 1 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/set_fpsr64.c b/gcc/testsuite/gcc.target/aarch64/set_fpsr64.c
new file mode 100644
index 000000000000..0ed3da2bce87
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/set_fpsr64.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+set_fpsr64 (long long unsigned x)
+{
+  return __builtin_aarch64_set_fpsr64 (x);
+}
+
+/* { dg-final { scan-assembler-times "msr.*fpsr" 1 } } */
-- 
2.17.1