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 #include <cmath>
19 #include <limits>
20
21 #include "Common/Math/math_util.h"
22
23 #include "Common.h"
24 #include "Common/Serialize/Serializer.h"
25 #include "Common/Serialize/SerializeFuncs.h"
26 #include "Core/ConfigValues.h"
27 #include "Core/MIPS/MIPS.h"
28 #include "Core/MIPS/MIPSInt.h"
29 #include "Core/MIPS/MIPSTables.h"
30 #include "Core/MIPS/MIPSDebugInterface.h"
31 #include "Core/MIPS/MIPSVFPUUtils.h"
32 #include "Core/MIPS/IR/IRJit.h"
33 #include "Core/Reporting.h"
34 #include "Core/System.h"
35 #include "Core/HLE/sceDisplay.h"
36 #include "Core/MIPS/JitCommon/JitCommon.h"
37 #include "Core/CoreTiming.h"
38
39 MIPSState mipsr4k;
40 MIPSState *currentMIPS = &mipsr4k;
41 MIPSDebugInterface debugr4k(&mipsr4k);
42 MIPSDebugInterface *currentDebugMIPS = &debugr4k;
43
44 u8 voffset[128];
45 u8 fromvoffset[128];
46
47
48 #ifndef M_LOG2E
49 #define M_E 2.71828182845904523536f
50 #define M_LOG2E 1.44269504088896340736f
51 #define M_LOG10E 0.434294481903251827651f
GetCrashHandler()52 #define M_LN2 0.693147180559945309417f
53 #define M_LN10 2.30258509299404568402f
54 #undef M_PI
55 #define M_PI 3.14159265358979323846f
56
57 #ifndef M_PI_2
58 #define M_PI_2 1.57079632679489661923f
59 #endif
60 #define M_PI_4 0.785398163397448309616f
61 #define M_1_PI 0.318309886183790671538f
62 #define M_2_PI 0.636619772367581343076f
63 #define M_2_SQRTPI 1.12837916709551257390f
64 #define M_SQRT2 1.41421356237309504880f
65 #define M_SQRT1_2 0.707106781186547524401f
66 #endif
67
68 const float cst_constants[32] = {
69 0,
70 std::numeric_limits<float>::max(), // all these are verified on real PSP
71 sqrtf(2.0f),
72 sqrtf(0.5f),
73 2.0f/sqrtf((float)M_PI),
74 2.0f/(float)M_PI,
75 1.0f/(float)M_PI,
76 (float)M_PI/4,
77 (float)M_PI/2,
78 (float)M_PI,
79 (float)M_E,
80 (float)M_LOG2E,
81 (float)M_LOG10E,
82 (float)M_LN2,
83 (float)M_LN10,
84 2*(float)M_PI,
85 (float)M_PI/6,
86 log10f(2.0f),
87 logf(10.0f)/logf(2.0f),
88 sqrtf(3.0f)/2.0f,
89 };
90
Comp_DoNothing(MIPSOpcode op)91
92 MIPSState::MIPSState() {
93 MIPSComp::jit = 0;
94
95 // Initialize vorder
96
97 // This reordering of the VFPU registers in RAM means that instead of being like this:
98
99 // 0x00 0x20 0x40 0x60 -> "columns", the most common direction
100 // 0x01 0x21 0x41 0x61
101 // 0x02 0x22 0x42 0x62
102 // 0x03 0x23 0x43 0x63
103
104 // 0x04 0x24 0x44 0x64
105 // 0x06 0x26 0x45 0x65
106 // ....
107
108 // the VPU registers are effectively organized like this:
109 // 0x00 0x01 0x02 0x03
110 // 0x04 0x05 0x06 0x07
111 // 0x08 0x09 0x0a 0x0b
112 // ....
113
114 // This is because the original indices look like this:
115 // 0XXMMMYY where M is the matrix number.
116
117 // We will now map 0YYMMMXX to 0MMMXXYY.
118
119 // Advantages:
120 // * Columns can be flushed and reloaded faster "at once"
121 // * 4x4 Matrices are contiguous in RAM, making them, too, fast-loadable in NEON
122
123 // Disadvantages:
124 // * Extra indirection, can be confusing and slower (interpreter only)
125 // * Flushing and reloading row registers is now slower
126
127 int i = 0;
128 for (int m = 0; m < 8; m++) {
129 for (int y = 0; y < 4; y++) {
130 for (int x = 0; x < 4; x++) {
131 voffset[m * 4 + x * 32 + y] = i++;
132 }
133 }
134 }
135
136 // And the inverse.
137 for (int i = 0; i < 128; i++) {
138 fromvoffset[voffset[i]] = i;
139 }
140
141 // Sanity check that things that should be ordered are ordered.
142 static const u8 firstThirtyTwo[] = {
143 0x0, 0x20, 0x40, 0x60,
144 0x1, 0x21, 0x41, 0x61,
145 0x2, 0x22, 0x42, 0x62,
146 0x3, 0x23, 0x43, 0x63,
147
148 0x4, 0x24, 0x44, 0x64,
149 0x5, 0x25, 0x45, 0x65,
150 0x6, 0x26, 0x46, 0x66,
151 0x7, 0x27, 0x47, 0x67,
152 };
153
154 for (int i = 0; i < (int)ARRAY_SIZE(firstThirtyTwo); i++) {
155 if (voffset[firstThirtyTwo[i]] != i) {
156 ERROR_LOG(CPU, "Wrong voffset order! %i: %i should have been %i", firstThirtyTwo[i], voffset[firstThirtyTwo[i]], i);
157 }
158 }
159 }
160
161 MIPSState::~MIPSState() {
162 Shutdown();
163 }
164
165 void MIPSState::Shutdown() {
166 if (MIPSComp::jit) {
167 delete MIPSComp::jit;
168 MIPSComp::jit = 0;
169 }
170 }
171
172 void MIPSState::Reset() {
173 Shutdown();
174 Init();
175 }
176
177 void MIPSState::Init() {
178 memset(r, 0, sizeof(r));
179 memset(f, 0, sizeof(f));
180 memset(v, 0, sizeof(v));
181 memset(vfpuCtrl, 0, sizeof(vfpuCtrl));
182
183 vfpuCtrl[VFPU_CTRL_SPREFIX] = 0xe4; //passthru
184 vfpuCtrl[VFPU_CTRL_TPREFIX] = 0xe4; //passthru
185 vfpuCtrl[VFPU_CTRL_DPREFIX] = 0;
186 vfpuCtrl[VFPU_CTRL_CC] = 0x3f;
187 vfpuCtrl[VFPU_CTRL_INF4] = 0;
188 vfpuCtrl[VFPU_CTRL_REV] = 0x7772ceab;
189 vfpuCtrl[VFPU_CTRL_RCX0] = 0x3f800001;
190 vfpuCtrl[VFPU_CTRL_RCX1] = 0x3f800002;
191 vfpuCtrl[VFPU_CTRL_RCX2] = 0x3f800004;
192 vfpuCtrl[VFPU_CTRL_RCX3] = 0x3f800008;
193 vfpuCtrl[VFPU_CTRL_RCX4] = 0x3f800000;
194 vfpuCtrl[VFPU_CTRL_RCX5] = 0x3f800000;
195 vfpuCtrl[VFPU_CTRL_RCX6] = 0x3f800000;
196 vfpuCtrl[VFPU_CTRL_RCX7] = 0x3f800000;
197
198 pc = 0;
199 hi = 0;
200 lo = 0;
201 fpcond = 0;
202 fcr31 = 0;
203 debugCount = 0;
204 currentMIPS = this;
205 inDelaySlot = false;
206 llBit = 0;
207 nextPC = 0;
208 downcount = 0;
209 // Initialize the VFPU random number generator with .. something?
210 rng.Init(0x1337);
211
212 if (PSP_CoreParameter().cpuCore == CPUCore::JIT) {
213 MIPSComp::jit = MIPSComp::CreateNativeJit(this);
214 } else if (PSP_CoreParameter().cpuCore == CPUCore::IR_JIT) {
215 MIPSComp::jit = new MIPSComp::IRJit(this);
216 } else {
217 MIPSComp::jit = nullptr;
218 }
219 }
220
221 bool MIPSState::HasDefaultPrefix() const {
222 return vfpuCtrl[VFPU_CTRL_SPREFIX] == 0xe4 && vfpuCtrl[VFPU_CTRL_TPREFIX] == 0xe4 && vfpuCtrl[VFPU_CTRL_DPREFIX] == 0;
223 }
224
225 void MIPSState::UpdateCore(CPUCore desired) {
226 if (PSP_CoreParameter().cpuCore == desired) {
227 return;
228 }
229
230 PSP_CoreParameter().cpuCore = desired;
231 switch (PSP_CoreParameter().cpuCore) {
232 case CPUCore::JIT:
233 INFO_LOG(CPU, "Switching to JIT");
234 if (MIPSComp::jit) {
235 delete MIPSComp::jit;
236 }
237 MIPSComp::jit = MIPSComp::CreateNativeJit(this);
238 break;
239
240 case CPUCore::IR_JIT:
241 INFO_LOG(CPU, "Switching to IRJIT");
242 if (MIPSComp::jit) {
243 delete MIPSComp::jit;
244 }
245 MIPSComp::jit = new MIPSComp::IRJit(this);
246 break;
247
248 case CPUCore::INTERPRETER:
249 INFO_LOG(CPU, "Switching to interpreter");
250 delete MIPSComp::jit;
251 MIPSComp::jit = 0;
252 break;
253 }
254 }
255
256 void MIPSState::DoState(PointerWrap &p) {
257 auto s = p.Section("MIPSState", 1, 3);
258 if (!s)
259 return;
260
261 // Reset the jit if we're loading.
262 if (p.mode == p.MODE_READ)
263 Reset();
264 if (MIPSComp::jit)
265 MIPSComp::jit->DoState(p);
266 else
267 MIPSComp::DoDummyJitState(p);
268
269 DoArray(p, r, sizeof(r) / sizeof(r[0]));
270 DoArray(p, f, sizeof(f) / sizeof(f[0]));
271 if (s <= 2) {
272 float vtemp[128];
273 DoArray(p, vtemp, sizeof(v) / sizeof(v[0]));
274 for (int i = 0; i < 128; i++) {
275 v[voffset[i]] = vtemp[i];
276 }
277 } else {
278 DoArray(p, v, sizeof(v) / sizeof(v[0]));
279 }
280 DoArray(p, vfpuCtrl, sizeof(vfpuCtrl) / sizeof(vfpuCtrl[0]));
281 Do(p, pc);
282 Do(p, nextPC);
283 Do(p, downcount);
284 // Reversed, but we can just leave it that way.
285 Do(p, hi);
286 Do(p, lo);
287 Do(p, fpcond);
288 if (s <= 1) {
289 u32 fcr0_unused = 0;
290 Do(p, fcr0_unused);
291 }
292 Do(p, fcr31);
293 Do(p, rng.m_w);
294 Do(p, rng.m_z);
295 Do(p, inDelaySlot);
296 Do(p, llBit);
297 Do(p, debugCount);
298
299 if (p.mode == p.MODE_READ && MIPSComp::jit) {
300 // Now that we've loaded fcr31, update any jit state associated.
301 MIPSComp::jit->UpdateFCR31();
302 }
303 }
304
305 void MIPSState::SingleStep() {
306 int cycles = MIPS_SingleStep();
307 currentMIPS->downcount -= cycles;
308 CoreTiming::Advance();
309 }
310
311 // returns 1 if reached ticks limit
312 int MIPSState::RunLoopUntil(u64 globalTicks) {
313 switch (PSP_CoreParameter().cpuCore) {
314 case CPUCore::JIT:
315 case CPUCore::IR_JIT:
316 while (inDelaySlot) {
317 // We must get out of the delay slot before going into jit.
318 SingleStep();
319 }
320 MIPSComp::jit->RunLoopUntil(globalTicks);
321 break;
322
323 case CPUCore::INTERPRETER:
324 return MIPSInterpret_RunUntil(globalTicks);
325 }
326 return 1;
327 }
328
329 void MIPSState::InvalidateICache(u32 address, int length) {
330 // Only really applies to jit.
331 if (MIPSComp::jit)
332 MIPSComp::jit->InvalidateCacheAt(address, length);
333 }
334
335 void MIPSState::ClearJitCache() {
336 if (MIPSComp::jit)
337 MIPSComp::jit->ClearCache();
338 }
339