rename_map.cc revision 1689
111524Sdavid.guillen@arm.com/*
211524Sdavid.guillen@arm.com * Copyright (c) 2004-2005 The Regents of The University of Michigan
311524Sdavid.guillen@arm.com * All rights reserved.
411524Sdavid.guillen@arm.com *
511524Sdavid.guillen@arm.com * Redistribution and use in source and binary forms, with or without
611524Sdavid.guillen@arm.com * modification, are permitted provided that the following conditions are
711524Sdavid.guillen@arm.com * met: redistributions of source code must retain the above copyright
811524Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer;
911524Sdavid.guillen@arm.com * redistributions in binary form must reproduce the above copyright
1011524Sdavid.guillen@arm.com * notice, this list of conditions and the following disclaimer in the
1111524Sdavid.guillen@arm.com * documentation and/or other materials provided with the distribution;
1211524Sdavid.guillen@arm.com * neither the name of the copyright holders nor the names of its
1311524Sdavid.guillen@arm.com * contributors may be used to endorse or promote products derived from
1411524Sdavid.guillen@arm.com * this software without specific prior written permission.
1511524Sdavid.guillen@arm.com *
1611524Sdavid.guillen@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1711524Sdavid.guillen@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1811524Sdavid.guillen@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1911524Sdavid.guillen@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2011524Sdavid.guillen@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2111524Sdavid.guillen@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2211524Sdavid.guillen@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2311524Sdavid.guillen@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2411524Sdavid.guillen@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2511524Sdavid.guillen@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2611524Sdavid.guillen@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2711524Sdavid.guillen@arm.com */
2811524Sdavid.guillen@arm.com
2911524Sdavid.guillen@arm.com#include <vector>
3011524Sdavid.guillen@arm.com
3111524Sdavid.guillen@arm.com#include "cpu/beta_cpu/rename_map.hh"
3211524Sdavid.guillen@arm.com
3311524Sdavid.guillen@arm.comusing namespace std;
3411524Sdavid.guillen@arm.com
3511524Sdavid.guillen@arm.com// Todo: Consider making functions inline.  Avoid having things that are
3611524Sdavid.guillen@arm.com// using the zero register or misc registers from adding on the registers
3711524Sdavid.guillen@arm.com// to the free list.  Possibly remove the direct communication between
3811524Sdavid.guillen@arm.com// this and the freelist.  Considering making inline bool functions that
3911524Sdavid.guillen@arm.com// determine if the register is a logical int, logical fp, physical int,
4011524Sdavid.guillen@arm.com// physical fp, etc.
4111524Sdavid.guillen@arm.com
4211524Sdavid.guillen@arm.comSimpleRenameMap::SimpleRenameMap(unsigned _numLogicalIntRegs,
4311524Sdavid.guillen@arm.com                                 unsigned _numPhysicalIntRegs,
4411527Sdavid.guillen@arm.com                                 unsigned _numLogicalFloatRegs,
4511527Sdavid.guillen@arm.com                                 unsigned _numPhysicalFloatRegs,
4611527Sdavid.guillen@arm.com                                 unsigned _numMiscRegs,
4711527Sdavid.guillen@arm.com                                 RegIndex _intZeroReg,
4811527Sdavid.guillen@arm.com                                 RegIndex _floatZeroReg)
4911527Sdavid.guillen@arm.com    : numLogicalIntRegs(_numLogicalIntRegs),
5011527Sdavid.guillen@arm.com      numPhysicalIntRegs(_numPhysicalIntRegs),
5111527Sdavid.guillen@arm.com      numLogicalFloatRegs(_numLogicalFloatRegs),
5211527Sdavid.guillen@arm.com      numPhysicalFloatRegs(_numPhysicalFloatRegs),
5311527Sdavid.guillen@arm.com      numMiscRegs(_numMiscRegs),
5411527Sdavid.guillen@arm.com      intZeroReg(_intZeroReg),
5511524Sdavid.guillen@arm.com      floatZeroReg(_floatZeroReg)
5611524Sdavid.guillen@arm.com{
5711524Sdavid.guillen@arm.com    DPRINTF(Rename, "Rename: Creating rename map.  Phys: %i / %i, Float: "
5811524Sdavid.guillen@arm.com            "%i / %i.\n", numLogicalIntRegs, numPhysicalIntRegs,
5911524Sdavid.guillen@arm.com            numLogicalFloatRegs, numPhysicalFloatRegs);
6011524Sdavid.guillen@arm.com
6111524Sdavid.guillen@arm.com    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
6211524Sdavid.guillen@arm.com
6311524Sdavid.guillen@arm.com    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
6411524Sdavid.guillen@arm.com
6511524Sdavid.guillen@arm.com    //Create the rename maps, and their scoreboards.
6611524Sdavid.guillen@arm.com    intRenameMap = new RenameEntry[numLogicalIntRegs];
6711524Sdavid.guillen@arm.com    floatRenameMap = new RenameEntry[numLogicalRegs];
6811524Sdavid.guillen@arm.com
6911524Sdavid.guillen@arm.com    // Should combine this into one scoreboard.
7011524Sdavid.guillen@arm.com    intScoreboard.resize(numPhysicalIntRegs);
7111524Sdavid.guillen@arm.com    floatScoreboard.resize(numPhysicalRegs);
7211524Sdavid.guillen@arm.com    miscScoreboard.resize(numPhysicalRegs + numMiscRegs);
7311524Sdavid.guillen@arm.com
7411524Sdavid.guillen@arm.com    // Initialize the entries in the integer rename map to point to the
7511524Sdavid.guillen@arm.com    // physical registers of the same index, and consider each register
7611524Sdavid.guillen@arm.com    // ready until the first rename occurs.
7711524Sdavid.guillen@arm.com    for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
7811524Sdavid.guillen@arm.com    {
7911524Sdavid.guillen@arm.com        intRenameMap[index].physical_reg = index;
8011524Sdavid.guillen@arm.com        intScoreboard[index] = 1;
8111529Sandreas.sandberg@arm.com    }
8211529Sandreas.sandberg@arm.com
8311524Sdavid.guillen@arm.com    // Initialize the rest of the physical registers (the ones that don't
8411524Sdavid.guillen@arm.com    // directly map to a logical register) as unready.
8511524Sdavid.guillen@arm.com    for (PhysRegIndex index = numLogicalIntRegs;
8611524Sdavid.guillen@arm.com         index < numPhysicalIntRegs;
8711524Sdavid.guillen@arm.com         ++index)
8811524Sdavid.guillen@arm.com    {
8911524Sdavid.guillen@arm.com        intScoreboard[index] = 0;
9011524Sdavid.guillen@arm.com    }
9111524Sdavid.guillen@arm.com
9211524Sdavid.guillen@arm.com    int float_reg_idx = numPhysicalIntRegs;
9312089Sjason@lowepower.com
9412263Stiago.muck@arm.com    // Initialize the entries in the floating point rename map to point to
9512263Stiago.muck@arm.com    // the physical registers of the same index, and consider each register
9612263Stiago.muck@arm.com    // ready until the first rename occurs.
9711524Sdavid.guillen@arm.com    // Although the index refers purely to architected registers, because
9811524Sdavid.guillen@arm.com    // the floating reg indices come after the integer reg indices, they
9911524Sdavid.guillen@arm.com    // may exceed the size of a normal RegIndex (short).
10011524Sdavid.guillen@arm.com    for (PhysRegIndex index = numLogicalIntRegs;
10111524Sdavid.guillen@arm.com         index < numLogicalRegs; ++index)
10211524Sdavid.guillen@arm.com    {
10311524Sdavid.guillen@arm.com        floatRenameMap[index].physical_reg = float_reg_idx++;
10411524Sdavid.guillen@arm.com    }
10511524Sdavid.guillen@arm.com
10611524Sdavid.guillen@arm.com    for (PhysRegIndex index = numPhysicalIntRegs;
10711524Sdavid.guillen@arm.com         index < numPhysicalIntRegs + numLogicalFloatRegs; ++index)
10811524Sdavid.guillen@arm.com    {
10911524Sdavid.guillen@arm.com        floatScoreboard[index] = 1;
11011524Sdavid.guillen@arm.com    }
11111524Sdavid.guillen@arm.com
11211524Sdavid.guillen@arm.com    // Initialize the rest of the physical registers (the ones that don't
11311524Sdavid.guillen@arm.com    // directly map to a logical register) as unready.
11411524Sdavid.guillen@arm.com    for (PhysRegIndex index = numPhysicalIntRegs + numLogicalFloatRegs;
11511524Sdavid.guillen@arm.com         index < numPhysicalRegs;
11611524Sdavid.guillen@arm.com         ++index)
11711524Sdavid.guillen@arm.com    {
11811524Sdavid.guillen@arm.com        floatScoreboard[index] = 0;
11911524Sdavid.guillen@arm.com    }
12011524Sdavid.guillen@arm.com
12111524Sdavid.guillen@arm.com    // Initialize the entries in the misc register scoreboard to be ready.
12211524Sdavid.guillen@arm.com    for (PhysRegIndex index = numPhysicalRegs;
12311524Sdavid.guillen@arm.com         index < numPhysicalRegs + numMiscRegs; ++index)
12411524Sdavid.guillen@arm.com    {
12511524Sdavid.guillen@arm.com        miscScoreboard[index] = 1;
12611524Sdavid.guillen@arm.com    }
12711524Sdavid.guillen@arm.com}
12811524Sdavid.guillen@arm.com
12911524Sdavid.guillen@arm.comSimpleRenameMap::~SimpleRenameMap()
13011524Sdavid.guillen@arm.com{
13111524Sdavid.guillen@arm.com    // Delete the rename maps as they were allocated with new.
13211524Sdavid.guillen@arm.com    delete [] intRenameMap;
13311524Sdavid.guillen@arm.com    delete [] floatRenameMap;
13411524Sdavid.guillen@arm.com}
13511524Sdavid.guillen@arm.com
13611524Sdavid.guillen@arm.comvoid
13711524Sdavid.guillen@arm.comSimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
13811524Sdavid.guillen@arm.com{
13911524Sdavid.guillen@arm.com    //Setup the interface to the freelist.
14011524Sdavid.guillen@arm.com    freeList = fl_ptr;
14111524Sdavid.guillen@arm.com}
14211524Sdavid.guillen@arm.com
14311524Sdavid.guillen@arm.com
14411524Sdavid.guillen@arm.com// Don't allow this stage to fault; force that check to the rename stage.
14511524Sdavid.guillen@arm.com// Simply ask to rename a logical register and get back a new physical
14611524Sdavid.guillen@arm.com// register index.
14711524Sdavid.guillen@arm.comSimpleRenameMap::RenameInfo
14811524Sdavid.guillen@arm.comSimpleRenameMap::rename(RegIndex arch_reg)
14911524Sdavid.guillen@arm.com{
15011524Sdavid.guillen@arm.com    PhysRegIndex renamed_reg;
15111524Sdavid.guillen@arm.com    PhysRegIndex prev_reg;
15211524Sdavid.guillen@arm.com
15311524Sdavid.guillen@arm.com    if (arch_reg < numLogicalIntRegs) {
15411524Sdavid.guillen@arm.com
15511524Sdavid.guillen@arm.com        // Record the current physical register that is renamed to the
15611524Sdavid.guillen@arm.com        // requested architected register.
15711525Sandreas.sandberg@arm.com        prev_reg = intRenameMap[arch_reg].physical_reg;
15811524Sdavid.guillen@arm.com
15911524Sdavid.guillen@arm.com        // If it's not referencing the zero register, then mark the register
16011524Sdavid.guillen@arm.com        // as not ready.
16111524Sdavid.guillen@arm.com        if (arch_reg != intZeroReg) {
16211524Sdavid.guillen@arm.com            // Get a free physical register to rename to.
16311524Sdavid.guillen@arm.com            renamed_reg = freeList->getIntReg();
16411524Sdavid.guillen@arm.com
16511524Sdavid.guillen@arm.com            // Update the integer rename map.
16611524Sdavid.guillen@arm.com            intRenameMap[arch_reg].physical_reg = renamed_reg;
16711525Sandreas.sandberg@arm.com
16811524Sdavid.guillen@arm.com            assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs);
16911524Sdavid.guillen@arm.com
17011524Sdavid.guillen@arm.com            // Mark register as not ready.
17111524Sdavid.guillen@arm.com            intScoreboard[renamed_reg] = false;
17211524Sdavid.guillen@arm.com        } else {
17311524Sdavid.guillen@arm.com            // Otherwise return the zero register so nothing bad happens.
17411525Sandreas.sandberg@arm.com            renamed_reg = intZeroReg;
17511524Sdavid.guillen@arm.com        }
17611524Sdavid.guillen@arm.com    } else if (arch_reg < numLogicalRegs) {
17711524Sdavid.guillen@arm.com        // Subtract off the base offset for floating point registers.
17811524Sdavid.guillen@arm.com//        arch_reg = arch_reg - numLogicalIntRegs;
17911524Sdavid.guillen@arm.com
18011524Sdavid.guillen@arm.com        // Record the current physical register that is renamed to the
18111524Sdavid.guillen@arm.com        // requested architected register.
18211524Sdavid.guillen@arm.com        prev_reg = floatRenameMap[arch_reg].physical_reg;
18311524Sdavid.guillen@arm.com
18411524Sdavid.guillen@arm.com        // If it's not referencing the zero register, then mark the register
18511524Sdavid.guillen@arm.com        // as not ready.
18611524Sdavid.guillen@arm.com        if (arch_reg != floatZeroReg) {
18711524Sdavid.guillen@arm.com            // Get a free floating point register to rename to.
18811524Sdavid.guillen@arm.com            renamed_reg = freeList->getFloatReg();
18911524Sdavid.guillen@arm.com
19011524Sdavid.guillen@arm.com            // Update the floating point rename map.
19111524Sdavid.guillen@arm.com            floatRenameMap[arch_reg].physical_reg = renamed_reg;
192
193            assert(renamed_reg < numPhysicalRegs &&
194                   renamed_reg >= numPhysicalIntRegs);
195
196            // Mark register as not ready.
197            floatScoreboard[renamed_reg] = false;
198        } else {
199            // Otherwise return the zero register so nothing bad happens.
200            renamed_reg = floatZeroReg;
201        }
202    } else {
203        // Subtract off the base offset for miscellaneous registers.
204        arch_reg = arch_reg - numLogicalRegs;
205
206        // No renaming happens to the misc. registers.  They are simply the
207        // registers that come after all the  physical registers; thus
208        // take the base architected register and add the physical registers
209        // to it.
210        renamed_reg = arch_reg + numPhysicalRegs;
211
212        // Set the previous register to the same register; mainly it must be
213        // known that the prev reg was outside the range of normal registers
214        // so the free list can avoid adding it.
215        prev_reg = renamed_reg;
216
217        assert(renamed_reg < numPhysicalRegs + numMiscRegs);
218
219        miscScoreboard[renamed_reg] = false;
220    }
221
222    return RenameInfo(renamed_reg, prev_reg);
223}
224
225//Perhaps give this a pair as a return value, of the physical register
226//and whether or not it's ready.
227PhysRegIndex
228SimpleRenameMap::lookup(RegIndex arch_reg)
229{
230    if (arch_reg < numLogicalIntRegs) {
231        return intRenameMap[arch_reg].physical_reg;
232    } else if (arch_reg < numLogicalRegs) {
233        // Subtract off the base FP offset.
234//        arch_reg = arch_reg - numLogicalIntRegs;
235
236        return floatRenameMap[arch_reg].physical_reg;
237    } else {
238        // Subtract off the misc registers offset.
239        arch_reg = arch_reg - numLogicalRegs;
240
241        // Misc. regs don't rename, so simply add the base arch reg to
242        // the number of physical registers.
243        return numPhysicalRegs + arch_reg;
244    }
245}
246
247bool
248SimpleRenameMap::isReady(PhysRegIndex phys_reg)
249{
250    if (phys_reg < numPhysicalIntRegs) {
251        return intScoreboard[phys_reg];
252    } else if (phys_reg < numPhysicalRegs) {
253
254        // Subtract off the base FP offset.
255//        phys_reg = phys_reg - numPhysicalIntRegs;
256
257        return floatScoreboard[phys_reg];
258    } else {
259        // Subtract off the misc registers offset.
260//        phys_reg = phys_reg - numPhysicalRegs;
261
262        return miscScoreboard[phys_reg];
263    }
264}
265
266// In this implementation the miscellaneous registers do not actually rename,
267// so this function does not allow you to try to change their mappings.
268void
269SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
270{
271    if (arch_reg < numLogicalIntRegs) {
272        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
273                (int)arch_reg, renamed_reg);
274
275        intRenameMap[arch_reg].physical_reg = renamed_reg;
276    } else {
277        assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
278
279        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
280                (int)arch_reg - numLogicalIntRegs, renamed_reg);
281
282        floatRenameMap[arch_reg].physical_reg = renamed_reg;
283    }
284}
285
286void
287SimpleRenameMap::squash(vector<RegIndex> freed_regs,
288                        vector<UnmapInfo> unmaps)
289{
290    panic("Not sure this function should be called.");
291
292    // Not sure the rename map should be able to access the free list
293    // like this.
294    while (!freed_regs.empty()) {
295        RegIndex free_register = freed_regs.back();
296
297        if (free_register < numPhysicalIntRegs) {
298            freeList->addIntReg(free_register);
299        } else {
300            // Subtract off the base FP dependence tag.
301            free_register = free_register - numPhysicalIntRegs;
302            freeList->addFloatReg(free_register);
303        }
304
305        freed_regs.pop_back();
306    }
307
308    // Take unmap info and roll back the rename map.
309}
310
311void
312SimpleRenameMap::markAsReady(PhysRegIndex ready_reg)
313{
314    DPRINTF(Rename, "Rename map: Marking register %i as ready.\n",
315            (int)ready_reg);
316
317    if (ready_reg < numPhysicalIntRegs) {
318        assert(ready_reg >= 0);
319
320        intScoreboard[ready_reg] = 1;
321    } else if (ready_reg < numPhysicalRegs) {
322
323        // Subtract off the base FP offset.
324//        ready_reg = ready_reg - numPhysicalIntRegs;
325
326        floatScoreboard[ready_reg] = 1;
327    } else {
328        //Subtract off the misc registers offset.
329//        ready_reg = ready_reg - numPhysicalRegs;
330
331        miscScoreboard[ready_reg] = 1;
332    }
333}
334
335int
336SimpleRenameMap::numFreeEntries()
337{
338    int free_int_regs = freeList->numFreeIntRegs();
339    int free_float_regs = freeList->numFreeFloatRegs();
340
341    if (free_int_regs < free_float_regs) {
342        return free_int_regs;
343    } else {
344        return free_float_regs;
345    }
346}
347