reg_class.hh (13762:36d5a1d9f5e6) reg_class.hh (14025:3a133070aa2e)
1/*
1/*
2 * Copyright (c) 2016-2017 ARM Limited
2 * Copyright (c) 2016-2018 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 61 unchanged lines hidden (view full) ---

72const int NumRegClasses = MiscRegClass + 1;
73
74/** Register ID: describe an architectural register with its class and index.
75 * This structure is used instead of just the register index to disambiguate
76 * between different classes of registers. For example, a integer register with
77 * index 3 is represented by Regid(IntRegClass, 3).
78 */
79class RegId {
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated

--- 61 unchanged lines hidden (view full) ---

72const int NumRegClasses = MiscRegClass + 1;
73
74/** Register ID: describe an architectural register with its class and index.
75 * This structure is used instead of just the register index to disambiguate
76 * between different classes of registers. For example, a integer register with
77 * index 3 is represented by Regid(IntRegClass, 3).
78 */
79class RegId {
80 private:
80 protected:
81 static const char* regClassStrings[];
82 RegClass regClass;
83 RegIndex regIdx;
84 ElemIndex elemIdx;
85 static constexpr size_t Scale = TheISA::NumVecElemPerVecReg;
81 static const char* regClassStrings[];
82 RegClass regClass;
83 RegIndex regIdx;
84 ElemIndex elemIdx;
85 static constexpr size_t Scale = TheISA::NumVecElemPerVecReg;
86 int numPinnedWrites;
87
86 friend struct std::hash<RegId>;
88 friend struct std::hash<RegId>;
89
87 public:
88 RegId() : regClass(IntRegClass), regIdx(0), elemIdx(-1) {}
89 RegId(RegClass reg_class, RegIndex reg_idx)
90 public:
91 RegId() : regClass(IntRegClass), regIdx(0), elemIdx(-1) {}
92 RegId(RegClass reg_class, RegIndex reg_idx)
90 : regClass(reg_class), regIdx(reg_idx), elemIdx(-1)
93 : regClass(reg_class), regIdx(reg_idx), elemIdx(-1),
94 numPinnedWrites(0)
91 {
92 panic_if(regClass == VecElemClass,
93 "Creating vector physical index w/o element index");
94 }
95
96 explicit RegId(RegClass reg_class, RegIndex reg_idx, ElemIndex elem_idx)
95 {
96 panic_if(regClass == VecElemClass,
97 "Creating vector physical index w/o element index");
98 }
99
100 explicit RegId(RegClass reg_class, RegIndex reg_idx, ElemIndex elem_idx)
97 : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx)
101 : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx),
102 numPinnedWrites(0)
98 {
99 panic_if(regClass != VecElemClass,
100 "Creating non-vector physical index w/ element index");
101 }
102
103 bool operator==(const RegId& that) const {
104 return regClass == that.classValue() && regIdx == that.index()
105 && elemIdx == that.elemIndex();

--- 91 unchanged lines hidden (view full) ---

197
198 /** Elem accessor */
199 const RegIndex& elemIndex() const { return elemIdx; }
200 /** Class accessor */
201 const RegClass& classValue() const { return regClass; }
202 /** Return a const char* with the register class name. */
203 const char* className() const { return regClassStrings[regClass]; }
204
103 {
104 panic_if(regClass != VecElemClass,
105 "Creating non-vector physical index w/ element index");
106 }
107
108 bool operator==(const RegId& that) const {
109 return regClass == that.classValue() && regIdx == that.index()
110 && elemIdx == that.elemIndex();

--- 91 unchanged lines hidden (view full) ---

202
203 /** Elem accessor */
204 const RegIndex& elemIndex() const { return elemIdx; }
205 /** Class accessor */
206 const RegClass& classValue() const { return regClass; }
207 /** Return a const char* with the register class name. */
208 const char* className() const { return regClassStrings[regClass]; }
209
210 int getNumPinnedWrites() const { return numPinnedWrites; }
211 void setNumPinnedWrites(int num_writes) { numPinnedWrites = num_writes; }
212
205 friend std::ostream&
206 operator<<(std::ostream& os, const RegId& rid) {
207 return os << rid.className() << "{" << rid.index() << "}";
208 }
209};
210
211/** Physical register index type.
212 * Although the Impl might be a better for this, but there are a few classes
213 * that need this typedef yet are not templated on the Impl.
214 */
215using PhysRegIndex = short int;
216
217/** Physical register ID.
218 * Like a register ID but physical. The inheritance is private because the
219 * only relationship between this types is functional, and it is done to
220 * prevent code replication. */
221class PhysRegId : private RegId {
222 private:
223 PhysRegIndex flatIdx;
213 friend std::ostream&
214 operator<<(std::ostream& os, const RegId& rid) {
215 return os << rid.className() << "{" << rid.index() << "}";
216 }
217};
218
219/** Physical register index type.
220 * Although the Impl might be a better for this, but there are a few classes
221 * that need this typedef yet are not templated on the Impl.
222 */
223using PhysRegIndex = short int;
224
225/** Physical register ID.
226 * Like a register ID but physical. The inheritance is private because the
227 * only relationship between this types is functional, and it is done to
228 * prevent code replication. */
229class PhysRegId : private RegId {
230 private:
231 PhysRegIndex flatIdx;
232 int numPinnedWritesToComplete;
233 bool pinned;
224
225 public:
234
235 public:
226 explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1) {}
236 explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1),
237 numPinnedWritesToComplete(0)
238 {}
227
228 /** Scalar PhysRegId constructor. */
229 explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
230 PhysRegIndex _flatIdx)
239
240 /** Scalar PhysRegId constructor. */
241 explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
242 PhysRegIndex _flatIdx)
231 : RegId(_regClass, _regIdx), flatIdx(_flatIdx)
243 : RegId(_regClass, _regIdx), flatIdx(_flatIdx),
244 numPinnedWritesToComplete(0), pinned(false)
232 {}
233
234 /** Vector PhysRegId constructor (w/ elemIndex). */
235 explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
236 ElemIndex elem_idx, PhysRegIndex flat_idx)
245 {}
246
247 /** Vector PhysRegId constructor (w/ elemIndex). */
248 explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx,
249 ElemIndex elem_idx, PhysRegIndex flat_idx)
237 : RegId(_regClass, _regIdx, elem_idx), flatIdx(flat_idx) { }
250 : RegId(_regClass, _regIdx, elem_idx), flatIdx(flat_idx),
251 numPinnedWritesToComplete(0), pinned(false)
252 {}
238
239 /** Visible RegId methods */
240 /** @{ */
241 using RegId::index;
242 using RegId::classValue;
243 using RegId::isZeroReg;
244 using RegId::className;
245 using RegId::elemIndex;

