regfile.hh revision 2980:eab855f06b79
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Kevin Lim 29 * Gabe Black 30 */ 31 32#ifndef __CPU_O3_REGFILE_HH__ 33#define __CPU_O3_REGFILE_HH__ 34 35#include "arch/isa_traits.hh" 36#include "arch/types.hh" 37#include "base/trace.hh" 38#include "config/full_system.hh" 39#include "cpu/o3/comm.hh" 40#include "sim/faults.hh" 41 42#if FULL_SYSTEM 43#include "kern/kernel_stats.hh" 44 45#endif 46 47#include <vector> 48 49/** 50 * Simple physical register file class. 51 * Right now this is specific to Alpha until we decide if/how to make things 52 * generic enough to support other ISAs. 53 */ 54template <class Impl> 55class PhysRegFile 56{ 57 protected: 58 typedef TheISA::IntReg IntReg; 59 typedef TheISA::FloatReg FloatReg; 60 typedef TheISA::FloatRegBits FloatRegBits; 61 typedef TheISA::MiscRegFile MiscRegFile; 62 typedef TheISA::MiscReg MiscReg; 63 64 typedef union { 65 FloatReg d; 66 FloatRegBits q; 67 } PhysFloatReg; 68 69 // Note that most of the definitions of the IntReg, FloatReg, etc. exist 70 // within the Impl/ISA class and not within this PhysRegFile class. 71 72 // Will make these registers public for now, but they probably should 73 // be private eventually with some accessor functions. 74 public: 75 typedef typename Impl::O3CPU O3CPU; 76 77 /** 78 * Constructs a physical register file with the specified amount of 79 * integer and floating point registers. 80 */ 81 PhysRegFile(unsigned _numPhysicalIntRegs, 82 unsigned _numPhysicalFloatRegs); 83 84 //Everything below should be pretty well identical to the normal 85 //register file that exists within AlphaISA class. 86 //The duplication is unfortunate but it's better than having 87 //different ways to access certain registers. 88 89 /** Reads an integer register. */ 90 uint64_t readIntReg(PhysRegIndex reg_idx) 91 { 92 assert(reg_idx < numPhysicalIntRegs); 93 94 DPRINTF(IEW, "RegFile: Access to int register %i, has data " 95 "%#x\n", int(reg_idx), intRegFile[reg_idx]); 96 return intRegFile[reg_idx]; 97 } 98 99 FloatReg readFloatReg(PhysRegIndex reg_idx, int width) 100 { 101 // Remove the base Float reg dependency. 102 reg_idx = reg_idx - numPhysicalIntRegs; 103 104 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 105 106 FloatReg floatReg = floatRegFile[reg_idx].d; 107 108 DPRINTF(IEW, "RegFile: Access to %d byte float register %i, has " 109 "data %#x\n", int(reg_idx), floatRegFile[reg_idx].q); 110 111 return floatReg; 112 } 113 114 /** Reads a floating point register (double precision). */ 115 FloatReg readFloatReg(PhysRegIndex reg_idx) 116 { 117 // Remove the base Float reg dependency. 118 reg_idx = reg_idx - numPhysicalIntRegs; 119 120 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 121 122 FloatReg floatReg = floatRegFile[reg_idx].d; 123 124 DPRINTF(IEW, "RegFile: Access to float register %i, has " 125 "data %#x\n", int(reg_idx), floatRegFile[reg_idx].q); 126 127 return floatReg; 128 } 129 130 /** Reads a floating point register as an integer. */ 131 FloatRegBits readFloatRegBits(PhysRegIndex reg_idx, int width) 132 { 133 // Remove the base Float reg dependency. 134 reg_idx = reg_idx - numPhysicalIntRegs; 135 136 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 137 138 FloatRegBits floatRegBits = floatRegFile[reg_idx].q; 139 140 DPRINTF(IEW, "RegFile: Access to float register %i as int, " 141 "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits); 142 143 return floatRegBits; 144 } 145 146 FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) 147 { 148 // Remove the base Float reg dependency. 149 reg_idx = reg_idx - numPhysicalIntRegs; 150 151 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 152 153 FloatRegBits floatRegBits = floatRegFile[reg_idx].q; 154 155 DPRINTF(IEW, "RegFile: Access to float register %i as int, " 156 "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits); 157 158 return floatRegBits; 159 } 160 161 /** Sets an integer register to the given value. */ 162 void setIntReg(PhysRegIndex reg_idx, uint64_t val) 163 { 164 assert(reg_idx < numPhysicalIntRegs); 165 166 DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n", 167 int(reg_idx), val); 168 169 if (reg_idx != TheISA::ZeroReg) 170 intRegFile[reg_idx] = val; 171 } 172 173 /** Sets a single precision floating point register to the given value. */ 174 void setFloatReg(PhysRegIndex reg_idx, FloatReg val, int width) 175 { 176 // Remove the base Float reg dependency. 177 reg_idx = reg_idx - numPhysicalIntRegs; 178 179 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 180 181 DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", 182 int(reg_idx), (uint64_t)val); 183 184 if (reg_idx != TheISA::ZeroReg) 185 floatRegFile[reg_idx].d = val; 186 } 187 188 /** Sets a double precision floating point register to the given value. */ 189 void setFloatReg(PhysRegIndex reg_idx, FloatReg val) 190 { 191 // Remove the base Float reg dependency. 192 reg_idx = reg_idx - numPhysicalIntRegs; 193 194 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 195 196 DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", 197 int(reg_idx), (uint64_t)val); 198 199 if (reg_idx != TheISA::ZeroReg) 200 floatRegFile[reg_idx].d = val; 201 } 202 203 /** Sets a floating point register to the given integer value. */ 204 void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val, int width) 205 { 206 // Remove the base Float reg dependency. 207 reg_idx = reg_idx - numPhysicalIntRegs; 208 209 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 210 211 DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", 212 int(reg_idx), (uint64_t)val); 213 214 floatRegFile[reg_idx].q = val; 215 } 216 217 void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val) 218 { 219 // Remove the base Float reg dependency. 220 reg_idx = reg_idx - numPhysicalIntRegs; 221 222 assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs); 223 224 DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n", 225 int(reg_idx), (uint64_t)val); 226 227 floatRegFile[reg_idx].q = val; 228 } 229 230 MiscReg readMiscReg(int misc_reg, unsigned thread_id) 231 { 232 return miscRegs[thread_id].readReg(misc_reg); 233 } 234 235 MiscReg readMiscRegWithEffect(int misc_reg, Fault &fault, 236 unsigned thread_id) 237 { 238 return miscRegs[thread_id].readRegWithEffect(misc_reg, fault, 239 cpu->tcBase(thread_id)); 240 } 241 242 Fault setMiscReg(int misc_reg, const MiscReg &val, unsigned thread_id) 243 { 244 return miscRegs[thread_id].setReg(misc_reg, val); 245 } 246 247 Fault setMiscRegWithEffect(int misc_reg, const MiscReg &val, 248 unsigned thread_id) 249 { 250 return miscRegs[thread_id].setRegWithEffect(misc_reg, val, 251 cpu->tcBase(thread_id)); 252 } 253 254#if FULL_SYSTEM 255 int readIntrFlag() { return intrflag; } 256 /** Sets an interrupt flag. */ 257 void setIntrFlag(int val) { intrflag = val; } 258#endif 259 260 public: 261 /** (signed) integer register file. */ 262 IntReg *intRegFile; 263 264 /** Floating point register file. */ 265 PhysFloatReg *floatRegFile; 266 267 /** Miscellaneous register file. */ 268 MiscRegFile miscRegs[Impl::MaxThreads]; 269 270#if FULL_SYSTEM 271 private: 272 int intrflag; // interrupt flag 273#endif 274 275 private: 276 /** CPU pointer. */ 277 O3CPU *cpu; 278 279 public: 280 /** Sets the CPU pointer. */ 281 void setCPU(O3CPU *cpu_ptr) { cpu = cpu_ptr; } 282 283 /** Number of physical integer registers. */ 284 unsigned numPhysicalIntRegs; 285 /** Number of physical floating point registers. */ 286 unsigned numPhysicalFloatRegs; 287}; 288 289template <class Impl> 290PhysRegFile<Impl>::PhysRegFile(unsigned _numPhysicalIntRegs, 291 unsigned _numPhysicalFloatRegs) 292 : numPhysicalIntRegs(_numPhysicalIntRegs), 293 numPhysicalFloatRegs(_numPhysicalFloatRegs) 294{ 295 intRegFile = new IntReg[numPhysicalIntRegs]; 296 floatRegFile = new PhysFloatReg[numPhysicalFloatRegs]; 297 298 for (int i = 0; i < Impl::MaxThreads; ++i) { 299 miscRegs[i].clear(); 300 } 301 302 memset(intRegFile, 0, sizeof(IntReg) * numPhysicalIntRegs); 303 memset(floatRegFile, 0, sizeof(PhysFloatReg) * numPhysicalFloatRegs); 304} 305 306#endif 307