aarch64: Add support for moving fpm system register
Unlike most system registers, fpmr can be heavily written to in code that
exercises the fp8 functionality. That is because every fp8 instrinsic call
can potentially change the value of fpmr.
Rather than just use an unspec, we treat the fpmr system register like
all other registers and use a move operation to read and write to it.
We introduce a new class of moveable system registers that, currently,
only accepts fpmr and a new constraint, Umv, that allows us to
selectively use mrs and msr instructions when expanding rtl for them.
Given that there is code that depends on "real" registers coming before
"fake" ones, we introduce a new constant FPM_REGNUM that uses an
existing value and renumber registers below that.
This requires us to update the bitmaps that describe which registers
belong to each register class.
gcc/ChangeLog:
* config/aarch64/aarch64.cc (aarch64_hard_regno_nregs): Add
support for MOVEABLE_SYSREGS class.
(aarch64_hard_regno_mode_ok): Allow reads and writes to fpmr.
(aarch64_regno_regclass): Support MOVEABLE_SYSREGS class.
(aarch64_class_max_nregs): Likewise.
* config/aarch64/aarch64.h (FIXED_REGISTERS): add fpmr.
(CALL_REALLY_USED_REGISTERS): Likewise.
(REGISTER_NAMES): Likewise.
(enum reg_class): Add MOVEABLE_SYSREGS class.
(REG_CLASS_NAMES): Likewise.
(REG_CLASS_CONTENTS): Update class bitmaps to deal with fpmr,
the new MOVEABLE_REGS class and renumbering of registers.
* config/aarch64/aarch64.md: (FPM_REGNUM): added new register
number, reusing old value.
(FFR_REGNUM): Renumber.
(FFRT_REGNUM): Likewise.
(LOWERING_REGNUM): Likewise.
(TPIDR2_BLOCK_REGNUM): Likewise.
(SME_STATE_REGNUM): Likewise.
(TPIDR2_SETUP_REGNUM): Likewise.
(ZA_FREE_REGNUM): Likewise.
(ZA_SAVED_REGNUM): Likewise.
(ZA_REGNUM): Likewise.
(ZT0_REGNUM): Likewise.
(*mov<mode>_aarch64): Add support for moveable sysregs.
(*movsi_aarch64): Likewise.
(*movdi_aarch64): Likewise.
* config/aarch64/constraints.md (MOVEABLE_SYSREGS): New constraint.