1
// Copyright (c) 2012- PPSSPP Project.
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.
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.
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
15
// Official git repository and contact information can be found at
16
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
21
#include "math/math_util.h"
24
#include "Common/ChunkFile.h"
25
#include "Core/MIPS/MIPS.h"
26
#include "Core/MIPS/MIPSInt.h"
27
#include "Core/MIPS/MIPSTables.h"
28
#include "Core/MIPS/MIPSDebugInterface.h"
29
#include "Core/MIPS/MIPSVFPUUtils.h"
30
#include "Core/MIPS/IR/IRJit.h"
31
#include "Core/Reporting.h"
32
#include "Core/System.h"
33
#include "Core/HLE/sceDisplay.h"
34
#include "Core/MIPS/JitCommon/JitCommon.h"
35
#include "Core/CoreTiming.h"
38
MIPSState *currentMIPS = &mipsr4k;
39
MIPSDebugInterface debugr4k(&mipsr4k);
40
MIPSDebugInterface *currentDebugMIPS = &debugr4k;
47
#define M_E 2.71828182845904523536f
48
#define M_LOG2E 1.44269504088896340736f
49
#define M_LOG10E 0.434294481903251827651f
50
#define M_LN2 0.693147180559945309417f
51
#define M_LN10 2.30258509299404568402f
53
#define M_PI 3.14159265358979323846f
56
#define M_PI_2 1.57079632679489661923f
58
#define M_PI_4 0.785398163397448309616f
59
#define M_1_PI 0.318309886183790671538f
60
#define M_2_PI 0.636619772367581343076f
61
#define M_2_SQRTPI 1.12837916709551257390f
62
#define M_SQRT2 1.41421356237309504880f
63
#define M_SQRT1_2 0.707106781186547524401f
66
const float cst_constants[32] = {
68
std::numeric_limits<float>::max(), // all these are verified on real PSP
71
2.0f/sqrtf((float)M_PI),
85
logf(10.0f)/logf(2.0f),
90
MIPSState::MIPSState() {
95
// This reordering of the VFPU registers in RAM means that instead of being like this:
97
// 0x00 0x20 0x40 0x60 -> "columns", the most common direction
98
// 0x01 0x21 0x41 0x61
99
// 0x02 0x22 0x42 0x62
100
// 0x03 0x23 0x43 0x63
102
// 0x04 0x24 0x44 0x64
103
// 0x06 0x26 0x45 0x65
106
// the VPU registers are effectively organized like this:
107
// 0x00 0x01 0x02 0x03
108
// 0x04 0x05 0x06 0x07
109
// 0x08 0x09 0x0a 0x0b
112
// This is because the original indices look like this:
113
// 0XXMMMYY where M is the matrix number.
115
// We will now map 0YYMMMXX to 0MMMXXYY.
118
// * Columns can be flushed and reloaded faster "at once"
119
// * 4x4 Matrices are contiguous in RAM, making them, too, fast-loadable in NEON
122
// * Extra indirection, can be confusing and slower (interpreter only)
123
// * Flushing and reloading row registers is now slower
126
for (int m = 0; m < 8; m++) {
127
for (int y = 0; y < 4; y++) {
128
for (int x = 0; x < 4; x++) {
129
voffset[m * 4 + x * 32 + y] = i++;
135
for (int i = 0; i < 128; i++) {
136
fromvoffset[voffset[i]] = i;
139
// Sanity check that things that should be ordered are ordered.
140
static const u8 firstThirtyTwo[] = {
141
0x0, 0x20, 0x40, 0x60,
142
0x1, 0x21, 0x41, 0x61,
143
0x2, 0x22, 0x42, 0x62,
144
0x3, 0x23, 0x43, 0x63,
146
0x4, 0x24, 0x44, 0x64,
147
0x5, 0x25, 0x45, 0x65,
148
0x6, 0x26, 0x46, 0x66,
149
0x7, 0x27, 0x47, 0x67,
152
for (int i = 0; i < (int)ARRAY_SIZE(firstThirtyTwo); i++) {
153
if (voffset[firstThirtyTwo[i]] != i) {
154
ERROR_LOG(CPU, "Wrong voffset order! %i: %i should have been %i", firstThirtyTwo[i], voffset[firstThirtyTwo[i]], i);
159
MIPSState::~MIPSState() {
163
void MIPSState::Shutdown() {
165
delete MIPSComp::jit;
170
void MIPSState::Reset() {
175
void MIPSState::Init() {
176
memset(r, 0, sizeof(r));
177
memset(f, 0, sizeof(f));
178
memset(v, 0, sizeof(v));
179
memset(vfpuCtrl, 0, sizeof(vfpuCtrl));
181
vfpuCtrl[VFPU_CTRL_SPREFIX] = 0xe4; //passthru
182
vfpuCtrl[VFPU_CTRL_TPREFIX] = 0xe4; //passthru
183
vfpuCtrl[VFPU_CTRL_DPREFIX] = 0;
184
vfpuCtrl[VFPU_CTRL_CC] = 0x3f;
185
vfpuCtrl[VFPU_CTRL_INF4] = 0;
186
vfpuCtrl[VFPU_CTRL_REV] = 0x7772ceab;
187
vfpuCtrl[VFPU_CTRL_RCX0] = 0x3f800001;
188
vfpuCtrl[VFPU_CTRL_RCX1] = 0x3f800002;
189
vfpuCtrl[VFPU_CTRL_RCX2] = 0x3f800004;
190
vfpuCtrl[VFPU_CTRL_RCX3] = 0x3f800008;
191
vfpuCtrl[VFPU_CTRL_RCX4] = 0x3f800000;
192
vfpuCtrl[VFPU_CTRL_RCX5] = 0x3f800000;
193
vfpuCtrl[VFPU_CTRL_RCX6] = 0x3f800000;
194
vfpuCtrl[VFPU_CTRL_RCX7] = 0x3f800000;
207
// Initialize the VFPU random number generator with .. something?
210
if (PSP_CoreParameter().cpuCore == CPU_CORE_JIT) {
211
MIPSComp::jit = MIPSComp::CreateNativeJit(this);
212
} else if (PSP_CoreParameter().cpuCore == CPU_CORE_IRJIT) {
213
MIPSComp::jit = new MIPSComp::IRJit(this);
215
MIPSComp::jit = nullptr;
219
bool MIPSState::HasDefaultPrefix() const {
220
return vfpuCtrl[VFPU_CTRL_SPREFIX] == 0xe4 && vfpuCtrl[VFPU_CTRL_TPREFIX] == 0xe4 && vfpuCtrl[VFPU_CTRL_DPREFIX] == 0;
223
void MIPSState::UpdateCore(CPUCore desired) {
224
if (PSP_CoreParameter().cpuCore == desired) {
228
PSP_CoreParameter().cpuCore = desired;
229
switch (PSP_CoreParameter().cpuCore) {
231
INFO_LOG(CPU, "Switching to JIT");
233
delete MIPSComp::jit;
235
MIPSComp::jit = MIPSComp::CreateNativeJit(this);
239
INFO_LOG(CPU, "Switching to IRJIT");
241
delete MIPSComp::jit;
243
MIPSComp::jit = new MIPSComp::IRJit(this);
246
case CPU_CORE_INTERPRETER:
247
INFO_LOG(CPU, "Switching to interpreter");
248
delete MIPSComp::jit;
254
void MIPSState::DoState(PointerWrap &p) {
255
auto s = p.Section("MIPSState", 1, 3);
259
// Reset the jit if we're loading.
260
if (p.mode == p.MODE_READ)
263
MIPSComp::jit->DoState(p);
265
MIPSComp::jit->DoDummyState(p);
267
p.DoArray(r, sizeof(r) / sizeof(r[0]));
268
p.DoArray(f, sizeof(f) / sizeof(f[0]));
271
p.DoArray(vtemp, sizeof(v) / sizeof(v[0]));
272
for (int i = 0; i < 128; i++) {
273
v[voffset[i]] = vtemp[i];
276
p.DoArray(v, sizeof(v) / sizeof(v[0]));
278
p.DoArray(vfpuCtrl, sizeof(vfpuCtrl) / sizeof(vfpuCtrl[0]));
282
// Reversed, but we can just leave it that way.
298
void MIPSState::SingleStep() {
299
int cycles = MIPS_SingleStep();
300
currentMIPS->downcount -= cycles;
301
CoreTiming::Advance();
304
// returns 1 if reached ticks limit
305
int MIPSState::RunLoopUntil(u64 globalTicks) {
306
switch (PSP_CoreParameter().cpuCore) {
309
MIPSComp::jit->RunLoopUntil(globalTicks);
312
case CPU_CORE_INTERPRETER:
313
return MIPSInterpret_RunUntil(globalTicks);
318
void MIPSState::InvalidateICache(u32 address, int length) {
319
// Only really applies to jit.
321
MIPSComp::jit->InvalidateCacheAt(address, length);
324
void MIPSState::ClearJitCache() {
326
MIPSComp::jit->ClearCache();