backend: Implement FpsrManager

This commit is contained in:
Merry 2022-08-02 00:33:59 +01:00 committed by merry
parent 72026c91b5
commit 60a119da6a
3 changed files with 75 additions and 0 deletions

View file

@ -390,6 +390,8 @@ elseif(ARCHITECTURE STREQUAL "arm64")
backend/arm64/emit_arm64_vector_floating_point.cpp backend/arm64/emit_arm64_vector_floating_point.cpp
backend/arm64/emit_arm64_vector_saturation.cpp backend/arm64/emit_arm64_vector_saturation.cpp
backend/arm64/emit_context.h backend/arm64/emit_context.h
backend/arm64/fpsr_manager.cpp
backend/arm64/fpsr_manager.h
backend/arm64/reg_alloc.cpp backend/arm64/reg_alloc.cpp
backend/arm64/reg_alloc.h backend/arm64/reg_alloc.h
backend/arm64/stack_layout.h backend/arm64/stack_layout.h

View file

@ -0,0 +1,40 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#include "dynarmic/backend/arm64/fpsr_manager.h"
#include <oaknut/oaknut.hpp>
#include "dynarmic/backend/arm64/abi.h"
namespace Dynarmic::Backend::Arm64 {
using namespace oaknut::util;
FpsrManager::FpsrManager(oaknut::CodeGenerator& code, size_t state_fpsr_offset)
: code{code}, state_fpsr_offset{state_fpsr_offset} {}
void FpsrManager::Spill() {
if (!fpsr_loaded)
return;
code.LDR(Wscratch0, Xstate, state_fpsr_offset);
code.MSR(oaknut::SystemReg::FPSR, Xscratch1);
code.ORR(Wscratch0, Wscratch0, Wscratch1);
code.STR(Wscratch0, Xstate, state_fpsr_offset);
fpsr_loaded = false;
}
void FpsrManager::Load() {
if (fpsr_loaded)
return;
code.MRS(XZR, oaknut::SystemReg::FPSR);
fpsr_loaded = true;
}
} // namespace Dynarmic::Backend::Arm64

View file

@ -0,0 +1,33 @@
/* This file is part of the dynarmic project.
* Copyright (c) 2022 MerryMage
* SPDX-License-Identifier: 0BSD
*/
#pragma once
#include <mcl/stdint.hpp>
namespace oaknut {
struct PointerCodeGeneratorPolicy;
template<typename>
class BasicCodeGenerator;
using CodeGenerator = BasicCodeGenerator<PointerCodeGeneratorPolicy>;
} // namespace oaknut
namespace Dynarmic::Backend::Arm64 {
class FpsrManager {
public:
explicit FpsrManager(oaknut::CodeGenerator& code, size_t state_fpsr_offset);
void Spill();
void Load();
void Overwrite() { fpsr_loaded = false; }
private:
oaknut::CodeGenerator& code;
size_t state_fpsr_offset;
bool fpsr_loaded = false;
};
} // namespace Dynarmic::Backend::Arm64