From 0d7e5fa655e59c99035bf94a46c912e369bb9fa0 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 * 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. --- gcc/config/aarch64/aarch64-builtins.c | 134 ++++++++++++------ gcc/config/aarch64/aarch64.md | 34 ++--- gcc/config/aarch64/iterators.md | 14 ++ gcc/doc/extend.texi | 5 + .../gcc.target/aarch64/get_fpcr64_1.c | 10 ++ .../gcc.target/aarch64/get_fpsr64_1.c | 10 ++ .../gcc.target/aarch64/set_fpcr64_1.c | 10 ++ .../gcc.target/aarch64/set_fpsr64_1.c | 10 ++ 8 files changed, 158 insertions(+), 69 deletions(-) create mode 100644 gcc/testsuite/gcc.target/aarch64/get_fpcr64_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/get_fpsr64_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/set_fpcr64_1.c create mode 100644 gcc/testsuite/gcc.target/aarch64/set_fpsr64_1.c diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index e87a4559c36..49dfbafec3a 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -450,6 +450,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, @@ -1247,32 +1252,63 @@ aarch64_init_memtag_builtins (void) #undef AARCH64_INIT_MEMTAG_BUILTINS_DECL } +/* Initialize fpsr fpcr getters and setters. */ + +static void +aarch64_init_fpsr_fpcr_builtins (void) +{ + tree ftype_set + = build_function_type_list (void_type_node, unsigned_type_node, NULL); + 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, + AARCH64_BUILTIN_GET_FPCR); + aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR] + = aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr", + ftype_set, + AARCH64_BUILTIN_SET_FPCR); + aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR] + = aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr", + ftype_get, + AARCH64_BUILTIN_GET_FPSR); + aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR] + = aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr", + 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) { - tree ftype_set_fpr - = build_function_type_list (void_type_node, unsigned_type_node, NULL); - tree ftype_get_fpr - = 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, - AARCH64_BUILTIN_GET_FPCR); - aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPCR] - = aarch64_general_add_builtin ("__builtin_aarch64_set_fpcr", - ftype_set_fpr, - AARCH64_BUILTIN_SET_FPCR); - aarch64_builtin_decls[AARCH64_BUILTIN_GET_FPSR] - = aarch64_general_add_builtin ("__builtin_aarch64_get_fpsr", - ftype_get_fpr, - AARCH64_BUILTIN_GET_FPSR); - aarch64_builtin_decls[AARCH64_BUILTIN_SET_FPSR] - = aarch64_general_add_builtin ("__builtin_aarch64_set_fpsr", - ftype_set_fpr, - AARCH64_BUILTIN_SET_FPSR); + aarch64_init_fpsr_fpcr_builtins (); aarch64_init_fp16_types (); @@ -1878,6 +1914,16 @@ aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target) return target; } +/* Expand an expression EXP as fpsr or cpsr setter (depending on + UNSPEC) using MODE. */ +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. */ @@ -1886,35 +1932,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: - case AARCH64_BUILTIN_SET_FPCR: - case AARCH64_BUILTIN_GET_FPSR: - 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); + 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: + 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 deca0004fed..c98ec7c3570 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 the Floating-point Status or Control 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))] +;; Read into the Floating-point Status or Control Register. +(define_insn "@aarch64_get_" + [(set (match_operand:GPI 0 "register_operand" "=r") + (unspec_volatile:GPI [(const_int 0)] GET_FPSCR))] "" - "mrs\\t%0, fpcr" + "mrs\\t%0, " [(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))] - "" - "mrs\\t%0, fpsr" - [(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 a568cf21b99..9a519168963 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 5a57c1c49c5..ecd3661d257 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13881,6 +13881,11 @@ 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_1.c b/gcc/testsuite/gcc.target/aarch64/get_fpcr64_1.c new file mode 100644 index 00000000000..66afca49107 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/get_fpcr64_1.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 {\tmrs\tx0, fpcr\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/get_fpsr64_1.c b/gcc/testsuite/gcc.target/aarch64/get_fpsr64_1.c new file mode 100644 index 00000000000..9e94f1cf3ea --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/get_fpsr64_1.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 {\tmrs\tx0, fpsr\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/set_fpcr64_1.c b/gcc/testsuite/gcc.target/aarch64/set_fpcr64_1.c new file mode 100644 index 00000000000..0b95e33ad77 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/set_fpcr64_1.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 {\tmsr\tfpcr, x0\n} 1 } } */ diff --git a/gcc/testsuite/gcc.target/aarch64/set_fpsr64_1.c b/gcc/testsuite/gcc.target/aarch64/set_fpsr64_1.c new file mode 100644 index 00000000000..e0256ea4db9 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/set_fpsr64_1.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 {\tmsr\tfpsr, x0\n} 1 } } */