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/ARM64/Arm64RegCacheFPU.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 "Core/MIPS/MIPS.h"
21
#include "Core/MIPS/ARM64/Arm64RegCache.h"
22
#include "Core/MIPS/MIPSVFPUUtils.h"
23
#include "Common/Arm64Emitter.h"
24
25
namespace Arm64JitConstants {
26
27
enum {
28
NUM_TEMPS = 16,
29
TEMP0 = 32 + 128,
30
TOTAL_MAPPABLE_MIPSFPUREGS = 32 + 128 + NUM_TEMPS,
31
};
32
33
enum {
34
MAP_READ = 0,
35
MAP_MTX_TRANSPOSED = 16,
36
MAP_PREFER_LOW = 16,
37
MAP_PREFER_HIGH = 32,
38
39
// Force is not yet correctly implemented, if the reg is already mapped it will not move
40
MAP_FORCE_LOW = 64, // Only map Q0-Q7 (and probably not Q0-Q3 as they are S registers so that leaves Q8-Q15)
41
MAP_FORCE_HIGH = 128, // Only map Q8-Q15
42
};
43
44
}
45
46
namespace MIPSAnalyst {
47
struct AnalysisResults;
48
};
49
50
struct FPURegARM64 {
51
int mipsReg; // if -1, no mipsreg attached.
52
bool isDirty; // Should the register be written back?
53
};
54
55
struct FPURegQuad64 {
56
int mipsVec;
57
VectorSize sz;
58
u8 vregs[4];
59
bool isDirty;
60
bool spillLock;
61
bool isTemp;
62
};
63
64
struct FPURegMIPS {
65
// Where is this MIPS register?
66
Arm64JitConstants::RegMIPSLoc loc;
67
// Data (only one of these is used, depending on loc. Could make a union).
68
u32 reg;
69
int lane;
70
71
bool spillLock; // if true, this register cannot be spilled.
72
bool tempLock;
73
// If loc == ML_MEM, it's back in its location in the CPU context struct.
74
};
75
76
namespace MIPSComp {
77
struct JitOptions;
78
struct JitState;
79
}
80
81
class Arm64RegCacheFPU {
82
public:
83
Arm64RegCacheFPU(MIPSState *mipsState, MIPSComp::JitState *js, MIPSComp::JitOptions *jo);
84
~Arm64RegCacheFPU() {}
85
86
void Init(Arm64Gen::ARM64XEmitter *emitter, Arm64Gen::ARM64FloatEmitter *fp);
87
88
void Start(MIPSAnalyst::AnalysisResults &stats);
89
90
// Protect the arm register containing a MIPS register from spilling, to ensure that
91
// it's being kept allocated.
92
void SpillLock(MIPSReg reg, MIPSReg reg2 = -1, MIPSReg reg3 = -1, MIPSReg reg4 = -1);
93
void SpillLockV(MIPSReg r) { SpillLock(r + 32); }
94
95
void ReleaseSpillLocksAndDiscardTemps();
96
void ReleaseSpillLock(int mipsreg) {
97
mr[mipsreg].spillLock = false;
98
}
99
void ReleaseSpillLockV(int mipsreg) {
100
ReleaseSpillLock(mipsreg + 32);
101
}
102
103
void SetImm(MIPSReg reg, u32 immVal);
104
bool IsImm(MIPSReg reg) const;
105
u32 GetImm(MIPSReg reg) const;
106
107
// Returns an ARM register containing the requested MIPS register.
108
Arm64Gen::ARM64Reg MapReg(MIPSReg reg, int mapFlags = 0);
109
void MapInIn(MIPSReg rd, MIPSReg rs);
110
void MapDirty(MIPSReg rd);
111
void MapDirtyIn(MIPSReg rd, MIPSReg rs, bool avoidLoad = true);
112
void MapDirtyInIn(MIPSReg rd, MIPSReg rs, MIPSReg rt, bool avoidLoad = true);
113
bool IsMapped(MIPSReg r);
114
bool IsMappedV(MIPSReg r) { return IsMapped((MIPSReg)(r + 32)); }
115
bool IsInRAM(MIPSReg r);
116
bool IsInRAMV(MIPSReg r) { return IsInRAM((MIPSReg)(r + 32)); }
117
void FlushArmReg(Arm64Gen::ARM64Reg r);
118
void FlushR(MIPSReg r);
119
void DiscardR(MIPSReg r);
120
Arm64Gen::ARM64Reg R(int preg); // Returns a cached register
121
122
void MapRegV(int vreg, int flags = 0);
123
void LoadToRegV(Arm64Gen::ARM64Reg armReg, int vreg);
124
void MapInInV(int rt, int rs);
125
void MapDirtyInV(int rd, int rs, bool avoidLoad = true);
126
void MapDirtyInInV(int rd, int rs, int rt, bool avoidLoad = true);
127
128
bool IsTempX(Arm64Gen::ARM64Reg r) const;
129
MIPSReg GetTempV() { return GetTempR() - 32; }
130
// VFPU registers as single VFP registers.
131
Arm64Gen::ARM64Reg V(int vreg) { return R(vreg + 32); }
132
133
void FlushAll();
134
135
// This one is allowed at any point.
136
void FlushV(MIPSReg r);
137
138
// NOTE: These require you to release spill locks manually!
139
void MapRegsAndSpillLockV(int vec, VectorSize vsz, int flags);
140
void MapRegsAndSpillLockV(const u8 *v, VectorSize vsz, int flags);
141
142
void SpillLockV(const u8 *v, VectorSize vsz);
143
void SpillLockV(int vec, VectorSize vsz);
144
145
void SetEmitter(Arm64Gen::ARM64XEmitter *emitter, Arm64Gen::ARM64FloatEmitter *fp) { emit_ = emitter; fp_ = fp; }
146
147
int GetMipsRegOffset(MIPSReg r);
148
int GetMipsRegOffsetV(MIPSReg r) {
149
return GetMipsRegOffset(r + 32);
150
}
151
152
private:
153
Arm64Gen::ARM64Reg ARM64RegForFlush(int r);
154
MIPSReg GetTempR();
155
const Arm64Gen::ARM64Reg *GetMIPSAllocationOrder(int &count);
156
157
void SetupInitialRegs();
158
159
MIPSState *mips_;
160
Arm64Gen::ARM64XEmitter *emit_;
161
Arm64Gen::ARM64FloatEmitter *fp_;
162
MIPSComp::JitState *js_;
163
MIPSComp::JitOptions *jo_;
164
165
int numARMFpuReg_;
166
167
enum {
168
// On ARM64, each of the 32 registers are full 128-bit. No sharing of components!
169
MAX_ARMFPUREG = 32,
170
NUM_MIPSFPUREG = Arm64JitConstants::TOTAL_MAPPABLE_MIPSFPUREGS,
171
};
172
173
FPURegARM64 ar[MAX_ARMFPUREG];
174
FPURegMIPS mr[NUM_MIPSFPUREG];
175
FPURegMIPS *vr;
176
177
bool pendingFlush;
178
bool initialReady = false;
179
FPURegARM64 arInitial[MAX_ARMFPUREG];
180
FPURegMIPS mrInitial[NUM_MIPSFPUREG];
181
};
182
183