Message ID | gkrwo7s8rli.fsf@arm.com |
---|---|
State | New |
Headers | show |
Series | [1/2,aarch64] Rework fpcr fpsr getter/setter builtins | expand |
Andrea Corallo <andrea.corallo@arm.com> writes: > 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.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_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.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. Hi all, Leaving aside 2/2, I've retested this one (1/2) on top of current master. Regtested and bootstrapped on aarch64-linux-gnu. Is it okay for trunk? Regards Andrea
Andrea Corallo <andrea.corallo@arm.com> writes: > Andrea Corallo <andrea.corallo@arm.com> writes: > >> 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.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_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.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. > > Hi all, > > Leaving aside 2/2, I've retested this one (1/2) on top of current > master. > > Regtested and bootstrapped on aarch64-linux-gnu. > > Is it okay for trunk? > > Regards > > Andrea Ping Andrea
Andrea Corallo <andrea.corallo@arm.com> writes: > 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) Sound like this part is uncontroversial. At least, if anyone objects to it, they should have said so earlier :-) > @@ -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. */ “getters” > @@ -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")]) I think instead we should replace the existing and new patterns with something like: (define_insn "@aarch64_get_<GET_FPSCR:name><GPI:mode>" [(set (...:GPI ...) (unspec_volatile:GPI ... GET_FPSCR))] "mrs... <GET_FPSCR:name>" ...) for the getter and similarly for the setter, giving 2 patterns in total. GET_FPSCR would be a define_int_iterator iterating over UNSPECV_GET_FPSR and UNSPECV_GET_FPCR. We wouldn't need separate unspecs for the 64-bit versions; that would be indicated by the mode instead. Then aarch64_expand_fcr_fpsr_builtin splits naturally into two: one for getters and one for setters. The getter side would need: gen_arch64_get (unspec_id, mode, target) where unspec_id is UNSPECV_GET_FPSR or UNSPECV_GET_FPCR. Similarly for the setter side. Thanks, Richard
Richard Sandiford <richard.sandiford@arm.com> writes: > Andrea Corallo <andrea.corallo@arm.com> writes: >> 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) > > Sound like this part is uncontroversial. At least, if anyone objects > to it, they should have said so earlier :-) > >> @@ -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. */ > > “getters” > >> @@ -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")]) > > I think instead we should replace the existing and new patterns with > something like: > > (define_insn "@aarch64_get_<GET_FPSCR:name><GPI:mode>" > [(set (...:GPI ...) > (unspec_volatile:GPI ... GET_FPSCR))] > "mrs... <GET_FPSCR:name>" > ...) > > for the getter and similarly for the setter, giving 2 patterns in total. > GET_FPSCR would be a define_int_iterator iterating over UNSPECV_GET_FPSR > and UNSPECV_GET_FPCR. We wouldn't need separate unspecs for the 64-bit > versions; that would be indicated by the mode instead. > > Then aarch64_expand_fcr_fpsr_builtin splits naturally into two: > one for getters and one for setters. The getter side would need: > > gen_arch64_get (unspec_id, mode, target) > > where unspec_id is UNSPECV_GET_FPSR or UNSPECV_GET_FPCR. > Similarly for the setter side. > > Thanks, > Richard Thanks for the review, I'll update the patch. Andrea
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 } } */