Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/src/core/cpu_recompiler_x64.h
4223 views
1
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <[email protected]>
2
// SPDX-License-Identifier: CC-BY-NC-ND-4.0
3
4
#pragma once
5
6
#include "cpu_recompiler.h"
7
8
#include <memory>
9
10
#ifdef CPU_ARCH_X64
11
12
// We need to include windows.h before xbyak does..
13
#ifdef _WIN32
14
#include "common/windows_headers.h"
15
#endif
16
17
#define XBYAK_NO_OP_NAMES 1
18
#include "xbyak.h"
19
20
namespace CPU {
21
22
class X64Recompiler final : public Recompiler
23
{
24
public:
25
X64Recompiler();
26
~X64Recompiler() override;
27
28
protected:
29
const char* GetHostRegName(u32 reg) const override;
30
31
const void* GetCurrentCodePointer() override;
32
33
void LoadHostRegWithConstant(u32 reg, u32 val) override;
34
void LoadHostRegFromCPUPointer(u32 reg, const void* ptr) override;
35
void StoreConstantToCPUPointer(u32 val, const void* ptr) override;
36
void StoreHostRegToCPUPointer(u32 reg, const void* ptr) override;
37
void CopyHostReg(u32 dst, u32 src) override;
38
39
void Reset(CodeCache::Block* block, u8* code_buffer, u32 code_buffer_space, u8* far_code_buffer,
40
u32 far_code_space) override;
41
void BeginBlock() override;
42
void GenerateBlockProtectCheck(const u8* ram_ptr, const u8* shadow_ptr, u32 size) override;
43
void GenerateICacheCheckAndUpdate() override;
44
void GenerateCall(const void* func, s32 arg1reg = -1, s32 arg2reg = -1, s32 arg3reg = -1) override;
45
void EndBlock(const std::optional<u32>& newpc, bool do_event_test) override;
46
void EndBlockWithException(Exception excode) override;
47
void EndAndLinkBlock(const std::optional<u32>& newpc, bool do_event_test, bool force_run_events);
48
const void* EndCompile(u32* code_size, u32* far_code_size) override;
49
50
void Flush(u32 flags) override;
51
52
void Compile_Fallback() override;
53
54
void CheckBranchTarget(const Xbyak::Reg32& pcreg);
55
void Compile_jr(CompileFlags cf) override;
56
void Compile_jalr(CompileFlags cf) override;
57
void Compile_bxx(CompileFlags cf, BranchCondition cond) override;
58
59
void Compile_addi(CompileFlags cf) override;
60
void Compile_addiu(CompileFlags cf) override;
61
void Compile_slti(CompileFlags cf, bool sign);
62
void Compile_slti(CompileFlags cf) override;
63
void Compile_sltiu(CompileFlags cf) override;
64
void Compile_andi(CompileFlags cf) override;
65
void Compile_ori(CompileFlags cf) override;
66
void Compile_xori(CompileFlags cf) override;
67
68
void Compile_sll(CompileFlags cf) override;
69
void Compile_srl(CompileFlags cf) override;
70
void Compile_sra(CompileFlags cf) override;
71
void Compile_variable_shift(CompileFlags cf,
72
void (Xbyak::CodeGenerator::*op)(const Xbyak::Operand&, const Xbyak::Reg8&),
73
void (Xbyak::CodeGenerator::*op_const)(const Xbyak::Operand&, int));
74
void Compile_sllv(CompileFlags cf) override;
75
void Compile_srlv(CompileFlags cf) override;
76
void Compile_srav(CompileFlags cf) override;
77
void Compile_mult(CompileFlags cf, bool sign);
78
void Compile_mult(CompileFlags cf) override;
79
void Compile_multu(CompileFlags cf) override;
80
void Compile_div(CompileFlags cf) override;
81
void Compile_divu(CompileFlags cf) override;
82
void TestOverflow(const Xbyak::Reg32& result);
83
void Compile_dst_op(CompileFlags cf, void (Xbyak::CodeGenerator::*op)(const Xbyak::Operand&, const Xbyak::Operand&),
84
void (Xbyak::CodeGenerator::*op_const)(const Xbyak::Operand&, u32), bool commutative,
85
bool overflow);
86
void Compile_add(CompileFlags cf) override;
87
void Compile_addu(CompileFlags cf) override;
88
void Compile_sub(CompileFlags cf) override;
89
void Compile_subu(CompileFlags cf) override;
90
void Compile_and(CompileFlags cf) override;
91
void Compile_or(CompileFlags cf) override;
92
void Compile_xor(CompileFlags cf) override;
93
void Compile_nor(CompileFlags cf) override;
94
void Compile_slt(CompileFlags cf, bool sign);
95
void Compile_slt(CompileFlags cf) override;
96
void Compile_sltu(CompileFlags cf) override;
97
98
Xbyak::Reg32 ComputeLoadStoreAddressArg(CompileFlags cf, const std::optional<VirtualMemoryAddress>& address,
99
const std::optional<const Xbyak::Reg32>& reg = std::nullopt);
100
template<typename RegAllocFn>
101
Xbyak::Reg32 GenerateLoad(const Xbyak::Reg32& addr_reg, MemoryAccessSize size, bool sign, bool use_fastmem,
102
const RegAllocFn& dst_reg_alloc);
103
void GenerateStore(const Xbyak::Reg32& addr_reg, const Xbyak::Reg32& value_reg, MemoryAccessSize size,
104
bool use_fastmem);
105
void Compile_lxx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,
106
const std::optional<VirtualMemoryAddress>& address) override;
107
void Compile_lwx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,
108
const std::optional<VirtualMemoryAddress>& address) override;
109
void Compile_lwc2(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,
110
const std::optional<VirtualMemoryAddress>& address) override;
111
void Compile_sxx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,
112
const std::optional<VirtualMemoryAddress>& address) override;
113
void Compile_swx(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,
114
const std::optional<VirtualMemoryAddress>& address) override;
115
void Compile_swc2(CompileFlags cf, MemoryAccessSize size, bool sign, bool use_fastmem,
116
const std::optional<VirtualMemoryAddress>& address) override;
117
118
void TestInterrupts(const Xbyak::Reg32& sr);
119
void Compile_mtc0(CompileFlags cf) override;
120
void Compile_rfe(CompileFlags cf) override;
121
122
void Compile_mfc2(CompileFlags cf) override;
123
void Compile_mtc2(CompileFlags cf) override;
124
void Compile_cop2(CompileFlags cf) override;
125
126
void GeneratePGXPCallWithMIPSRegs(const void* func, u32 arg1val, Reg arg2reg = Reg::count,
127
Reg arg3reg = Reg::count) override;
128
129
private:
130
void SwitchToFarCode(bool emit_jump, void (Xbyak::CodeGenerator::*jump_op)(const void*) = nullptr);
131
void SwitchToNearCode(bool emit_jump, void (Xbyak::CodeGenerator::*jump_op)(const void*) = nullptr);
132
133
Xbyak::Address MipsPtr(Reg r) const;
134
Xbyak::Reg32 CFGetRegD(CompileFlags cf) const;
135
Xbyak::Reg32 CFGetRegS(CompileFlags cf) const;
136
Xbyak::Reg32 CFGetRegT(CompileFlags cf) const;
137
Xbyak::Reg32 CFGetRegLO(CompileFlags cf) const;
138
Xbyak::Reg32 CFGetRegHI(CompileFlags cf) const;
139
140
Xbyak::Reg32 MoveSToD(CompileFlags cf);
141
Xbyak::Reg32 MoveSToT(CompileFlags cf);
142
Xbyak::Reg32 MoveTToD(CompileFlags cf);
143
void MoveSToReg(const Xbyak::Reg32& dst, CompileFlags cf);
144
void MoveTToReg(const Xbyak::Reg32& dst, CompileFlags cf);
145
void MoveMIPSRegToReg(const Xbyak::Reg32& dst, Reg reg);
146
147
std::unique_ptr<Xbyak::CodeGenerator> m_emitter;
148
std::unique_ptr<Xbyak::CodeGenerator> m_far_emitter;
149
Xbyak::CodeGenerator* cg;
150
};
151
152
} // namespace CPU
153
154
#endif // CPU_ARCH_X64
155
156