--- 44 unchanged lines hidden (view full) ---

290 bool isFixedMapping() const
291 {
292 return !isRenameable();
293 }
294
295 /** Flat index accessor */
296 const PhysRegIndex& flatIndex() const { return flatIdx; }
297
253
254 /** Visible RegId methods */
255 /** @{ */
256 using RegId::index;
257 using RegId::classValue;
258 using RegId::isZeroReg;
259 using RegId::className;
260 using RegId::elemIndex;

--- 44 unchanged lines hidden (view full) ---

305 bool isFixedMapping() const
306 {
307 return !isRenameable();
308 }
309
310 /** Flat index accessor */
311 const PhysRegIndex& flatIndex() const { return flatIdx; }
312
298 static PhysRegId elemId(const PhysRegId* vid, ElemIndex elem)
313 static PhysRegId elemId(PhysRegId* vid, ElemIndex elem)
299 {
300 assert(vid->isVectorPhysReg());
301 return PhysRegId(VecElemClass, vid->index(), elem);
302 }
314 {
315 assert(vid->isVectorPhysReg());
316 return PhysRegId(VecElemClass, vid->index(), elem);
317 }
318
319 int getNumPinnedWrites() const { return numPinnedWrites; }
320
321 void setNumPinnedWrites(int numWrites)
322 {
323 // An instruction with a pinned destination reg can get
324 // squashed. The numPinnedWrites counter may be zero when
325 // the squash happens but we need to know if the dest reg
326 // was pinned originally in order to reset counters properly
327 // for a possible re-rename using the same physical reg (which
328 // may be required in case of a mem access order violation).
329 pinned = (numWrites != 0);
330 numPinnedWrites = numWrites;
331 }
332
333 void decrNumPinnedWrites() { --numPinnedWrites; }
334 void incrNumPinnedWrites() { ++numPinnedWrites; }
335
336 bool isPinned() const { return pinned; }
337
338 int getNumPinnedWritesToComplete() const
339 {
340 return numPinnedWritesToComplete;
341 }
342
343 void setNumPinnedWritesToComplete(int numWrites)
344 {
345 numPinnedWritesToComplete = numWrites;
346 }
347
348 void decrNumPinnedWritesToComplete() { --numPinnedWritesToComplete; }
349 void incrNumPinnedWritesToComplete() { ++numPinnedWritesToComplete; }
303};
304
350};
351
305/** Constant pointer definition.
306 * PhysRegIds only need to be created once and then we can just share
307 * pointers */
308using PhysRegIdPtr = const PhysRegId*;
352using PhysRegIdPtr = PhysRegId*;
309
310namespace std
311{
312template<>
313struct hash<RegId>
314{
315 size_t operator()(const RegId& reg_id) const
316 {

--- 22 unchanged lines hidden ---
353
354namespace std
355{
356template<>
357struct hash<RegId>
358{
359 size_t operator()(const RegId& reg_id) const
360 {

--- 22 unchanged lines hidden ---