Path: blob/master/src/core/cpu_recompiler_riscv64.h
4223 views
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>1// SPDX-License-Identifier: CC-BY-NC-ND-4.023#pragma once45#include "cpu_recompiler.h"67#include <memory>89#ifdef CPU_ARCH_RISCV641011#include "biscuit/assembler.hpp"1213namespace CPU {1415class RISCV64Recompiler final : public Recompiler16{17public:18RISCV64Recompiler();19~RISCV64Recompiler() override;2021protected:22const char* GetHostRegName(u32 reg) const override;2324const void* GetCurrentCodePointer() override;2526void LoadHostRegWithConstant(u32 reg, u32 val) override;27void LoadHostRegFromCPUPointer(u32 reg, const void* ptr) override;28void StoreConstantToCPUPointer(u32 val, const void* ptr) override;29void StoreHostRegToCPUPointer(u32 reg, const void* ptr) override;30void CopyHostReg(u32 dst, u32 src) override;3132void Reset(CodeCache::Block* block, u8* code_buffer, u32 code_buffer_space, u8* far_code_buffer,33u32 far_code_space) override;34void GenerateBlockProtectCheck(const u8* ram_ptr, const u8* shadow_ptr, u32 size) override;35void GenerateICacheCheckAndUpdate() override;36void GenerateCall(const void* func, s32 arg1reg = -1, s32 arg2reg = -1, s32 arg3reg = -1) override;37void EndBlock(const std::optional<u32>& newpc, bool do_event_test) override;38void EndBlockWithException(Exception excode) override;39void EndAndLinkBlock(const std::optional<u32>& newpc, bool do_event_test, bool force_run_events);40const void* EndCompile(u32* code_size, u32* far_code_size) override;4142void Flush(u32 flags) override;4344void Compile_Fallback() override;4546void CheckBranchTarget(const biscuit::GPR& pcreg);47void Compile_jr(CompileFlags cf) override;48void Compile_jalr(CompileFlags cf) override;49void Compile_bxx(CompileFlags cf, BranchCondition cond) override;5051void Compile_addi(CompileFlags cf, bool overflow);52void Compile_addi(CompileFlags cf) override;53void Compile_addiu(CompileFlags cf) override;54void Compile_slti(CompileFlags cf, bool sign);55void Compile_slti(CompileFlags cf) override;56void Compile_sltiu(CompileFlags cf) override;57void Compile_andi(CompileFlags cf) override;58void Compile_ori(CompileFlags cf) override;59void Compile_xori(CompileFlags cf) override;6061void Compile_shift(CompileFlags cf, void (biscuit::Assembler::*op)(biscuit::GPR, biscuit::GPR, biscuit::GPR),62void (biscuit::Assembler::*op_const)(biscuit::GPR, biscuit::GPR, unsigned));63void Compile_sll(CompileFlags cf) override;64void Compile_srl(CompileFlags cf) override;65void Compile_sra(CompileFlags cf) override;66void Compile_variable_shift(CompileFlags cf, void (biscuit::Assembler::*op)(biscuit::GPR, biscuit::GPR, biscuit::GPR),67void (biscuit::Assembler::*op_const)(biscuit::GPR, biscuit::GPR, unsigned));68void Compile_sllv(CompileFlags cf) override;69void Compile_srlv(CompileFlags cf) override;70void Compile_srav(CompileFlags cf) override;71void Compile_mult(CompileFlags cf, bool sign);72void Compile_mult(CompileFlags cf) override;73void Compile_multu(CompileFlags cf) override;74void Compile_div(CompileFlags cf) override;75void Compile_divu(CompileFlags cf) override;76void TestOverflow(const biscuit::GPR& long_res, const biscuit::GPR& res, const biscuit::GPR& reg_to_discard);77void Compile_dst_op(CompileFlags cf, void (biscuit::Assembler::*op)(biscuit::GPR, biscuit::GPR, biscuit::GPR),78void (RISCV64Recompiler::*op_const)(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm),79void (biscuit::Assembler::*op_long)(biscuit::GPR, biscuit::GPR, biscuit::GPR), bool commutative,80bool overflow);81void Compile_add(CompileFlags cf) override;82void Compile_addu(CompileFlags cf) override;83void Compile_sub(CompileFlags cf) override;84void Compile_subu(CompileFlags cf) override;85void Compile_and(CompileFlags cf) override;86void Compile_or(CompileFlags cf) override;87void Compile_xor(CompileFlags cf) override;88void Compile_nor(CompileFlags cf) override;89void Compile_slt(CompileFlags cf, bool sign);90void Compile_slt(CompileFlags cf) override;91void Compile_sltu(CompileFlags cf) override;9293biscuit::GPR ComputeLoadStoreAddressArg(CompileFlags cf, const std::optional<VirtualMemoryAddress>& address,94const std::optional<const biscuit::GPR>& reg = std::nullopt);95template<typename RegAllocFn>96biscuit::GPR GenerateLoad(const biscuit::GPR& addr_reg, MemoryAccessSize size, bool sign, bool use_fastmem,97const RegAllocFn& dst_reg_alloc);98void GenerateStore(const biscuit::GPR& addr_reg, const biscuit::GPR& value_reg, MemoryAccessSize size,99bool use_fastmem);100void Compile_lxx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,101const std::optional<VirtualMemoryAddress>& address) override;102void Compile_lwx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,103const std::optional<VirtualMemoryAddress>& address) override;104void Compile_lwc2(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,105const std::optional<VirtualMemoryAddress>& address) override;106void Compile_sxx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,107const std::optional<VirtualMemoryAddress>& address) override;108void Compile_swx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,109const std::optional<VirtualMemoryAddress>& address) override;110void Compile_swc2(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,111const std::optional<VirtualMemoryAddress>& address) override;112113void TestInterrupts(const biscuit::GPR& sr);114void Compile_mtc0(CompileFlags cf) override;115void Compile_rfe(CompileFlags cf) override;116117void Compile_mfc2(CompileFlags cf) override;118void Compile_mtc2(CompileFlags cf) override;119void Compile_cop2(CompileFlags cf) override;120121void GeneratePGXPCallWithMIPSRegs(const void* func, u32 arg1val, Reg arg2reg = Reg::count,122Reg arg3reg = Reg::count) override;123124private:125void EmitMov(const biscuit::GPR& dst, u32 val);126void EmitCall(const void* ptr);127128void SwitchToFarCode(bool emit_jump,129void (biscuit::Assembler::*inverted_cond)(biscuit::GPR, biscuit::GPR, biscuit::Label*) = nullptr,130const biscuit::GPR& rs1 = biscuit::zero, const biscuit::GPR& rs2 = biscuit::zero);131void SwitchToNearCode(bool emit_jump);132133void AssertRegOrConstS(CompileFlags cf) const;134void AssertRegOrConstT(CompileFlags cf) const;135// vixl::aarch64::MemOperand MipsPtr(Reg r) const;136137void SafeImmSExtIType(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm,138void (biscuit::Assembler::*iop)(biscuit::GPR, biscuit::GPR, u32),139void (biscuit::Assembler::*rop)(biscuit::GPR, biscuit::GPR, biscuit::GPR));140141void SafeADDI(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);142void SafeADDIW(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);143void SafeSUBIW(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);144void SafeANDI(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);145void SafeORI(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);146void SafeXORI(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);147void SafeSLTI(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);148void SafeSLTIU(const biscuit::GPR& rd, const biscuit::GPR& rs, u32 imm);149150void EmitSExtB(const biscuit::GPR& rd, const biscuit::GPR& rs);151void EmitUExtB(const biscuit::GPR& rd, const biscuit::GPR& rs);152void EmitSExtH(const biscuit::GPR& rd, const biscuit::GPR& rs);153void EmitUExtH(const biscuit::GPR& rd, const biscuit::GPR& rs);154void EmitDSExtW(const biscuit::GPR& rd, const biscuit::GPR& rs);155void EmitDUExtW(const biscuit::GPR& rd, const biscuit::GPR& rs);156157biscuit::GPR CFGetSafeRegS(CompileFlags cf, const biscuit::GPR& temp_reg);158biscuit::GPR CFGetSafeRegT(CompileFlags cf, const biscuit::GPR& temp_reg);159160biscuit::GPR CFGetRegD(CompileFlags cf) const;161biscuit::GPR CFGetRegS(CompileFlags cf) const;162biscuit::GPR CFGetRegT(CompileFlags cf) const;163biscuit::GPR CFGetRegLO(CompileFlags cf) const;164biscuit::GPR CFGetRegHI(CompileFlags cf) const;165166void MoveSToReg(const biscuit::GPR& dst, CompileFlags cf);167void MoveTToReg(const biscuit::GPR& dst, CompileFlags cf);168void MoveMIPSRegToReg(const biscuit::GPR& dst, Reg reg);169170std::unique_ptr<biscuit::Assembler> m_emitter;171std::unique_ptr<biscuit::Assembler> m_far_emitter;172biscuit::Assembler* rvAsm;173};174175} // namespace CPU176177#endif // CPU_ARCH_RISCV64178179180