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