Richard Sandiford <richard.sandif...@arm.com> writes: > Andrea Corallo <andrea.cora...@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