backend: Implement FpsrManager
This commit is contained in:
parent
72026c91b5
commit
60a119da6a
3 changed files with 75 additions and 0 deletions
|
@ -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
|
||||||
|
|
40
src/dynarmic/backend/arm64/fpsr_manager.cpp
Normal file
40
src/dynarmic/backend/arm64/fpsr_manager.cpp
Normal 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
|
33
src/dynarmic/backend/arm64/fpsr_manager.h
Normal file
33
src/dynarmic/backend/arm64/fpsr_manager.h
Normal 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
|
Loading…
Reference in a new issue