regfile.hh revision 2665:a124942bacb8
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_CPU_REGFILE_HH__
33#define __CPU_O3_CPU_REGFILE_HH__
34
35// @todo: Destructor
36
37#include "arch/isa_traits.hh"
38#include "arch/faults.hh"
39#include "base/trace.hh"
40#include "config/full_system.hh"
41#include "cpu/o3/comm.hh"
42
43#if FULL_SYSTEM
44#include "kern/kernel_stats.hh"
45
46#endif
47
48// This really only depends on the ISA, and not the Impl.  It might be nicer
49// to see if I can make it depend on nothing...
50// Things that are in the ifdef FULL_SYSTEM are pretty dependent on the ISA,
51// and should go in the AlphaFullCPU.
52
53template <class Impl>
54class PhysRegFile
55{
56  protected:
57    typedef TheISA::IntReg IntReg;
58    typedef TheISA::FloatReg FloatReg;
59    typedef TheISA::MiscRegFile MiscRegFile;
60    typedef TheISA::MiscReg MiscReg;
61
62    //Note that most of the definitions of the IntReg, FloatReg, etc. exist
63    //within the Impl/ISA class and not within this PhysRegFile class.
64
65    //Will need some way to allow stuff like swap_palshadow to access the
66    //correct registers.  Might require code changes to swap_palshadow and
67    //other execution contexts.
68
69    //Will make these registers public for now, but they probably should
70    //be private eventually with some accessor functions.
71  public:
72    typedef typename Impl::FullCPU FullCPU;
73
74    PhysRegFile(unsigned _numPhysicalIntRegs,
75                unsigned _numPhysicalFloatRegs);
76
77    //Everything below should be pretty well identical to the normal
78    //register file that exists within AlphaISA class.
79    //The duplication is unfortunate but it's better than having
80    //different ways to access certain registers.
81
82    //Add these in later when everything else is in place
83//    void serialize(std::ostream &os);
84//    void unserialize(Checkpoint *cp, const std::string &section);
85
86    uint64_t readIntReg(PhysRegIndex reg_idx)
87    {
88        assert(reg_idx < numPhysicalIntRegs);
89
90        DPRINTF(IEW, "RegFile: Access to int register %i, has data "
91                "%i\n", int(reg_idx), intRegFile[reg_idx]);
92        return intRegFile[reg_idx];
93    }
94
95    FloatReg readFloatReg(PhysRegIndex reg_idx, int width)
96    {
97        // Remove the base Float reg dependency.
98        reg_idx = reg_idx - numPhysicalIntRegs;
99
100        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
101
102        FloatReg floatReg = floatRegFile.readReg(reg_idx, width);
103
104        DPRINTF(IEW, "RegFile: Access to %d byte float register %i, has "
105                "data %8.8d\n", int(reg_idx), (double)floatReg);
106
107        return floatReg;
108    }
109
110    FloatReg readFloatReg(PhysRegIndex reg_idx)
111    {
112        // Remove the base Float reg dependency.
113        reg_idx = reg_idx - numPhysicalIntRegs;
114
115        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
116
117        FloatReg floatReg = floatRegFile.readReg(reg_idx);
118
119        DPRINTF(IEW, "RegFile: Access to float register %i, has "
120                "data %8.8d\n", int(reg_idx), (double)floatReg);
121
122        return floatReg;
123    }
124
125    FloatRegBits readFloatRegBits(PhysRegIndex reg_idx, int width)
126    {
127        // Remove the base Float reg dependency.
128        reg_idx = reg_idx - numPhysicalIntRegs;
129
130        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
131
132        FloatRegBits floatRegBits = floatRegFile.readRegBits(reg_idx, width);
133
134        DPRINTF(IEW, "RegFile: Access to %d byte float register %i as int, "
135                "has data %lli\n", int(reg_idx), (uint64_t)floatRegBits);
136
137        return floatRegBits;
138    }
139
140    FloatRegBits readFloatRegBits(PhysRegIndex reg_idx)
141    {
142        // Remove the base Float reg dependency.
143        reg_idx = reg_idx - numPhysicalIntRegs;
144
145        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
146
147        FloatRegBits floatRegBits = floatRegFile.readRegBits(reg_idx);
148
149        DPRINTF(IEW, "RegFile: Access to float register %i as int, "
150                "has data %lli\n", int(reg_idx), (uint64_t)floatRegBits);
151
152        return floatRegBits;
153    }
154
155    void setIntReg(PhysRegIndex reg_idx, uint64_t val)
156    {
157        assert(reg_idx < numPhysicalIntRegs);
158
159        DPRINTF(IEW, "RegFile: Setting int register %i to %lli\n",
160                int(reg_idx), val);
161
162        intRegFile[reg_idx] = val;
163    }
164
165    void setFloatReg(PhysRegIndex reg_idx, FloatReg val, int width)
166    {
167        // Remove the base Float reg dependency.
168        reg_idx = reg_idx - numPhysicalIntRegs;
169
170        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
171
172        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8d\n",
173                int(reg_idx), (double)val);
174
175        floatRegFile.setReg(reg_idx, val, width);
176    }
177
178    void setFloatReg(PhysRegIndex reg_idx, FloatReg val)
179    {
180        // Remove the base Float reg dependency.
181        reg_idx = reg_idx - numPhysicalIntRegs;
182
183        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
184
185        DPRINTF(IEW, "RegFile: Setting float register %i to %8.8d\n",
186                int(reg_idx), (double)val);
187
188        floatRegFile.setReg(reg_idx, val);
189    }
190
191    void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val, int width)
192    {
193        // Remove the base Float reg dependency.
194        reg_idx = reg_idx - numPhysicalIntRegs;
195
196        assert(reg_idx < numPhysicalFloatRegs + numPhysicalIntRegs);
197
198        DPRINTF(IEW, "RegFile: Setting float register %i to %lli\n",
199                int(reg_idx), (uint64_t)val);
200
201        floatRegFile.setRegBits(reg_idx, val, width);
202    }
203
204    void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val)
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 %lli\n",
212                int(reg_idx), (uint64_t)val);
213
214        floatRegFile.setRegBits(reg_idx, val);
215    }
216
217    uint64_t readPC()
218    {
219        return pc;
220    }
221
222    void setPC(uint64_t val)
223    {
224        pc = val;
225    }
226
227    void setNextPC(uint64_t val)
228    {
229        npc = val;
230    }
231
232    //Consider leaving this stuff and below in some implementation specific
233    //file as opposed to the general register file.  Or have a derived class.
234    MiscReg readMiscReg(int misc_reg)
235    {
236        // Dummy function for now.
237        // @todo: Fix this once proxy XC is used.
238        return 0;
239    }
240
241    Fault setMiscReg(int misc_reg, const MiscReg &val)
242    {
243        // Dummy function for now.
244        // @todo: Fix this once proxy XC is used.
245        return NoFault;
246    }
247
248#if FULL_SYSTEM
249    int readIntrFlag() { return intrflag; }
250    void setIntrFlag(int val) { intrflag = val; }
251#endif
252
253    // These should be private eventually, but will be public for now
254    // so that I can hack around the initregs issue.
255  public:
256    /** (signed) integer register file. */
257    IntReg *intRegFile;
258
259    /** Floating point register file. */
260    FloatReg *floatRegFile;
261
262    /** Miscellaneous register file. */
263    MiscRegFile miscRegs;
264
265    /** Program counter. */
266    Addr pc;
267
268    /** Next-cycle program counter. */
269    Addr npc;
270
271#if FULL_SYSTEM
272  private:
273    // This is ISA specifc stuff; remove it eventually once ISAImpl is used
274//    IntReg palregs[NumIntRegs];	// PAL shadow registers
275    int intrflag;			// interrupt flag
276    bool pal_shadow;		// using pal_shadow registers
277#endif
278
279  private:
280    FullCPU *cpu;
281
282  public:
283    void setCPU(FullCPU *cpu_ptr) { cpu = cpu_ptr; }
284
285    unsigned numPhysicalIntRegs;
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 FloatReg[numPhysicalFloatRegs];
297
298    memset(intRegFile, 0, sizeof(*intRegFile));
299    memset(floatRegFile, 0, sizeof(*floatRegFile));
300}
301
302#endif // __CPU_O3_CPU_REGFILE_HH__
303