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/x86/RegCache.h
Views: 1401
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
#pragma once
19
20
#include "ppsspp_config.h"
21
#include "Common/x64Emitter.h"
22
#include "Core/MIPS/MIPS.h"
23
24
namespace X64JitConstants {
25
#if PPSSPP_ARCH(AMD64)
26
const Gen::X64Reg MEMBASEREG = Gen::RBX;
27
const Gen::X64Reg CTXREG = Gen::R14;
28
const Gen::X64Reg JITBASEREG = Gen::R15;
29
#else
30
const Gen::X64Reg CTXREG = Gen::EBP;
31
#endif
32
33
// This must be one of EAX, EBX, ECX, EDX as they have 8-bit subregisters.
34
const Gen::X64Reg TEMPREG = Gen::EAX;
35
const int NUM_MIPS_GPRS = 36;
36
37
#if PPSSPP_ARCH(AMD64)
38
const u32 NUM_X_REGS = 16;
39
#elif PPSSPP_ARCH(X86)
40
const u32 NUM_X_REGS = 8;
41
#endif
42
}
43
44
namespace MIPSAnalyst {
45
struct AnalysisResults;
46
};
47
48
struct MIPSCachedReg {
49
Gen::OpArg location;
50
bool away; // value not in source register
51
bool locked;
52
};
53
54
struct X64CachedReg {
55
MIPSGPReg mipsReg;
56
bool dirty;
57
bool free;
58
bool allocLocked;
59
};
60
61
struct GPRRegCacheState {
62
MIPSCachedReg regs[X64JitConstants::NUM_MIPS_GPRS];
63
X64CachedReg xregs[X64JitConstants::NUM_X_REGS];
64
};
65
66
namespace MIPSComp {
67
struct JitOptions;
68
struct JitState;
69
}
70
71
class GPRRegCache
72
{
73
public:
74
GPRRegCache();
75
~GPRRegCache() {}
76
void Start(MIPSState *mipsState, MIPSComp::JitState *js, MIPSComp::JitOptions *jo, MIPSAnalyst::AnalysisResults &stats);
77
78
void DiscardRegContentsIfCached(MIPSGPReg preg);
79
void DiscardR(MIPSGPReg preg);
80
void SetEmitter(Gen::XEmitter *emitter) {emit = emitter;}
81
82
void FlushR(Gen::X64Reg reg);
83
void FlushLockX(Gen::X64Reg reg) {
84
FlushR(reg);
85
LockX(reg);
86
}
87
void FlushLockX(Gen::X64Reg reg1, Gen::X64Reg reg2) {
88
FlushR(reg1); FlushR(reg2);
89
LockX(reg1); LockX(reg2);
90
}
91
void Flush();
92
void FlushBeforeCall();
93
94
// Flushes one register and reuses the register for another one. Dirtyness is implied.
95
void FlushRemap(MIPSGPReg oldreg, MIPSGPReg newreg);
96
97
int SanityCheck() const;
98
void KillImmediate(MIPSGPReg preg, bool doLoad, bool makeDirty);
99
100
void MapReg(MIPSGPReg preg, bool doLoad = true, bool makeDirty = true);
101
void StoreFromRegister(MIPSGPReg preg);
102
103
const Gen::OpArg &R(MIPSGPReg preg) const {return regs[preg].location;}
104
Gen::X64Reg RX(MIPSGPReg preg) const
105
{
106
if (regs[preg].away && regs[preg].location.IsSimpleReg())
107
return regs[preg].location.GetSimpleReg();
108
_assert_msg_(false, "Not so simple - %d", preg);
109
return (Gen::X64Reg)-1;
110
}
111
Gen::OpArg GetDefaultLocation(MIPSGPReg reg) const;
112
113
// Register locking.
114
void Lock(MIPSGPReg p1, MIPSGPReg p2 = MIPS_REG_INVALID, MIPSGPReg p3 = MIPS_REG_INVALID, MIPSGPReg p4 = MIPS_REG_INVALID);
115
void LockX(int x1, int x2=0xff, int x3=0xff, int x4=0xff);
116
void UnlockAll();
117
void UnlockAllX();
118
119
void SetImm(MIPSGPReg preg, u32 immValue);
120
bool IsImm(MIPSGPReg preg) const;
121
u32 GetImm(MIPSGPReg preg) const;
122
123
void GetState(GPRRegCacheState &state) const;
124
void RestoreState(const GPRRegCacheState& state);
125
126
MIPSState *mips_ = nullptr;
127
128
private:
129
Gen::X64Reg GetFreeXReg();
130
Gen::X64Reg FindBestToSpill(bool unusedOnly, bool *clobbered);
131
const Gen::X64Reg *GetAllocationOrder(int &count);
132
133
MIPSCachedReg regs[X64JitConstants::NUM_MIPS_GPRS]{};
134
X64CachedReg xregs[X64JitConstants::NUM_X_REGS]{};
135
136
Gen::XEmitter *emit = nullptr;
137
MIPSComp::JitState *js_;
138
MIPSComp::JitOptions *jo_;
139
};
140
141