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/RiscV/RiscVCompBranch.cpp
Views: 1401
1
// Copyright (c) 2023- 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 "Core/MIPS/RiscV/RiscVJit.h"
19
#include "Core/MIPS/RiscV/RiscVRegCache.h"
20
21
// This file contains compilation for exits.
22
//
23
// All functions should have CONDITIONAL_DISABLE, so we can narrow things down to a file quickly.
24
// Currently known non working ones should have DISABLE. No flags because that's in IR already.
25
26
// #define CONDITIONAL_DISABLE { CompIR_Generic(inst); return; }
27
#define CONDITIONAL_DISABLE {}
28
#define DISABLE { CompIR_Generic(inst); return; }
29
#define INVALIDOP { _assert_msg_(false, "Invalid IR inst %d", (int)inst.op); CompIR_Generic(inst); return; }
30
31
namespace MIPSComp {
32
33
using namespace RiscVGen;
34
using namespace RiscVJitConstants;
35
36
void RiscVJitBackend::CompIR_Exit(IRInst inst) {
37
CONDITIONAL_DISABLE;
38
39
RiscVReg exitReg = INVALID_REG;
40
switch (inst.op) {
41
case IROp::ExitToConst:
42
FlushAll();
43
WriteConstExit(inst.constant);
44
break;
45
46
case IROp::ExitToReg:
47
exitReg = regs_.MapGPR(inst.src1);
48
FlushAll();
49
// TODO: If ever we don't read this back in dispatcherPCInSCRATCH1_, we should zero upper.
50
MV(SCRATCH1, exitReg);
51
QuickJ(R_RA, dispatcherPCInSCRATCH1_);
52
break;
53
54
case IROp::ExitToPC:
55
FlushAll();
56
QuickJ(R_RA, dispatcherCheckCoreState_);
57
break;
58
59
default:
60
INVALIDOP;
61
break;
62
}
63
}
64
65
void RiscVJitBackend::CompIR_ExitIf(IRInst inst) {
66
CONDITIONAL_DISABLE;
67
68
RiscVReg lhs = INVALID_REG;
69
RiscVReg rhs = INVALID_REG;
70
FixupBranch fixup;
71
switch (inst.op) {
72
case IROp::ExitToConstIfEq:
73
case IROp::ExitToConstIfNeq:
74
regs_.Map(inst);
75
// We can't use SCRATCH1, which is destroyed by FlushAll()... but cheat and use R_RA.
76
NormalizeSrc12(inst, &lhs, &rhs, R_RA, SCRATCH2, true);
77
FlushAll();
78
79
switch (inst.op) {
80
case IROp::ExitToConstIfEq:
81
fixup = BNE(lhs, rhs);
82
break;
83
84
case IROp::ExitToConstIfNeq:
85
fixup = BEQ(lhs, rhs);
86
break;
87
88
default:
89
INVALIDOP;
90
break;
91
}
92
93
WriteConstExit(inst.constant);
94
SetJumpTarget(fixup);
95
break;
96
97
case IROp::ExitToConstIfGtZ:
98
case IROp::ExitToConstIfGeZ:
99
case IROp::ExitToConstIfLtZ:
100
case IROp::ExitToConstIfLeZ:
101
regs_.Map(inst);
102
NormalizeSrc1(inst, &lhs, SCRATCH2, true);
103
FlushAll();
104
105
switch (inst.op) {
106
case IROp::ExitToConstIfGtZ:
107
fixup = BGE(R_ZERO, lhs);
108
break;
109
110
case IROp::ExitToConstIfGeZ:
111
fixup = BLT(lhs, R_ZERO);
112
break;
113
114
case IROp::ExitToConstIfLtZ:
115
fixup = BGE(lhs, R_ZERO);
116
break;
117
118
case IROp::ExitToConstIfLeZ:
119
fixup = BLT(R_ZERO, lhs);
120
break;
121
122
default:
123
INVALIDOP;
124
break;
125
}
126
127
WriteConstExit(inst.constant);
128
SetJumpTarget(fixup);
129
break;
130
131
case IROp::ExitToConstIfFpTrue:
132
case IROp::ExitToConstIfFpFalse:
133
// Note: not used.
134
DISABLE;
135
break;
136
137
default:
138
INVALIDOP;
139
break;
140
}
141
}
142
143
} // namespace MIPSComp
144
145