Path: blob/master/src/core/cpu_recompiler_loongarch64.h
10595 views
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]> and contributors.1// SPDX-License-Identifier: CC-BY-NC-ND-4.023#pragma once45#include "cpu_recompiler.h"67#ifdef CPU_ARCH_LOONGARCH6489extern "C" {10#include "lagoon.h"11}1213namespace CPU {1415// Function pointer types for lagoon operations16using LaRRROp = void (*)(lagoon_assembler_t*, la_gpr_t, la_gpr_t, la_gpr_t);17using LaRROp = void (*)(lagoon_assembler_t*, la_gpr_t, la_gpr_t);18using LaRRSImmOp = void (*)(lagoon_assembler_t*, la_gpr_t, la_gpr_t, int32_t);19using LaRRUImmOp = void (*)(lagoon_assembler_t*, la_gpr_t, la_gpr_t, uint32_t);2021// Branch condition enum for SwitchToFarCode22enum class LaBranchCondition23{24None,25EQ,26NE,27LT,28GE,29LTU,30GEU31};3233class LoongArch64Recompiler final : public Recompiler34{35public:36LoongArch64Recompiler();37~LoongArch64Recompiler() override;3839protected:40const char* GetHostRegName(u32 reg) const override;4142const void* GetCurrentCodePointer() override;4344void LoadHostRegWithConstant(u32 reg, u32 val) override;45void LoadHostRegFromCPUPointer(u32 reg, const void* ptr) override;46void StoreConstantToCPUPointer(u32 val, const void* ptr) override;47void StoreHostRegToCPUPointer(u32 reg, const void* ptr) override;48void CopyHostReg(u32 dst, u32 src) override;4950void Reset(CodeCache::Block* block, u8* code_buffer, u32 code_buffer_space, u8* far_code_buffer,51u32 far_code_space) override;52void GenerateBlockProtectCheck(const u8* ram_ptr, const u8* shadow_ptr, u32 size) override;53void GenerateICacheCheckAndUpdate() override;54void GenerateCall(const void* func, s32 arg1reg = -1, s32 arg2reg = -1, s32 arg3reg = -1) override;55void EndBlock(const std::optional<u32>& newpc, bool do_event_test) override;56void EndBlockWithException(Exception excode) override;57void EndAndLinkBlock(const std::optional<u32>& newpc, bool do_event_test, bool force_run_events);58const void* EndCompile(u32* code_size, u32* far_code_size) override;5960void Flush(u32 flags) override;6162void Compile_Fallback() override;6364void CheckBranchTarget(la_gpr_t pcreg);65void Compile_jr(CompileFlags cf) override;66void Compile_jalr(CompileFlags cf) override;67void Compile_bxx(CompileFlags cf, BranchCondition cond) override;6869void Compile_addi(CompileFlags cf, bool overflow);70void Compile_addi(CompileFlags cf) override;71void Compile_addiu(CompileFlags cf) override;72void Compile_slti(CompileFlags cf, bool sign);73void Compile_slti(CompileFlags cf) override;74void Compile_sltiu(CompileFlags cf) override;75void Compile_andi(CompileFlags cf) override;76void Compile_ori(CompileFlags cf) override;77void Compile_xori(CompileFlags cf) override;7879void Compile_shift(CompileFlags cf, LaRRROp op, LaRRUImmOp op_const);80void Compile_sll(CompileFlags cf) override;81void Compile_srl(CompileFlags cf) override;82void Compile_sra(CompileFlags cf) override;83void Compile_variable_shift(CompileFlags cf, LaRRROp op, LaRRUImmOp op_const);84void Compile_sllv(CompileFlags cf) override;85void Compile_srlv(CompileFlags cf) override;86void Compile_srav(CompileFlags cf) override;87void Compile_mult(CompileFlags cf, bool sign);88void Compile_mult(CompileFlags cf) override;89void Compile_multu(CompileFlags cf) override;90void Compile_div(CompileFlags cf) override;91void Compile_divu(CompileFlags cf) override;92void TestOverflow(la_gpr_t long_res, la_gpr_t res, la_gpr_t reg_to_discard);93void Compile_dst_op(CompileFlags cf, LaRRROp op,94void (LoongArch64Recompiler::*op_const)(la_gpr_t rd, la_gpr_t rs, u32 imm), LaRRROp op_long,95bool commutative, bool overflow);96void Compile_add(CompileFlags cf) override;97void Compile_addu(CompileFlags cf) override;98void Compile_sub(CompileFlags cf) override;99void Compile_subu(CompileFlags cf) override;100void Compile_and(CompileFlags cf) override;101void Compile_or(CompileFlags cf) override;102void Compile_xor(CompileFlags cf) override;103void Compile_nor(CompileFlags cf) override;104void Compile_slt(CompileFlags cf, bool sign);105void Compile_slt(CompileFlags cf) override;106void Compile_sltu(CompileFlags cf) override;107108la_gpr_t ComputeLoadStoreAddressArg(CompileFlags cf, const std::optional<VirtualMemoryAddress>& address,109const std::optional<la_gpr_t>& reg = std::nullopt);110template<typename RegAllocFn>111la_gpr_t GenerateLoad(la_gpr_t addr_reg, MemoryAccessSize size, bool sign, bool use_fastmem,112const RegAllocFn& dst_reg_alloc);113void GenerateStore(la_gpr_t addr_reg, la_gpr_t value_reg, MemoryAccessSize size, bool use_fastmem);114void Compile_lxx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,115const std::optional<VirtualMemoryAddress>& address) override;116void Compile_lwx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,117const std::optional<VirtualMemoryAddress>& address) override;118void Compile_lwc2(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,119const std::optional<VirtualMemoryAddress>& address) override;120void Compile_sxx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,121const std::optional<VirtualMemoryAddress>& address) override;122void Compile_swx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,123const std::optional<VirtualMemoryAddress>& address) override;124void Compile_swc2(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,125const std::optional<VirtualMemoryAddress>& address) override;126127void TestInterrupts(la_gpr_t sr);128void Compile_mtc0(CompileFlags cf) override;129void Compile_rfe(CompileFlags cf) override;130131void Compile_mfc2(CompileFlags cf) override;132void Compile_mtc2(CompileFlags cf) override;133void Compile_cop2(CompileFlags cf) override;134135void GeneratePGXPCallWithMIPSRegs(const void* func, u32 arg1val, Reg arg2reg = Reg::count,136Reg arg3reg = Reg::count) override;137138private:139void EmitMov(la_gpr_t dst, u32 val);140void EmitCall(const void* ptr);141142void SwitchToFarCode(bool emit_jump, LaBranchCondition cond = LaBranchCondition::None, la_gpr_t rs1 = LA_ZERO,143la_gpr_t rs2 = LA_ZERO);144void SwitchToNearCode(bool emit_jump);145146void AssertRegOrConstS(CompileFlags cf) const;147void AssertRegOrConstT(CompileFlags cf) const;148149void SafeImmSImm12(la_gpr_t rd, la_gpr_t rs, u32 imm, LaRRSImmOp iop, LaRRROp rop);150void SafeImmUImm12(la_gpr_t rd, la_gpr_t rs, u32 imm, LaRRUImmOp iop, LaRRROp rop);151152void SafeADDI(la_gpr_t rd, la_gpr_t rs, u32 imm);153void SafeADDIW(la_gpr_t rd, la_gpr_t rs, u32 imm);154void SafeSUBIW(la_gpr_t rd, la_gpr_t rs, u32 imm);155void SafeANDI(la_gpr_t rd, la_gpr_t rs, u32 imm);156void SafeORI(la_gpr_t rd, la_gpr_t rs, u32 imm);157void SafeXORI(la_gpr_t rd, la_gpr_t rs, u32 imm);158void SafeSLTI(la_gpr_t rd, la_gpr_t rs, u32 imm);159void SafeSLTIU(la_gpr_t rd, la_gpr_t rs, u32 imm);160161void EmitSExtB(la_gpr_t rd, la_gpr_t rs);162void EmitUExtB(la_gpr_t rd, la_gpr_t rs);163void EmitSExtH(la_gpr_t rd, la_gpr_t rs);164void EmitUExtH(la_gpr_t rd, la_gpr_t rs);165void EmitDSExtW(la_gpr_t rd, la_gpr_t rs);166void EmitDUExtW(la_gpr_t rd, la_gpr_t rs);167168la_gpr_t CFGetSafeRegS(CompileFlags cf, la_gpr_t temp_reg);169la_gpr_t CFGetSafeRegT(CompileFlags cf, la_gpr_t temp_reg);170171la_gpr_t CFGetRegD(CompileFlags cf) const;172la_gpr_t CFGetRegS(CompileFlags cf) const;173la_gpr_t CFGetRegT(CompileFlags cf) const;174la_gpr_t CFGetRegLO(CompileFlags cf) const;175la_gpr_t CFGetRegHI(CompileFlags cf) const;176177void MoveSToReg(la_gpr_t dst, CompileFlags cf);178void MoveTToReg(la_gpr_t dst, CompileFlags cf);179void MoveMIPSRegToReg(la_gpr_t dst, Reg reg, bool ignore_load_delays = false);180181lagoon_assembler_t m_emitter;182lagoon_assembler_t m_far_emitter;183lagoon_assembler_t* laAsm;184};185186} // namespace CPU187188#endif // CPU_ARCH_LOONGARCH64189190