Merge branch 'main' into android

This commit is contained in:
SSimco
2025-05-09 16:57:28 +03:00
4 changed files with 54 additions and 20 deletions
+8
View File
@@ -558,6 +558,14 @@ if(ANDROID)
endif()
endif()
if(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)")
target_sources(CemuCafe PRIVATE
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp
HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.h
)
target_link_libraries(CemuCafe PRIVATE xbyak_aarch64)
endif()
set_property(TARGET CemuCafe PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
target_include_directories(CemuCafe PUBLIC "../")
@@ -152,7 +152,6 @@ struct AArch64GenContext_t : CodeGenerator
void jump(IMLSegment* imlSegment);
void conditionalJumpCycleCheck(IMLSegment* imlSegment);
void gqr_generateScaleCode(const VReg& resReg, const VReg& dataReg, bool isLoad, bool scalePS1, const IMLReg& registerGQR);
static constexpr size_t MAX_JUMP_INSTR_COUNT = 2;
std::list<std::pair<size_t, JumpInfo>> jumps;
void prepareJump(JumpInfo&& jumpInfo)
@@ -282,16 +281,41 @@ struct AArch64GenContext_t : CodeGenerator
}
};
template<typename T>
template<std::derived_from<VRegSc> T>
T fpReg(const IMLReg& imlReg)
{
return T(imlReg.GetRegID() - IMLArchAArch64::PHYSREG_FPR_BASE);
cemu_assert_debug(imlReg.GetRegFormat() == IMLRegFormat::F64);
auto regId = imlReg.GetRegID();
cemu_assert_debug(regId >= IMLArchAArch64::PHYSREG_FPR_BASE && regId < IMLArchAArch64::PHYSREG_FPR_BASE + IMLArchAArch64::PHYSREG_FPR_COUNT);
return T(regId - IMLArchAArch64::PHYSREG_FPR_BASE);
}
template<typename T>
template<std::derived_from<RReg> T>
T gpReg(const IMLReg& imlReg)
{
return T(imlReg.GetRegID() - IMLArchAArch64::PHYSREG_GPR_BASE);
auto regFormat = imlReg.GetRegFormat();
if (std::is_same_v<T, WReg>)
cemu_assert_debug(regFormat == IMLRegFormat::I32);
else if (std::is_same_v<T, XReg>)
cemu_assert_debug(regFormat == IMLRegFormat::I64);
else
cemu_assert_unimplemented();
auto regId = imlReg.GetRegID();
cemu_assert_debug(regId >= IMLArchAArch64::PHYSREG_GPR_BASE && regId < IMLArchAArch64::PHYSREG_GPR_BASE + IMLArchAArch64::PHYSREG_GPR_COUNT);
return T(regId - IMLArchAArch64::PHYSREG_GPR_BASE);
}
template<std::derived_from<VRegSc> To, std::derived_from<VRegSc> From>
To aliasAs(const From& reg)
{
return To(reg.getIdx());
}
template<std::derived_from<RReg> To, std::derived_from<RReg> From>
To aliasAs(const From& reg)
{
return To(reg.getIdx());
}
AArch64GenContext_t::AArch64GenContext_t(Allocator* allocator)
@@ -314,7 +338,7 @@ constexpr bool isAdrImmValidFPR(sint32 imm, uint32 bits)
constexpr bool isAdrImmValidGPR(sint32 imm, uint32 bits = 32)
{
uint32 size = std::countr_zero(bits / 8u);
int32_t times = 1 << size;
sint32 times = 1 << size;
return (0 <= imm && imm <= 4095 * times) && ((uint64)imm & ones(size)) == 0;
}
@@ -357,7 +381,8 @@ void AArch64GenContext_t::r_name(IMLInstruction* imlInstruction)
if (imlInstruction->op_r_name.regR.GetBaseFormat() == IMLRegFormat::I64)
{
WReg regR = gpReg<WReg>(imlInstruction->op_r_name.regR);
XReg regRXReg = gpReg<XReg>(imlInstruction->op_r_name.regR);
WReg regR = aliasAs<WReg>(regRXReg);
if (name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0 + 32)
{
ldr(regR, AdrUimm(HCPU_REG, offsetof(PPCInterpreter_t, gpr) + sizeof(uint32) * (name - PPCREC_NAME_R0)));
@@ -437,7 +462,8 @@ void AArch64GenContext_t::name_r(IMLInstruction* imlInstruction)
if (imlInstruction->op_r_name.regR.GetBaseFormat() == IMLRegFormat::I64)
{
auto regR = gpReg<WReg>(imlInstruction->op_r_name.regR);
XReg regRXReg = gpReg<XReg>(imlInstruction->op_r_name.regR);
WReg regR = aliasAs<WReg>(regRXReg);
if (name >= PPCREC_NAME_R0 && name < PPCREC_NAME_R0 + 32)
{
str(regR, AdrUimm(HCPU_REG, offsetof(PPCInterpreter_t, gpr) + sizeof(uint32) * (name - PPCREC_NAME_R0)));
@@ -658,7 +684,7 @@ bool AArch64GenContext_t::r_r_s32_carry(IMLInstruction* imlInstruction)
bool AArch64GenContext_t::r_r_r(IMLInstruction* imlInstruction)
{
WReg regResult = gpReg<WReg>(imlInstruction->op_r_r_r.regR);
XReg reg64Result = gpReg<XReg>(imlInstruction->op_r_r_r.regR);
XReg reg64Result = aliasAs<XReg>(regResult);
WReg regOperand1 = gpReg<WReg>(imlInstruction->op_r_r_r.regA);
WReg regOperand2 = gpReg<WReg>(imlInstruction->op_r_r_r.regB);
@@ -860,12 +886,12 @@ bool AArch64GenContext_t::macro(IMLInstruction* imlInstruction)
{
if (imlInstruction->operation == PPCREC_IML_MACRO_B_TO_REG)
{
XReg branchDstReg = gpReg<XReg>(imlInstruction->op_macro.paramReg);
WReg branchDstReg = gpReg<WReg>(imlInstruction->op_macro.paramReg);
mov(TEMP_GPR1.XReg, offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable));
add(TEMP_GPR1.XReg, TEMP_GPR1.XReg, branchDstReg, ShMod::LSL, 1);
ldr(TEMP_GPR1.XReg, AdrReg(PPC_REC_INSTANCE_REG, TEMP_GPR1.XReg));
mov(LR.XReg, branchDstReg);
mov(TEMP_GPR1.WReg, offsetof(PPCRecompilerInstanceData_t, ppcRecompilerDirectJumpTable));
add(TEMP_GPR1.WReg, TEMP_GPR1.WReg, branchDstReg, ShMod::LSL, 1);
ldr(TEMP_GPR1.XReg, AdrExt(PPC_REC_INSTANCE_REG, TEMP_GPR1.WReg, ExtMod::UXTW));
mov(LR.WReg, branchDstReg);
br(TEMP_GPR1.XReg);
return true;
}
@@ -1391,9 +1417,9 @@ Cond ImlFPCondToArm64Cond(IMLCondition cond)
void AArch64GenContext_t::fpr_compare(IMLInstruction* imlInstruction)
{
auto regR = gpReg<XReg>(imlInstruction->op_fpr_compare.regR);
auto regA = fpReg<DReg>(imlInstruction->op_fpr_compare.regA);
auto regB = fpReg<DReg>(imlInstruction->op_fpr_compare.regB);
WReg regR = gpReg<WReg>(imlInstruction->op_fpr_compare.regR);
DReg regA = fpReg<DReg>(imlInstruction->op_fpr_compare.regA);
DReg regB = fpReg<DReg>(imlInstruction->op_fpr_compare.regB);
auto cond = ImlFPCondToArm64Cond(imlInstruction->op_fpr_compare.cond);
fcmp(regA, regB);
cset(regR, cond);
@@ -1697,10 +1697,10 @@ void VulkanRenderer::Initialize()
void VulkanRenderer::Shutdown()
{
DeleteFontTextures();
Renderer::Shutdown();
SubmitCommandBuffer();
WaitDeviceIdle();
DeleteFontTextures();
Renderer::Shutdown();
if (m_imguiRenderPass != VK_NULL_HANDLE)
{
vkDestroyRenderPass(m_logicalDevice, m_imguiRenderPass, nullptr);