[A64] Optimize FPCR switching with lazy mode tracking

Replace per-op save/restore of FPCR in EmitWithVmxFpcr with tracked
lazy switching via ChangeFpcrMode. Consecutive VMX float ops in the
same basic block now emit a single FPCR switch instead of one per op.

ChangeFpcrMode loads pre-computed values from the backend context
(fpcr_fpu/fpcr_vmx) instead of MRS + read-modify-write, eliminating
an expensive system register read per switch.

FPU mode is restored at block boundaries and calls via ForgetFpcrMode.
Scalar FP sequences guard with ChangeFpcrMode(Fpu) which is a no-op
when already in FPU mode.
This commit is contained in:
Herman S.
2026-03-29 18:07:18 +09:00
parent 904c6c8b1c
commit 59f9fb9964
4 changed files with 32 additions and 20 deletions

View File

@@ -138,7 +138,12 @@ class A64Emitter : public Xbyak_aarch64::CodeGenerator {
static void HandleStackpointOverflowError(ppc::PPCContext* context);
void ForgetFpcrMode() { fpcr_mode_ = FPCRMode::Unknown; }
void ForgetFpcrMode() {
if (fpcr_mode_ == FPCRMode::Vmx) {
ChangeFpcrMode(FPCRMode::Fpu);
}
fpcr_mode_ = FPCRMode::Unknown;
}
bool ChangeFpcrMode(FPCRMode new_mode, bool already_set = false);
bool IsFeatureEnabled(uint64_t feature_flag) const {
return (feature_flags_ & feature_flag) == feature_flag;