Hi all, I'd like to submit this patch introducing 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) Regards Andrea gcc/ChangeLog: 2020-??-?? Andrea Corallo <andrea.cora...@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_expand_fcr_fpsr_builtin): New function. (aarch64_general_expand_builtin): Modify to make use of the later. * config/aarch64/aarch64.md (UNSPECV_GET_FPCR64) (UNSPECV_SET_FPCR64, UNSPECV_GET_FPSR64, UNSPECV_SET_FPSR64): Add 4 new unpecv. (set_fpcr64, get_fpcr64,set_fpsr64, get_fpsr64): New patterns. * 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.cora...@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.
diff --git a/gcc/config/aarch64/aarch64-builtins.c b/gcc/config/aarch64/aarch64-builtins.c index 9c9c6d86ae29..b3ffa3893c08 100644 --- a/gcc/config/aarch64/aarch64-builtins.c +++ b/gcc/config/aarch64/aarch64-builtins.c @@ -443,6 +443,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, @@ -1240,33 +1245,65 @@ aarch64_init_memtag_builtins (void) #undef AARCH64_INIT_MEMTAG_BUILTINS_DECL } -/* Initialize all builtins in the AARCH64_BUILTIN_GENERAL group. */ +/* Initialize fpsr fpcr getter 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 (); @@ -1871,6 +1908,40 @@ aarch64_expand_builtin_memtag (int fcode, tree exp, rtx target) return target; } +static rtx +aarch64_expand_fcr_fpsr_builtin (tree exp, machine_mode mode, bool getter, + bool fpsr) +{ + int icode; + rtx pat; + rtx target = NULL_RTX; + + gcc_assert (mode == SImode || (mode == DImode)); + + if (getter) + { + if (mode == SImode) + icode = fpsr ? CODE_FOR_get_fpsr : CODE_FOR_get_fpcr; + else + icode = fpsr ? CODE_FOR_get_fpsr64 : CODE_FOR_get_fpcr64; + target = gen_reg_rtx (mode); + pat = GEN_FCN (icode) (target); + } + else + { + target = NULL_RTX; + if (mode == SImode) + icode = fpsr ? CODE_FOR_set_fpsr : CODE_FOR_set_fpcr; + else + icode = fpsr ? CODE_FOR_set_fpsr64 : CODE_FOR_set_fpcr64; + tree arg = CALL_EXPR_ARG (exp, 0); + rtx op = force_reg (mode, expand_normal (arg)); + pat = GEN_FCN (icode) (op); + } + emit_insn (pat); + return target; +} + /* 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. */ @@ -1879,35 +1950,27 @@ 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: + return aarch64_expand_fcr_fpsr_builtin (exp, SImode, true, false); case AARCH64_BUILTIN_SET_FPCR: + return aarch64_expand_fcr_fpsr_builtin (exp, SImode, false, false); case AARCH64_BUILTIN_GET_FPSR: + return aarch64_expand_fcr_fpsr_builtin (exp, SImode, true, true); 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); - return target; - + return aarch64_expand_fcr_fpsr_builtin (exp, SImode, false, true); + case AARCH64_BUILTIN_GET_FPCR64: + return aarch64_expand_fcr_fpsr_builtin (exp, DImode, true, false); + case AARCH64_BUILTIN_SET_FPCR64: + return aarch64_expand_fcr_fpsr_builtin (exp, DImode, false, false); + case AARCH64_BUILTIN_GET_FPSR64: + return aarch64_expand_fcr_fpsr_builtin (exp, DImode, true, true); + case AARCH64_BUILTIN_SET_FPSR64: + return aarch64_expand_fcr_fpsr_builtin (exp, DImode, false, true); 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 7ad4e918578b..b6836710c9c2 100644 --- a/gcc/config/aarch64/aarch64.md +++ b/gcc/config/aarch64/aarch64.md @@ -289,6 +289,10 @@ UNSPECV_SET_FPCR ; Represent assign of FPCR content. UNSPECV_GET_FPSR ; Represent fetch of FPSR content. UNSPECV_SET_FPSR ; Represent assign of FPSR content. + UNSPECV_GET_FPCR64 ; Represent fetch of 64 bits FPCR content. + UNSPECV_SET_FPCR64 ; Represent assign of 64 bits FPCR content. + UNSPECV_GET_FPSR64 ; Represent fetch of 64 bits FPSR content. + UNSPECV_SET_FPSR64 ; Represent assign of 64 bits FPSR content. UNSPECV_BLOCKAGE ; Represent a blockage UNSPECV_PROBE_STACK_RANGE ; Represent stack range probing. UNSPECV_SPECULATION_BARRIER ; Represent speculation barrier. @@ -7198,6 +7202,35 @@ "mrs\\t%0, fpsr" [(set_attr "type" "mrs")]) +;; Write 64 bits into Floating-point Control Register. +(define_insn "set_fpcr64" + [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] UNSPECV_SET_FPCR64)] + "" + "msr\\tfpcr, %0" + [(set_attr "type" "mrs")]) + +;; Read Floating-point Control Register 64 bits. +(define_insn "get_fpcr64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(const_int 0)] UNSPECV_GET_FPCR64))] + "" + "mrs\\t%0, fpcr" + [(set_attr "type" "mrs")]) + +;; Write 64 bits into Floating-point Status Register. +(define_insn "set_fpsr64" + [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")] UNSPECV_SET_FPSR64)] + "" + "msr\\tfpsr, %0" + [(set_attr "type" "mrs")]) + +;; Read Floating-point Status Register 64 bits. +(define_insn "get_fpsr64" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec_volatile:DI [(const_int 0)] UNSPECV_GET_FPSR64))] + "" + "mrs\\t%0, fpsr" + [(set_attr "type" "mrs")]) ;; Define the subtract-one-and-jump insns so loop.c ;; knows what to generate. diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 11b79a5852c1..2ec30537146a 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13768,6 +13768,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 } } */