1/* |
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 { |
80 protected: |
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 |
88 friend struct std::hash<RegId>; |
89 |
90 public: 91 RegId() : regClass(IntRegClass), regIdx(0), elemIdx(-1) {} 92 RegId(RegClass reg_class, RegIndex reg_idx) |
93 : regClass(reg_class), regIdx(reg_idx), elemIdx(-1), 94 numPinnedWrites(0) |
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) |
101 : regClass(reg_class), regIdx(reg_idx), elemIdx(elem_idx), 102 numPinnedWrites(0) |
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 |
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; |
234 235 public: |
236 explicit PhysRegId() : RegId(IntRegClass, -1), flatIdx(-1), 237 numPinnedWritesToComplete(0) 238 {} |
239 240 /** Scalar PhysRegId constructor. */ 241 explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx, 242 PhysRegIndex _flatIdx) |
243 : RegId(_regClass, _regIdx), flatIdx(_flatIdx), 244 numPinnedWritesToComplete(0), pinned(false) |
245 {} 246 247 /** Vector PhysRegId constructor (w/ elemIndex). */ 248 explicit PhysRegId(RegClass _regClass, PhysRegIndex _regIdx, 249 ElemIndex elem_idx, PhysRegIndex flat_idx) |
250 : RegId(_regClass, _regIdx, elem_idx), flatIdx(flat_idx), 251 numPinnedWritesToComplete(0), pinned(false) 252 {} |
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 |
313 static PhysRegId elemId(PhysRegId* vid, ElemIndex elem) |
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; } |
350}; 351 |
352using PhysRegIdPtr = PhysRegId*; |
353 354namespace std 355{ 356template<> 357struct hash<RegId> 358{ 359 size_t operator()(const RegId& reg_id) const 360 { --- 22 unchanged lines hidden --- |