Andrea Corallo <andrea.cora...@arm.com> writes: > @@ -2034,6 +2034,16 @@ aarch64_expand_fpsr_fpcr_setter (int unspec, > machine_mode mode, tree exp) > emit_insn (gen_aarch64_set (unspec, mode, op)); > } > > +/* Expand a fpsr or fpcr getter (depending on UNSPEC) using MODE. > + Return the target. */ > +static rtx > +aarch64_expand_fpsr_fpcr_getter (int unspec, machine_mode mode) > +{ > + rtx target = gen_reg_rtx (mode); > + emit_insn (gen_aarch64_get (unspec, mode, target)); > + return target; > +}
I agree this is functionally correct, but if a valid target has been given to the caller, it's generally better to use it. So IMO it would be better to use the expand_insn machinery, passing the original target to create_output_operand. Thanks, Richard > + > /* 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. */ > @@ -2048,26 +2058,22 @@ aarch64_general_expand_builtin (unsigned int fcode, > tree exp, rtx target, > switch (fcode) > { > case AARCH64_BUILTIN_GET_FPCR: > - emit_insn (gen_aarch64_get (UNSPECV_GET_FPCR, SImode, target)); > - return target; > + return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPCR, SImode); > 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; > + return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPSR, SImode); > 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; > + return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPCR, DImode); > 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; > + return aarch64_expand_fpsr_fpcr_getter (UNSPECV_GET_FPSR, DImode); > case AARCH64_BUILTIN_SET_FPSR64: > aarch64_expand_fpsr_fpcr_setter (UNSPECV_SET_FPSR, DImode, exp); > return target; > diff --git a/gcc/testsuite/gcc.target/aarch64/pr96968.c > b/gcc/testsuite/gcc.target/aarch64/pr96968.c > new file mode 100644 > index 00000000000..21ffd955153 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/pr96968.c > @@ -0,0 +1,28 @@ > +/* { dg-options "-O1" } */ > + > +void > +fpsr_getter (void) > +{ > + unsigned int fpsr = __builtin_aarch64_get_fpsr (); > +} > + > +void > +fpsr64_getter (void) > +{ > + unsigned long fpsr = __builtin_aarch64_get_fpsr64 (); > +} > + > +void > +fpcr_getter (void) > +{ > + unsigned int fpcr = __builtin_aarch64_get_fpcr (); > +} > + > +void > +fpcr64_getter (void) > +{ > + unsigned long fpcr = __builtin_aarch64_get_fpcr64 (); > +} > + > +/* { dg-final { scan-assembler-times {\tmrs\tx0, fpsr\n} 2 } } */ > +/* { dg-final { scan-assembler-times {\tmrs\tx0, fpcr\n} 2 } } */