diff --git a/dependencies/xbyak_aarch64 b/dependencies/xbyak_aarch64 index e61bad54..904b8923 160000 --- a/dependencies/xbyak_aarch64 +++ b/dependencies/xbyak_aarch64 @@ -1 +1 @@ -Subproject commit e61bad546f8ecf29b91d993930efe049644976a7 +Subproject commit 904b8923457f3ec0d6f82ea2d6832a792851194d diff --git a/src/Cafe/CMakeLists.txt b/src/Cafe/CMakeLists.txt index 716f5729..94ee793b 100644 --- a/src/Cafe/CMakeLists.txt +++ b/src/Cafe/CMakeLists.txt @@ -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$<$:Debug>") target_include_directories(CemuCafe PUBLIC "../") diff --git a/src/Cafe/HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp b/src/Cafe/HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp index 8125b83e..cb71234d 100644 --- a/src/Cafe/HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/BackendAArch64/BackendAArch64.cpp @@ -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> jumps; void prepareJump(JumpInfo&& jumpInfo) @@ -282,16 +281,41 @@ struct AArch64GenContext_t : CodeGenerator } }; -template +template 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 +template T> T gpReg(const IMLReg& imlReg) { - return T(imlReg.GetRegID() - IMLArchAArch64::PHYSREG_GPR_BASE); + auto regFormat = imlReg.GetRegFormat(); + if (std::is_same_v) + cemu_assert_debug(regFormat == IMLRegFormat::I32); + else if (std::is_same_v) + 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 To, std::derived_from From> +To aliasAs(const From& reg) +{ + return To(reg.getIdx()); +} + +template To, std::derived_from 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(imlInstruction->op_r_name.regR); + XReg regRXReg = gpReg(imlInstruction->op_r_name.regR); + WReg regR = aliasAs(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(imlInstruction->op_r_name.regR); + XReg regRXReg = gpReg(imlInstruction->op_r_name.regR); + WReg regR = aliasAs(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(imlInstruction->op_r_r_r.regR); - XReg reg64Result = gpReg(imlInstruction->op_r_r_r.regR); + XReg reg64Result = aliasAs(regResult); WReg regOperand1 = gpReg(imlInstruction->op_r_r_r.regA); WReg regOperand2 = gpReg(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(imlInstruction->op_macro.paramReg); + WReg branchDstReg = gpReg(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(imlInstruction->op_fpr_compare.regR); - auto regA = fpReg(imlInstruction->op_fpr_compare.regA); - auto regB = fpReg(imlInstruction->op_fpr_compare.regB); + WReg regR = gpReg(imlInstruction->op_fpr_compare.regR); + DReg regA = fpReg(imlInstruction->op_fpr_compare.regA); + DReg regB = fpReg(imlInstruction->op_fpr_compare.regB); auto cond = ImlFPCondToArm64Cond(imlInstruction->op_fpr_compare.cond); fcmp(regA, regB); cset(regR, cond); diff --git a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp index e216fa03..9aee8438 100644 --- a/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp +++ b/src/Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.cpp @@ -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);