From: Andrea Corallo Date: Thu, 28 May 2020 07:49:42 +0000 (+0100) Subject: aarch64: Add 64 bit setter getter fpsr fpcr X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0d7e5fa655e59c99035bf94a46c912e369bb9fa0;p=gcc.git 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. --- 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,33 +1252,64 @@ 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 (); @@ -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: + 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 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))] - "" - "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))] +;; 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, 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 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 } } */