CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/MIPS/x86/JitSafeMem.h
Views: 1401
1
// Copyright (c) 2012- PPSSPP Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17
18
#pragma once
19
20
#include <vector>
21
22
class ThunkManager;
23
24
namespace MIPSComp {
25
26
class Jit;
27
28
class JitSafeMem {
29
public:
30
JitSafeMem(Jit *jit, MIPSGPReg raddr, s32 offset, u32 alignMask = 0xFFFFFFFF);
31
32
// Emit code necessary for a memory write, returns true if MOV to dest is needed.
33
bool PrepareWrite(Gen::OpArg &dest, int size);
34
// Emit code proceeding a slow write call, returns true if slow write is needed.
35
bool PrepareSlowWrite();
36
// Emit a slow write from src.
37
void DoSlowWrite(const void *safeFunc, const Gen::OpArg& src, int suboffset = 0);
38
template <typename T>
39
void DoSlowWrite(void (*safeFunc)(T val, u32 addr), const Gen::OpArg& src, int suboffset = 0) {
40
DoSlowWrite((const void *)safeFunc, src, suboffset);
41
}
42
43
// Emit code necessary for a memory read, returns true if MOV from src is needed.
44
bool PrepareRead(Gen::OpArg &src, int size);
45
// Emit code for a slow read call, and returns true if result is in EAX.
46
bool PrepareSlowRead(const void *safeFunc);
47
template <typename T>
48
bool PrepareSlowRead(T (*safeFunc)(u32 addr)) {
49
return PrepareSlowRead((const void *)safeFunc);
50
}
51
52
// Cleans up final code for the memory access.
53
void Finish();
54
55
// WARNING: Only works for non-GPR. Do not use for reads into GPR.
56
Gen::OpArg NextFastAddress(int suboffset);
57
// WARNING: Only works for non-GPR. Do not use for reads into GPR.
58
void NextSlowRead(const void *safeFunc, int suboffset);
59
template <typename T>
60
void NextSlowRead(T (*safeFunc)(u32 addr), int suboffset) {
61
NextSlowRead((const void *)safeFunc, suboffset);
62
}
63
64
private:
65
enum MemoryOpType {
66
MEM_READ,
67
MEM_WRITE,
68
};
69
70
Gen::OpArg PrepareMemoryOpArg(MemoryOpType type);
71
void PrepareSlowAccess();
72
bool ImmValid();
73
void IndirectCALL(const void *safeFunc);
74
75
Jit *jit_;
76
MIPSGPReg raddr_;
77
s32 offset_;
78
int size_;
79
bool needsCheck_;
80
bool needsSkip_;
81
bool fast_;
82
u32 alignMask_;
83
u32 iaddr_;
84
Gen::X64Reg xaddr_;
85
Gen::FixupBranch tooLow_, tooHigh_, skip_;
86
std::vector<Gen::FixupBranch> skipChecks_;
87
const u8 *safe_;
88
};
89
90
// Kept separate to avoid mistakes in the above class not using jit_.
91
class JitSafeMemFuncs : public Gen::XCodeBlock
92
{
93
public:
94
JitSafeMemFuncs() {
95
}
96
~JitSafeMemFuncs() {
97
Shutdown();
98
}
99
100
void Init(ThunkManager *thunks);
101
void Shutdown();
102
103
const u8 *readU32;
104
const u8 *readU16;
105
const u8 *readU8;
106
const u8 *writeU32;
107
const u8 *writeU16;
108
const u8 *writeU8;
109
110
private:
111
void CreateReadFunc(int bits, const void *fallbackFunc);
112
void CreateWriteFunc(int bits, const void *fallbackFunc);
113
114
void CheckDirectEAX();
115
void StartDirectAccess();
116
117
std::vector<Gen::FixupBranch> skips_;
118
ThunkManager *thunks_;
119
};
120
121
};
122
123