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/JitCommon/JitState.h
Views: 1401
1
// Copyright (c) 2013- 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
19
#pragma once
20
21
#include "Common/CommonTypes.h"
22
#include "Common/Log.h"
23
#include "Core/MIPS/MIPS.h"
24
25
struct JitBlock;
26
class JitBlockCache;
27
28
namespace MIPSComp {
29
30
enum CompileDelaySlotFlags
31
{
32
// Easy, nothing extra.
33
DELAYSLOT_NICE = 0,
34
// Flush registers after delay slot.
35
DELAYSLOT_FLUSH = 1,
36
// Preserve flags.
37
DELAYSLOT_SAFE = 2,
38
// Flush registers after and preserve flags.
39
DELAYSLOT_SAFE_FLUSH = DELAYSLOT_FLUSH | DELAYSLOT_SAFE,
40
};
41
42
struct JitState
43
{
44
enum PrefixState
45
{
46
PREFIX_UNKNOWN = 0x00,
47
PREFIX_KNOWN = 0x01,
48
PREFIX_DIRTY = 0x10,
49
PREFIX_KNOWN_DIRTY = 0x11,
50
};
51
52
enum AfterOp
53
{
54
AFTER_NONE = 0x00,
55
AFTER_CORE_STATE = 0x01,
56
};
57
58
u32 compilerPC;
59
u32 blockStart;
60
u32 lastContinuedPC;
61
u32 initialBlockSize;
62
int nextExit;
63
bool cancel;
64
bool inDelaySlot;
65
// See JitState::AfterOp for values.
66
int afterOp;
67
int downcountAmount;
68
int numInstructions;
69
bool compiling; // TODO: get rid of this in favor of using analysis results to determine end of block
70
bool hadBreakpoints;
71
bool preloading = false;
72
JitBlock *curBlock;
73
74
u8 hasSetRounding = 0;
75
u8 lastSetRounding = 0;
76
const u8 *currentRoundingFunc = nullptr;
77
78
// VFPU prefix magic
79
bool startDefaultPrefix = true;
80
bool blockWrotePrefixes = false;
81
u32 prefixS;
82
u32 prefixT;
83
u32 prefixD;
84
PrefixState prefixSFlag = PREFIX_UNKNOWN;
85
PrefixState prefixTFlag = PREFIX_UNKNOWN;
86
PrefixState prefixDFlag = PREFIX_UNKNOWN;
87
88
void PrefixStart() {
89
if (startDefaultPrefix) {
90
EatPrefix();
91
} else {
92
PrefixUnknown();
93
}
94
}
95
96
void PrefixUnknown() {
97
prefixSFlag = PREFIX_UNKNOWN;
98
prefixTFlag = PREFIX_UNKNOWN;
99
prefixDFlag = PREFIX_UNKNOWN;
100
}
101
102
bool HasSPrefix() const {
103
return (prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4;
104
}
105
106
bool HasTPrefix() const {
107
return (prefixTFlag & PREFIX_KNOWN) == 0 || prefixT != 0xE4;
108
}
109
110
bool HasDPrefix() const {
111
return (prefixDFlag & PREFIX_KNOWN) == 0 || prefixD != 0x0;
112
}
113
114
bool MayHavePrefix() const {
115
if (HasUnknownPrefix()) {
116
return true;
117
} else if (prefixS != 0xE4 || prefixT != 0xE4 || prefixD != 0) {
118
return true;
119
}
120
return false;
121
}
122
123
bool HasUnknownPrefix() const {
124
if (!(prefixSFlag & PREFIX_KNOWN) || !(prefixTFlag & PREFIX_KNOWN) || !(prefixDFlag & PREFIX_KNOWN)) {
125
return true;
126
}
127
return false;
128
}
129
130
bool HasNoPrefix() const {
131
return !HasSPrefix() && !HasTPrefix() && !HasDPrefix();
132
}
133
134
void EatPrefix() {
135
if (HasSPrefix())
136
prefixSFlag = PREFIX_KNOWN_DIRTY;
137
prefixS = 0xE4;
138
if (HasTPrefix())
139
prefixTFlag = PREFIX_KNOWN_DIRTY;
140
prefixT = 0xE4;
141
if (HasDPrefix())
142
prefixDFlag = PREFIX_KNOWN_DIRTY;
143
prefixD = 0x0;
144
}
145
146
u8 VfpuWriteMask() const {
147
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
148
return (prefixD >> 8) & 0xF;
149
}
150
151
bool VfpuWriteMask(int i) const {
152
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
153
return (prefixD >> (8 + i)) & 1;
154
}
155
156
void LogPrefix() {
157
LogSTPrefix("S", prefixS, prefixSFlag);
158
LogSTPrefix("T", prefixT, prefixTFlag);
159
LogDPrefix();
160
}
161
162
private:
163
void LogSTPrefix(const char *name, int p, int pflag) {
164
if ((prefixSFlag & PREFIX_KNOWN) == 0) {
165
ERROR_LOG(Log::JIT, "%s: unknown (%08x %i)", name, p, pflag);
166
} else if (prefixS != 0xE4) {
167
ERROR_LOG(Log::JIT, "%s: %08x flag: %i", name, p, pflag);
168
} else {
169
WARN_LOG(Log::JIT, "%s: %08x flag: %i", name, p, pflag);
170
}
171
}
172
void LogDPrefix() {
173
if ((prefixDFlag & PREFIX_KNOWN) == 0) {
174
ERROR_LOG(Log::JIT, "D: unknown (%08x %i)", prefixD, prefixDFlag);
175
} else if (prefixD != 0) {
176
ERROR_LOG(Log::JIT, "D: (%08x %i)", prefixD, prefixDFlag);
177
} else {
178
WARN_LOG(Log::JIT, "D: %08x flag: %i", prefixD, prefixDFlag);
179
}
180
}
181
};
182
183
enum class JitDisable {
184
ALU = 0x0001,
185
ALU_IMM = 0x0002,
186
ALU_BIT = 0x0004,
187
MULDIV = 0x0008,
188
189
FPU = 0x0010,
190
FPU_COMP = 0x0040,
191
FPU_XFER = 0x0080,
192
193
VFPU_VEC = 0x0100,
194
VFPU_MTX_VTFM = 0x0200,
195
VFPU_COMP = 0x0400,
196
VFPU_XFER = 0x0800,
197
198
LSU = 0x1000,
199
LSU_UNALIGNED = 0x2000,
200
LSU_FPU = 0x4000,
201
LSU_VFPU = 0x8000,
202
203
SIMD = 0x00100000,
204
BLOCKLINK = 0x00200000,
205
POINTERIFY = 0x00400000,
206
STATIC_ALLOC = 0x00800000,
207
CACHE_POINTERS = 0x01000000,
208
REGALLOC_GPR = 0x02000000, // Doesn't really disable regalloc, but flushes after every instr.
209
REGALLOC_FPR = 0x04000000,
210
VFPU_MTX_VMMOV = 0x08000000,
211
VFPU_MTX_VMMUL = 0x10000000,
212
VFPU_MTX_VMSCL = 0x20000000,
213
214
ALL_FLAGS = 0x3FFFFFFF,
215
};
216
217
struct JitOptions {
218
JitOptions();
219
220
bool Disabled(JitDisable bit);
221
222
uint32_t disableFlags;
223
224
// x86
225
bool enableVFPUSIMD;
226
bool reserveR15ForAsm;
227
228
// ARM/ARM64
229
bool useBackJump;
230
bool useForwardJump;
231
bool cachePointers;
232
// ARM only
233
bool useNEONVFPU;
234
bool downcountInRegister;
235
// ARM64 only
236
bool useASIMDVFPU;
237
// ARM64 and RV64
238
bool useStaticAlloc;
239
bool enablePointerify;
240
// IR Interpreter
241
bool optimizeForInterpreter;
242
243
// Common
244
bool enableBlocklink;
245
bool immBranches;
246
bool continueBranches;
247
bool continueJumps;
248
int continueMaxInstructions;
249
};
250
}
251
252