From 96a285d0a80cbf3e1e06d7c5a6d4d2e37dd28c65 Mon Sep 17 00:00:00 2001 From: Andrea Corallo 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_) (@aarch64_get_): 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 * 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_" + [(unspec_volatile [(match_operand:GPI 0 "register_operand" "r")] SET_FPSCR)] "" - "msr\\tfpcr, %0" + "msr\\t, %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_" + [(set (match_operand:GPI 0 "register_operand" "=r") + (unspec_volatile:GPI [(const_int 0)] GET_FPSCR))] "" - "mrs\\t%0, fpsr" + "mrs\\t%0, " [(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