-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRISCVRegister.cpp
More file actions
191 lines (174 loc) · 5.45 KB
/
Copy pathRISCVRegister.cpp
File metadata and controls
191 lines (174 loc) · 5.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
/**
* @file RISCVRegister.cpp
* @brief RISC-V 寄存器类的实现文件
* @details 本文件实现了 RISC-V 架构中的物理寄存器、虚拟寄存器、加载地址寄存器以及寄存器列表的相关方法。
* 包括寄存器的创建、获取、设置和打印功能。
*/
#include "../include/backend/RISCVRegister.hpp"
#include "../include/lib/MagicEnum.hpp"
#include <sstream>
#include <string>
PhyRegister::PhyRegister(PhyReg _regenum)
: Register(RISCVType::riscv_none, magic_enum::enum_name(_regenum)),
regenum(_regenum) {}
PhyRegister *PhyRegister::GetPhyReg(PhyReg _regnum) {
static std::unordered_map<PhyReg, PhyRegister *> registry;
auto it = registry.find(_regnum);
if (it == registry.end())
it = registry.emplace(_regnum, new PhyRegister(_regnum)).first;
return it->second;
}
VirRegister::VirRegister(RISCVType tp, uint32_t _spill, uint32_t _reload)
: Register(tp) {
penalty_spill = _spill;
penalty_reload = _reload;
static int cnt = 0;
counter = cnt++;
//set name
std::ostringstream oss;
oss << "%" << counter;
rname= oss.str();
}
PhyRegister* PhyRegMask::GetPhyReg(uint64_t flag){
for(uint8_t i=0u;i<64u;i++){
if(flag==(((uint64_t)1)<<i)){
auto regenum = PhyRegister::PhyReg(i);
return PhyRegister::GetPhyReg(regenum);
}
}
assert(0&&"Can not get here");
}
uint64_t PhyRegMask::GetPhyRegMask(PhyRegister* reg) {
return ((uint64_t)1) << static_cast<uint64_t>(reg->Getregenum());
}
bool PhyRegMask::isCallerSaved(uint64_t flag) {
auto reg = GetPhyReg(flag);
return reg->isCallerSaved();
}
bool PhyRegMask::isCalleeSaved(uint64_t flag) {
auto reg = GetPhyReg(flag);
return reg->isCalleeSaved();
}
void PhyRegMask::visit(uint64_t flag, std::function<void(uint64_t)> func) {
for(uint8_t i=0u;i<64u;i++){
if(flag&(((uint64_t)1)<<i)){
func((uint64_t)1<<i);
}
}
}
void PhyRegister::print() { std::cout << magic_enum::enum_name(regenum); }
std::string PhyRegister::GetName() {
auto x= magic_enum::enum_name(regenum);
std::string str(x);
return str;
}
std::string VirRegister::GetName() {
return "."+std::to_string(counter);
}
void VirRegister::print(){
std::cout<<"%"<<counter;
}
// std::string VirRegister::GetName() {
// std::ostringstream oss;
// oss << "%" << counter;
// std::string str= oss.str();
// return str;
// }
LARegister::LARegister(RISCVType _type, std::string _name)
: Register(_type,_name), regnum(LAReg::hi) {}
LARegister::LARegister(RISCVType _type, std::string _name, LAReg _regenum)
: Register(_type,_name), regnum(_regenum) {}
LARegister::LARegister(RISCVType _type, std::string _name, Register *_vreg)
: Register(_type,_name), regnum(LAReg::lo), vreg(_vreg) {}
Register*& LARegister::GetVreg() { return vreg; }
void LARegister::SetReg(PhyRegister* &_reg) { vreg = _reg; }
void LARegister::print() {
// todo
std::cout << "%" << magic_enum::enum_name(regnum);
std::cout << "(" << rname << ")";
if (vreg != nullptr) {
std::cout << "(";
vreg->print();
std::cout << ")";
// std::cout << ")" << std::endl;
}
}
RegisterList::RegisterList() {
using PhyReg=PhyRegister::PhyReg;
// reglist_int
// t0 & t1 will not be regalloced, and it is real temp register
reglist_int.push_back(PhyRegister::GetPhyReg(PhyReg::t2));
PhyReg regenum = PhyReg::a0;
auto PushReg_Added = [&](std::vector<PhyRegister*>& list) {
list.push_back(PhyRegister::GetPhyReg(regenum));
regenum = PhyReg(regenum + 1);
};
while(regenum<=PhyReg::a7) {
PushReg_Added(reglist_int);
}
regenum = PhyReg::t3;
while(regenum<=PhyReg::t6) {
PushReg_Added(reglist_int);
}
reglist_int.push_back(PhyRegister::GetPhyReg(PhyReg::s1));
regenum = PhyReg::s2;
while(regenum<=PhyReg::s11) {
PushReg_Added(reglist_int);
}
// reglist_float
regenum = PhyReg::ft0;
while(regenum<=PhyReg::ft7) {
PushReg_Added(reglist_float);
}
regenum = PhyReg::fa0;
while(regenum<=PhyReg::fa7) {
PushReg_Added(reglist_float);
}
regenum = PhyReg::ft8;
while(regenum<=PhyReg::ft11) {
PushReg_Added(reglist_float);
}
regenum = PhyReg::fs0;
while(regenum<=PhyReg::fs1) {
PushReg_Added(reglist_float);
}
regenum = PhyReg::fs2;
while(regenum<=PhyReg::fs11) {
PushReg_Added(reglist_float);
}
// reglist_test
regenum = PhyReg::a0;
while(regenum<=PhyReg::a3) {
PushReg_Added(reglist_test);
}
// reglist_caller
reglist_caller.push_back(PhyRegister::GetPhyReg(PhyReg::t2));
regenum = PhyReg::a0;
while(regenum<=PhyReg::a7) {
PushReg_Added(reglist_caller);
}
regenum = PhyReg::t3;
while(regenum<=PhyReg::t6) {
PushReg_Added(reglist_caller);
}
regenum = PhyReg::ft0;
while(regenum <= PhyReg::ft7) {
PushReg_Added(reglist_caller);
}
regenum = PhyReg::fa0;
while(regenum <= PhyReg::fa7) {
PushReg_Added(reglist_caller);
}
regenum = PhyReg::ft8;
while(regenum <= PhyReg::ft11) {
PushReg_Added(reglist_caller);
}
}
RegisterList& RegisterList::GetPhyRegList() {
static RegisterList reglist;
return reglist;
}
std::vector<PhyRegister*>& RegisterList::GetReglistInt() {return reglist_int;}
std::vector<PhyRegister*>& RegisterList::GetReglistFloat() {return reglist_float;}
std::vector<PhyRegister*>& RegisterList::GetReglistTest() {return reglist_test;}
std::vector<PhyRegister*>& RegisterList::GetReglistCaller() {return reglist_caller;}