Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/MIPS/JitCommon/JitState.h
3189 views
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
JitBlock *curBlock;
72
73
u8 hasSetRounding = 0;
74
u8 lastSetRounding = 0;
75
const u8 *currentRoundingFunc = nullptr;
76
77
// VFPU prefix magic
78
bool startDefaultPrefix = true;
79
bool blockWrotePrefixes = false;
80
u32 prefixS;
81
u32 prefixT;
82
u32 prefixD;
83
PrefixState prefixSFlag = PREFIX_UNKNOWN;
84
PrefixState prefixTFlag = PREFIX_UNKNOWN;
85
PrefixState prefixDFlag = PREFIX_UNKNOWN;
86
87
void PrefixStart() {
88
if (startDefaultPrefix) {
89
EatPrefix();
90
} else {
91
PrefixUnknown();
92
}
93
}
94
95
void PrefixUnknown() {
96
prefixSFlag = PREFIX_UNKNOWN;
97
prefixTFlag = PREFIX_UNKNOWN;
98
prefixDFlag = PREFIX_UNKNOWN;
99
}
100
101
bool HasSPrefix() const {
102
return (prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4;
103
}
104
105
bool HasTPrefix() const {
106
return (prefixTFlag & PREFIX_KNOWN) == 0 || prefixT != 0xE4;
107
}
108
109
bool HasDPrefix() const {
110
return (prefixDFlag & PREFIX_KNOWN) == 0 || prefixD != 0x0;
111
}
112
113
bool MayHavePrefix() const {
114
if (HasUnknownPrefix()) {
115
return true;
116
} else if (prefixS != 0xE4 || prefixT != 0xE4 || prefixD != 0) {
117
return true;
118
}
119
return false;
120
}
121
122
bool HasUnknownPrefix() const {
123
if (!(prefixSFlag & PREFIX_KNOWN) || !(prefixTFlag & PREFIX_KNOWN) || !(prefixDFlag & PREFIX_KNOWN)) {
124
return true;
125
}
126
return false;
127
}
128
129
bool HasNoPrefix() const {
130
return !HasSPrefix() && !HasTPrefix() && !HasDPrefix();
131
}
132
133
void EatPrefix() {
134
if (HasSPrefix())
135
prefixSFlag = PREFIX_KNOWN_DIRTY;
136
prefixS = 0xE4;
137
if (HasTPrefix())
138
prefixTFlag = PREFIX_KNOWN_DIRTY;
139
prefixT = 0xE4;
140
if (HasDPrefix())
141
prefixDFlag = PREFIX_KNOWN_DIRTY;
142
prefixD = 0x0;
143
}
144
145
u8 VfpuWriteMask() const {
146
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
147
return (prefixD >> 8) & 0xF;
148
}
149
150
bool VfpuWriteMask(int i) const {
151
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
152
return (prefixD >> (8 + i)) & 1;
153
}
154
155
void LogPrefix() {
156
LogSTPrefix("S", prefixS, prefixSFlag);
157
LogSTPrefix("T", prefixT, prefixTFlag);
158
LogDPrefix();
159
}
160
161
private:
162
void LogSTPrefix(const char *name, int p, int pflag) {
163
if ((prefixSFlag & PREFIX_KNOWN) == 0) {
164
ERROR_LOG(Log::JIT, "%s: unknown (%08x %i)", name, p, pflag);
165
} else if (prefixS != 0xE4) {
166
ERROR_LOG(Log::JIT, "%s: %08x flag: %i", name, p, pflag);
167
} else {
168
WARN_LOG(Log::JIT, "%s: %08x flag: %i", name, p, pflag);
169
}
170
}
171
void LogDPrefix() {
172
if ((prefixDFlag & PREFIX_KNOWN) == 0) {
173
ERROR_LOG(Log::JIT, "D: unknown (%08x %i)", prefixD, prefixDFlag);
174
} else if (prefixD != 0) {
175
ERROR_LOG(Log::JIT, "D: (%08x %i)", prefixD, prefixDFlag);
176
} else {
177
WARN_LOG(Log::JIT, "D: %08x flag: %i", prefixD, prefixDFlag);
178
}
179
}
180
};
181
182
enum class JitDisable {
183
ALU = 0x0001,
184
ALU_IMM = 0x0002,
185
ALU_BIT = 0x0004,
186
MULDIV = 0x0008,
187
188
FPU = 0x0010,
189
FPU_COMP = 0x0040,
190
FPU_XFER = 0x0080,
191
192
VFPU_VEC = 0x0100,
193
VFPU_MTX_VTFM = 0x0200,
194
VFPU_COMP = 0x0400,
195
VFPU_XFER = 0x0800,
196
197
LSU = 0x1000,
198
LSU_UNALIGNED = 0x2000,
199
LSU_FPU = 0x4000,
200
LSU_VFPU = 0x8000,
201
202
SIMD = 0x00100000,
203
BLOCKLINK = 0x00200000,
204
POINTERIFY = 0x00400000,
205
STATIC_ALLOC = 0x00800000,
206
CACHE_POINTERS = 0x01000000,
207
REGALLOC_GPR = 0x02000000, // Doesn't really disable regalloc, but flushes after every instr.
208
REGALLOC_FPR = 0x04000000,
209
VFPU_MTX_VMMOV = 0x08000000,
210
VFPU_MTX_VMMUL = 0x10000000,
211
VFPU_MTX_VMSCL = 0x20000000,
212
213
ALL_FLAGS = 0x3FFFFFFF,
214
};
215
216
struct JitOptions {
217
JitOptions();
218
219
bool Disabled(JitDisable bit);
220
221
uint32_t disableFlags;
222
223
// x86
224
bool enableVFPUSIMD;
225
bool reserveR15ForAsm;
226
227
// ARM/ARM64
228
bool useBackJump;
229
bool useForwardJump;
230
bool cachePointers;
231
// ARM only
232
bool useNEONVFPU;
233
bool downcountInRegister;
234
// ARM64 only
235
bool useASIMDVFPU;
236
// ARM64 and RV64
237
bool useStaticAlloc;
238
bool enablePointerify;
239
// IR Interpreter
240
bool optimizeForInterpreter;
241
242
// Common
243
bool enableBlocklink;
244
bool immBranches;
245
bool continueBranches;
246
bool continueJumps;
247
int continueMaxInstructions;
248
};
249
}
250
251