1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * Copyright (c) 2013 Advanced Micro Devices, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are 8 * met: redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer; 10 * redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution; 13 * neither the name of the copyright holders nor the names of its 14 * contributors may be used to endorse or promote products derived from 15 * this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * Authors: Kevin Lim 30 * Gabe Black 31 */ 32 33#ifndef __CPU_O3_REGFILE_HH__ 34#define __CPU_O3_REGFILE_HH__ 35 36#include <vector> 37 38#include "arch/isa_traits.hh" 39#include "arch/kernel_stats.hh" 40#include "arch/types.hh" 41#include "base/trace.hh" 42#include "config/the_isa.hh" 43#include "cpu/o3/comm.hh" 44#include "debug/IEW.hh" 45 46class UnifiedFreeList; 47 48/** 49 * Simple physical register file class. 50 */ 51class PhysRegFile 52{ 53 private: 54 55 typedef TheISA::IntReg IntReg; 56 typedef TheISA::FloatReg FloatReg; 57 typedef TheISA::FloatRegBits FloatRegBits; 58 typedef TheISA::CCReg CCReg; 59 60 typedef union { 61 FloatReg d; 62 FloatRegBits q; 63 } PhysFloatReg; 64 65 /** Integer register file. */ 66 std::vector<IntReg> intRegFile;
|
67 std::vector<PhysRegId> intRegIds; |
68 69 /** Floating point register file. */ 70 std::vector<PhysFloatReg> floatRegFile;
|
71 std::vector<PhysRegId> floatRegIds; |
72 73 /** Condition-code register file. */ 74 std::vector<CCReg> ccRegFile;
|
75 std::vector<PhysRegId> ccRegIds; |
76
|
77 /** Misc Reg Ids */ 78 std::vector<PhysRegId> miscRegIds; 79 |
80 /**
|
75 * The first floating-point physical register index. The physical
76 * register file has a single continuous index space, with the
77 * initial indices mapping to the integer registers, followed
78 * immediately by the floating-point registers. Thus the first
79 * floating-point index is equal to the number of integer
80 * registers.
81 *
82 * Note that this internal organizational detail on how physical
83 * register file indices are ordered should *NOT* be exposed
84 * outside of this class. Other classes can use the is*PhysReg()
85 * methods to map from a physical register index to a class
86 * without knowing the internal structure of the index map.
|
81 * Number of physical general purpose registers |
82 */
|
88 unsigned baseFloatRegIndex;
|
83 unsigned numPhysicalIntRegs; |
84 85 /**
|
91 * The first condition-code physical register index. The
92 * condition-code registers follow the floating-point registers.
|
86 * Number of physical general purpose registers |
87 */
|
94 unsigned baseCCRegIndex;
|
88 unsigned numPhysicalFloatRegs; |
89
|
90 /** 91 * Number of physical general purpose registers 92 */ 93 unsigned numPhysicalCCRegs; 94 |
95 /** Total number of physical registers. */ 96 unsigned totalNumRegs; 97 98 public: 99 /** 100 * Constructs a physical register file with the specified amount of 101 * integer and floating point registers. 102 */ 103 PhysRegFile(unsigned _numPhysicalIntRegs, 104 unsigned _numPhysicalFloatRegs, 105 unsigned _numPhysicalCCRegs); 106 107 /** 108 * Destructor to free resources 109 */ 110 ~PhysRegFile() {} 111 112 /** Initialize the free list */ 113 void initFreeList(UnifiedFreeList *freeList); 114 115 /** @return the number of integer physical registers. */
|
117 unsigned numIntPhysRegs() const { return baseFloatRegIndex; }
|
116 unsigned numIntPhysRegs() const { return numPhysicalIntRegs; } |
117 118 /** @return the number of floating-point physical registers. */
|
120 unsigned numFloatPhysRegs() const
121 { return baseCCRegIndex - baseFloatRegIndex; }
|
119 unsigned numFloatPhysRegs() const { return numPhysicalFloatRegs; } |
120 121 /** @return the number of condition-code physical registers. */
|
124 unsigned numCCPhysRegs() const
125 { return totalNumRegs - baseCCRegIndex; }
|
122 unsigned numCCPhysRegs() const { return numPhysicalCCRegs; } |
123 124 /** @return the total number of physical registers. */ 125 unsigned totalNumPhysRegs() const { return totalNumRegs; } 126
|
130 /**
131 * @return true if the specified physical register index
132 * corresponds to an integer physical register.
133 */
134 bool isIntPhysReg(PhysRegIndex reg_idx) const
135 {
136 return 0 <= reg_idx && reg_idx < baseFloatRegIndex;
|
127 /** Gets a misc register PhysRegIdPtr. */ 128 PhysRegIdPtr getMiscRegId(RegIndex reg_idx) { 129 return &miscRegIds[reg_idx]; |
130 } 131
|
139 /**
140 * @return true if the specified physical register index
141 * corresponds to a floating-point physical register.
142 */
143 bool isFloatPhysReg(PhysRegIndex reg_idx) const
144 {
145 return (baseFloatRegIndex <= reg_idx && reg_idx < baseCCRegIndex);
146 }
147
148 /**
149 * Return true if the specified physical register index
150 * corresponds to a condition-code physical register.
151 */
152 bool isCCPhysReg(PhysRegIndex reg_idx)
153 {
154 return (baseCCRegIndex <= reg_idx && reg_idx < totalNumRegs);
155 }
156
|
132 /** Reads an integer register. */
|
158 uint64_t readIntReg(PhysRegIndex reg_idx) const
|
133 uint64_t readIntReg(PhysRegIdPtr phys_reg) const |
134 {
|
160 assert(isIntPhysReg(reg_idx));
|
135 assert(phys_reg->isIntPhysReg()); |
136 137 DPRINTF(IEW, "RegFile: Access to int register %i, has data "
|
163 "%#x\n", int(reg_idx), intRegFile[reg_idx]);
164 return intRegFile[reg_idx];
|
138 "%#x\n", phys_reg->regIdx, intRegFile[phys_reg->regIdx]); 139 return intRegFile[phys_reg->regIdx]; |
140 } 141 142 /** Reads a floating point register (double precision). */
|
168 FloatReg readFloatReg(PhysRegIndex reg_idx) const
|
143 FloatReg readFloatReg(PhysRegIdPtr phys_reg) const |
144 {
|
170 assert(isFloatPhysReg(reg_idx));
|
145 assert(phys_reg->isFloatPhysReg()); |
146
|
172 // Remove the base Float reg dependency.
173 PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
174
|
147 DPRINTF(IEW, "RegFile: Access to float register %i, has "
|
176 "data %#x\n", int(reg_idx), floatRegFile[reg_offset].q);
|
148 "data %#x\n", phys_reg->regIdx, 149 floatRegFile[phys_reg->regIdx].q); |
150
|
178 return floatRegFile[reg_offset].d;
|
151 return floatRegFile[phys_reg->regIdx].d; |
152 } 153
|
181 FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) const
|
154 FloatRegBits readFloatRegBits(PhysRegIdPtr phys_reg) const |
155 {
|
183 assert(isFloatPhysReg(reg_idx));
|
156 assert(phys_reg->isFloatPhysReg()); |
157
|
185 // Remove the base Float reg dependency.
186 PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
|
158 FloatRegBits floatRegBits = floatRegFile[phys_reg->regIdx].q; |
159
|
188 FloatRegBits floatRegBits = floatRegFile[reg_offset].q;
189
|
160 DPRINTF(IEW, "RegFile: Access to float register %i as int, "
|
191 "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits);
|
161 "has data %#x\n", phys_reg->regIdx, 162 (uint64_t)floatRegBits); |
163 164 return floatRegBits; 165 } 166 167 /** Reads a condition-code register. */
|
197 CCReg readCCReg(PhysRegIndex reg_idx)
|
168 CCReg readCCReg(PhysRegIdPtr phys_reg) |
169 {
|
199 assert(isCCPhysReg(reg_idx));
|
170 assert(phys_reg->isCCPhysReg()); |
171
|
201 // Remove the base CC reg dependency.
202 PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
203
|
172 DPRINTF(IEW, "RegFile: Access to cc register %i, has "
|
205 "data %#x\n", int(reg_idx), ccRegFile[reg_offset]);
|
173 "data %#x\n", phys_reg->regIdx, 174 ccRegFile[phys_reg->regIdx]); |
175
|
207 return ccRegFile[reg_offset];
|
176 return ccRegFile[phys_reg->regIdx]; |
177 } 178 179 /** Sets an integer register to the given value. */
|
211 void setIntReg(PhysRegIndex reg_idx, uint64_t val)
|
180 void setIntReg(PhysRegIdPtr phys_reg, uint64_t val) |
181 {
|
213 assert(isIntPhysReg(reg_idx));
|
182 assert(phys_reg->isIntPhysReg()); |
183 184 DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
|
216 int(reg_idx), val);
|
185 phys_reg->regIdx, val); |
186
|
218 if (reg_idx != TheISA::ZeroReg)
219 intRegFile[reg_idx] = val;
|
187 if (!phys_reg->isZeroReg()) 188 intRegFile[phys_reg->regIdx] = val; |
189 } 190 191 /** Sets a double precision floating point register to the given value. */
|
223 void setFloatReg(PhysRegIndex reg_idx, FloatReg val)
|
192 void setFloatReg(PhysRegIdPtr phys_reg, FloatReg val) |
193 {
|
225 assert(isFloatPhysReg(reg_idx));
|
194 assert(phys_reg->isFloatPhysReg()); |
195
|
227 // Remove the base Float reg dependency.
228 PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
229
|
196 DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
|
231 int(reg_idx), (uint64_t)val);
|
197 phys_reg->regIdx, (uint64_t)val); |
198
|
233#if THE_ISA == ALPHA_ISA
234 if (reg_offset != TheISA::ZeroReg)
235#endif
236 floatRegFile[reg_offset].d = val;
|
199 if (!phys_reg->isZeroReg()) 200 floatRegFile[phys_reg->regIdx].d = val; |
201 } 202
|
239 void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val)
|
203 void setFloatRegBits(PhysRegIdPtr phys_reg, FloatRegBits val) |
204 {
|
241 assert(isFloatPhysReg(reg_idx));
|
205 assert(phys_reg->isFloatPhysReg()); |
206
|
243 // Remove the base Float reg dependency.
244 PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
245
|
207 DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
|
247 int(reg_idx), (uint64_t)val);
|
208 phys_reg->regIdx, (uint64_t)val); |
209
|
249 floatRegFile[reg_offset].q = val;
|
210 floatRegFile[phys_reg->regIdx].q = val; |
211 } 212 213 /** Sets a condition-code register to the given value. */
|
253 void setCCReg(PhysRegIndex reg_idx, CCReg val)
|
214 void setCCReg(PhysRegIdPtr phys_reg, CCReg val) |
215 {
|
255 assert(isCCPhysReg(reg_idx));
|
216 assert(phys_reg->isCCPhysReg()); |
217
|
257 // Remove the base CC reg dependency.
258 PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
259
|
218 DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
|
261 int(reg_idx), (uint64_t)val);
|
219 phys_reg->regIdx, (uint64_t)val); |
220
|
263 ccRegFile[reg_offset] = val;
|
221 ccRegFile[phys_reg->regIdx] = val; |
222 } 223}; 224 225 226#endif //__CPU_O3_REGFILE_HH__
|