Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/MIPS/JitCommon/JitState.h
5923 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/Common.h"
22
#include "Common/CommonTypes.h"
23
#include "Common/Log.h"
24
#include "Core/MIPS/MIPS.h"
25
26
struct JitBlock;
27
class JitBlockCache;
28
29
namespace MIPSComp {
30
31
enum CompileDelaySlotFlags {
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
enum PrefixState {
44
PREFIX_UNKNOWN = 0x00,
45
PREFIX_KNOWN = 0x01,
46
PREFIX_DIRTY = 0x10,
47
PREFIX_KNOWN_DIRTY = 0x11,
48
};
49
50
enum AfterOp {
51
AFTER_NONE = 0x00,
52
AFTER_CORE_STATE = 0x01,
53
};
54
55
u32 compilerPC;
56
u32 blockStart;
57
u32 initialBlockSize;
58
int nextExit;
59
bool cancel;
60
bool inDelaySlot;
61
// See JitState::AfterOp for values.
62
int afterOp;
63
int downcountAmount;
64
int numInstructions;
65
bool compiling; // TODO: get rid of this in favor of using analysis results to determine end of block
66
bool hadBreakpoints;
67
JitBlock *curBlock;
68
69
u8 hasSetRounding = 0;
70
u8 lastSetRounding = 0;
71
const u8 *currentRoundingFunc = nullptr;
72
73
// VFPU prefix magic
74
bool startDefaultPrefix = true;
75
bool blockWrotePrefixes = false;
76
u32 prefixS;
77
u32 prefixT;
78
u32 prefixD;
79
PrefixState prefixSFlag = PREFIX_UNKNOWN;
80
PrefixState prefixTFlag = PREFIX_UNKNOWN;
81
PrefixState prefixDFlag = PREFIX_UNKNOWN;
82
83
void Begin(JitBlock *block);
84
85
void PrefixStart() {
86
if (startDefaultPrefix) {
87
EatPrefix();
88
} else {
89
PrefixUnknown();
90
}
91
}
92
93
void PrefixUnknown() {
94
prefixSFlag = PREFIX_UNKNOWN;
95
prefixTFlag = PREFIX_UNKNOWN;
96
prefixDFlag = PREFIX_UNKNOWN;
97
}
98
99
bool HasSPrefix() const {
100
return (prefixSFlag & PREFIX_KNOWN) == 0 || prefixS != 0xE4;
101
}
102
103
bool HasTPrefix() const {
104
return (prefixTFlag & PREFIX_KNOWN) == 0 || prefixT != 0xE4;
105
}
106
107
bool HasDPrefix() const {
108
return (prefixDFlag & PREFIX_KNOWN) == 0 || prefixD != 0x0;
109
}
110
111
bool MayHavePrefix() const {
112
if (HasUnknownPrefix()) {
113
return true;
114
} else if (prefixS != 0xE4 || prefixT != 0xE4 || prefixD != 0) {
115
return true;
116
}
117
return false;
118
}
119
120
bool HasUnknownPrefix() const {
121
if (!(prefixSFlag & PREFIX_KNOWN) || !(prefixTFlag & PREFIX_KNOWN) || !(prefixDFlag & PREFIX_KNOWN)) {
122
return true;
123
}
124
return false;
125
}
126
127
bool HasNoPrefix() const {
128
return !HasSPrefix() && !HasTPrefix() && !HasDPrefix();
129
}
130
131
void EatPrefix() {
132
if (HasSPrefix())
133
prefixSFlag = PREFIX_KNOWN_DIRTY;
134
prefixS = 0xE4;
135
if (HasTPrefix())
136
prefixTFlag = PREFIX_KNOWN_DIRTY;
137
prefixT = 0xE4;
138
if (HasDPrefix())
139
prefixDFlag = PREFIX_KNOWN_DIRTY;
140
prefixD = 0x0;
141
}
142
143
u8 VfpuWriteMask() const {
144
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
145
return (prefixD >> 8) & 0xF;
146
}
147
148
bool VfpuWriteMask(int i) const {
149
_assert_(prefixDFlag & JitState::PREFIX_KNOWN);
150
return (prefixD >> (8 + i)) & 1;
151
}
152
153
void LogPrefix() {
154
LogSTPrefix("S", prefixS, prefixSFlag);
155
LogSTPrefix("T", prefixT, prefixTFlag);
156
LogDPrefix();
157
}
158
159
private:
160
void LogSTPrefix(const char *name, int p, int pflag) {
161
if ((prefixSFlag & PREFIX_KNOWN) == 0) {
162
ERROR_LOG(Log::JIT, "%s: unknown (%08x %i)", name, p, pflag);
163
} else if (prefixS != 0xE4) {
164
ERROR_LOG(Log::JIT, "%s: %08x flag: %i", name, p, pflag);
165
} else {
166
WARN_LOG(Log::JIT, "%s: %08x flag: %i", name, p, pflag);
167
}
168
}
169
void LogDPrefix() {
170
if ((prefixDFlag & PREFIX_KNOWN) == 0) {
171
ERROR_LOG(Log::JIT, "D: unknown (%08x %i)", prefixD, prefixDFlag);
172
} else if (prefixD != 0) {
173
ERROR_LOG(Log::JIT, "D: (%08x %i)", prefixD, prefixDFlag);
174
} else {
175
WARN_LOG(Log::JIT, "D: %08x flag: %i", prefixD, prefixDFlag);
176
}
177
}
178
};
179
180
enum class JitDisable : u32 {
181
DEFAULT = 0,
182
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
ENUM_CLASS_BITOPS(JitDisable);
216
217
struct JitOptions {
218
JitOptions();
219
220
bool Disabled(JitDisable bit);
221
222
JitDisable 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 downcountInRegister;
234
// ARM64 and RV64
235
bool useStaticAlloc;
236
bool enablePointerify;
237
// IR Interpreter
238
bool optimizeForInterpreter;
239
240
// Common
241
bool enableBlocklink;
242
};
243
}
244
245