regfile.hh revision 10935:acd48ddd725f
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
68    /** Floating point register file. */
69    std::vector<PhysFloatReg> floatRegFile;
70
71    /** Condition-code register file. */
72    std::vector<CCReg> ccRegFile;
73
74    /**
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.
87     */
88    unsigned baseFloatRegIndex;
89
90    /**
91     * The first condition-code physical register index.  The
92     * condition-code registers follow the floating-point registers.
93     */
94    unsigned baseCCRegIndex;
95
96    /** Total number of physical registers. */
97    unsigned totalNumRegs;
98
99  public:
100    /**
101     * Constructs a physical register file with the specified amount of
102     * integer and floating point registers.
103     */
104    PhysRegFile(unsigned _numPhysicalIntRegs,
105                unsigned _numPhysicalFloatRegs,
106                unsigned _numPhysicalCCRegs);
107
108    /**
109     * Destructor to free resources
110     */
111    ~PhysRegFile() {}
112
113    /** Initialize the free list */
114    void initFreeList(UnifiedFreeList *freeList);
115
116    /** @return the number of integer physical registers. */
117    unsigned numIntPhysRegs() const { return baseFloatRegIndex; }
118
119    /** @return the number of floating-point physical registers. */
120    unsigned numFloatPhysRegs() const
121    { return baseCCRegIndex - baseFloatRegIndex; }
122
123    /** @return the number of condition-code physical registers. */
124    unsigned numCCPhysRegs() const
125    { return totalNumRegs - baseCCRegIndex; }
126
127    /** @return the total number of physical registers. */
128    unsigned totalNumPhysRegs() const { return totalNumRegs; }
129
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;
137    }
138
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
157    /** Reads an integer register. */
158    uint64_t readIntReg(PhysRegIndex reg_idx) const
159    {
160        assert(isIntPhysReg(reg_idx));
161
162        DPRINTF(IEW, "RegFile: Access to int register %i, has data "
163                "%#x\n", int(reg_idx), intRegFile[reg_idx]);
164        return intRegFile[reg_idx];
165    }
166
167    /** Reads a floating point register (double precision). */
168    FloatReg readFloatReg(PhysRegIndex reg_idx) const
169    {
170        assert(isFloatPhysReg(reg_idx));
171
172        // Remove the base Float reg dependency.
173        PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
174
175        DPRINTF(IEW, "RegFile: Access to float register %i, has "
176                "data %#x\n", int(reg_idx), floatRegFile[reg_offset].q);
177
178        return floatRegFile[reg_offset].d;
179    }
180
181    FloatRegBits readFloatRegBits(PhysRegIndex reg_idx) const
182    {
183        assert(isFloatPhysReg(reg_idx));
184
185        // Remove the base Float reg dependency.
186        PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
187
188        FloatRegBits floatRegBits = floatRegFile[reg_offset].q;
189
190        DPRINTF(IEW, "RegFile: Access to float register %i as int, "
191                "has data %#x\n", int(reg_idx), (uint64_t)floatRegBits);
192
193        return floatRegBits;
194    }
195
196    /** Reads a condition-code register. */
197    CCReg readCCReg(PhysRegIndex reg_idx)
198    {
199        assert(isCCPhysReg(reg_idx));
200
201        // Remove the base CC reg dependency.
202        PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
203
204        DPRINTF(IEW, "RegFile: Access to cc register %i, has "
205                "data %#x\n", int(reg_idx), ccRegFile[reg_offset]);
206
207        return ccRegFile[reg_offset];
208    }
209
210    /** Sets an integer register to the given value. */
211    void setIntReg(PhysRegIndex reg_idx, uint64_t val)
212    {
213        assert(isIntPhysReg(reg_idx));
214
215        DPRINTF(IEW, "RegFile: Setting int register %i to %#x\n",
216                int(reg_idx), val);
217
218        if (reg_idx != TheISA::ZeroReg)
219            intRegFile[reg_idx] = val;
220    }
221
222    /** Sets a double precision floating point register to the given value. */
223    void setFloatReg(PhysRegIndex reg_idx, FloatReg val)
224    {
225        assert(isFloatPhysReg(reg_idx));
226
227        // Remove the base Float reg dependency.
228        PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
229
230        DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
231                int(reg_idx), (uint64_t)val);
232
233#if THE_ISA == ALPHA_ISA
234        if (reg_offset != TheISA::ZeroReg)
235#endif
236            floatRegFile[reg_offset].d = val;
237    }
238
239    void setFloatRegBits(PhysRegIndex reg_idx, FloatRegBits val)
240    {
241        assert(isFloatPhysReg(reg_idx));
242
243        // Remove the base Float reg dependency.
244        PhysRegIndex reg_offset = reg_idx - baseFloatRegIndex;
245
246        DPRINTF(IEW, "RegFile: Setting float register %i to %#x\n",
247                int(reg_idx), (uint64_t)val);
248
249        floatRegFile[reg_offset].q = val;
250    }
251
252    /** Sets a condition-code register to the given value. */
253    void setCCReg(PhysRegIndex reg_idx, CCReg val)
254    {
255        assert(isCCPhysReg(reg_idx));
256
257        // Remove the base CC reg dependency.
258        PhysRegIndex reg_offset = reg_idx - baseCCRegIndex;
259
260        DPRINTF(IEW, "RegFile: Setting cc register %i to %#x\n",
261                int(reg_idx), (uint64_t)val);
262
263        ccRegFile[reg_offset] = val;
264    }
265};
266
267
268#endif //__CPU_O3_REGFILE_HH__
269