rename_map.cc revision 1060
1
2#include "cpu/beta_cpu/rename_map.hh"
3
4// Todo: Consider making functions inline.  Avoid having things that are
5// using the zero register or misc registers from adding on the registers
6// to the free list.
7
8SimpleRenameMap::RenameEntry::RenameEntry()
9    : physical_reg(0), valid(false)
10{
11}
12
13SimpleRenameMap::SimpleRenameMap(unsigned _numLogicalIntRegs,
14                                 unsigned _numPhysicalIntRegs,
15                                 unsigned _numLogicalFloatRegs,
16                                 unsigned _numPhysicalFloatRegs,
17                                 unsigned _numMiscRegs,
18                                 RegIndex _intZeroReg,
19                                 RegIndex _floatZeroReg)
20    : numLogicalIntRegs(_numLogicalIntRegs),
21      numPhysicalIntRegs(_numPhysicalIntRegs),
22      numLogicalFloatRegs(_numLogicalFloatRegs),
23      numPhysicalFloatRegs(_numPhysicalFloatRegs),
24      numMiscRegs(_numMiscRegs),
25      intZeroReg(_intZeroReg),
26      floatZeroReg(_floatZeroReg)
27{
28    DPRINTF(Rename, "Rename: Creating rename map.  Phys: %i / %i, Float: "
29            "%i / %i.\n", numLogicalIntRegs, numPhysicalIntRegs,
30            numLogicalFloatRegs, numPhysicalFloatRegs);
31
32    numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs;
33
34    numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs;
35
36    //Create the rename maps, and their scoreboards.
37    intRenameMap = new RenameEntry[numLogicalIntRegs];
38    floatRenameMap = new RenameEntry[numLogicalFloatRegs];
39
40    intScoreboard.resize(numPhysicalIntRegs);
41    floatScoreboard.resize(numPhysicalFloatRegs);
42    miscScoreboard.resize(numMiscRegs);
43
44    // Initialize the entries in the integer rename map to point to the
45    // physical registers of the same index, and consider each register
46    // ready until the first rename occurs.
47    for (RegIndex index = 0; index < numLogicalIntRegs; ++index)
48    {
49        intRenameMap[index].physical_reg = index;
50        intScoreboard[index] = 1;
51    }
52
53    // Initialize the rest of the physical registers (the ones that don't
54    // directly map to a logical register) as unready.
55    for (PhysRegIndex index = numLogicalIntRegs;
56         index < numPhysicalIntRegs;
57         ++index)
58    {
59        intScoreboard[index] = 0;
60    }
61
62    // Initialize the entries in the floating point rename map to point to
63    // the physical registers of the same index, and consider each register
64    // ready until the first rename occurs.
65    for (RegIndex index = 0; index < numLogicalFloatRegs; ++index)
66    {
67        floatRenameMap[index].physical_reg = index + numPhysicalIntRegs;
68        floatScoreboard[index] = 1;
69    }
70
71    // Initialize the rest of the physical registers (the ones that don't
72    // directly map to a logical register) as unready.
73    for (PhysRegIndex index = numLogicalFloatRegs;
74         index < numPhysicalFloatRegs;
75         ++index)
76    {
77        floatScoreboard[index] = 0;
78    }
79
80    // Initialize the entries in the misc register scoreboard to be ready.
81    for (RegIndex index = 0; index < numMiscRegs; ++index)
82    {
83        miscScoreboard[index] = 1;
84    }
85}
86
87void
88SimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr)
89{
90    //Setup the interface to the freelist.
91    freeList = fl_ptr;
92}
93
94
95// Don't allow this stage to fault; force that check to the rename stage.
96// Simply ask to rename a logical register and get back a new physical
97// register index.
98SimpleRenameMap::RenameInfo
99SimpleRenameMap::rename(RegIndex arch_reg)
100{
101    PhysRegIndex renamed_reg;
102    PhysRegIndex prev_reg;
103
104    if (arch_reg < numLogicalIntRegs) {
105
106        // Record the current physical register that is renamed to the
107        // requested architected register.
108        prev_reg = intRenameMap[arch_reg].physical_reg;
109
110        // If it's not referencing the zero register, then mark the register
111        // as not ready.
112        if (arch_reg != intZeroReg) {
113            // Get a free physical register to rename to.
114            renamed_reg = freeList->getIntReg();
115
116            // Update the integer rename map.
117            intRenameMap[arch_reg].physical_reg = renamed_reg;
118
119            // Mark register as not ready.
120            intScoreboard[renamed_reg] = false;
121        } else {
122            // Otherwise return the zero register so nothing bad happens.
123            renamed_reg = intZeroReg;
124        }
125    } else if (arch_reg < numLogicalRegs) {
126        // Subtract off the base offset for floating point registers.
127        arch_reg = arch_reg - numLogicalIntRegs;
128
129        // Record the current physical register that is renamed to the
130        // requested architected register.
131        prev_reg = floatRenameMap[arch_reg].physical_reg;
132
133        // If it's not referencing the zero register, then mark the register
134        // as not ready.
135        if (arch_reg != floatZeroReg) {
136            // Get a free floating point register to rename to.
137            renamed_reg = freeList->getFloatReg();
138
139            // Update the floating point rename map.
140            floatRenameMap[arch_reg].physical_reg = renamed_reg;
141
142            // Mark register as not ready.
143            floatScoreboard[renamed_reg] = false;
144        } else {
145            // Otherwise return the zero register so nothing bad happens.
146            renamed_reg = floatZeroReg;
147        }
148    } else {
149        // Subtract off the base offset for miscellaneous registers.
150        arch_reg = arch_reg - numLogicalRegs;
151
152        // No renaming happens to the misc. registers.  They are simply the
153        // registers that come after all the  physical registers; thus
154        // take the base architected register and add the physical registers
155        // to it.
156        renamed_reg = arch_reg + numPhysicalRegs;
157
158        // Set the previous register to the same register; mainly it must be
159        // known that the prev reg was outside the range of normal registers
160        // so the free list can avoid adding it.
161        prev_reg = renamed_reg;
162
163        miscScoreboard[renamed_reg] = false;
164    }
165
166    return RenameInfo(renamed_reg, prev_reg);
167}
168
169//Perhaps give this a pair as a return value, of the physical register
170//and whether or not it's ready.
171PhysRegIndex
172SimpleRenameMap::lookup(RegIndex arch_reg)
173{
174    if (arch_reg < numLogicalIntRegs) {
175        return intRenameMap[arch_reg].physical_reg;
176    } else if (arch_reg < numLogicalRegs) {
177        // Subtract off the base FP offset.
178        arch_reg = arch_reg - numLogicalIntRegs;
179
180        return floatRenameMap[arch_reg].physical_reg;
181    } else {
182        // Subtract off the misc registers offset.
183        arch_reg = arch_reg - numLogicalRegs;
184
185        // Misc. regs don't rename, so simply add the base arch reg to
186        // the number of physical registers.
187        return numPhysicalRegs + arch_reg;
188    }
189}
190
191bool
192SimpleRenameMap::isReady(PhysRegIndex phys_reg)
193{
194    if (phys_reg < numPhysicalIntRegs) {
195        return intScoreboard[phys_reg];
196    } else if (phys_reg < numPhysicalRegs) {
197
198        // Subtract off the base FP offset.
199        phys_reg = phys_reg - numPhysicalIntRegs;
200
201        return floatScoreboard[phys_reg];
202    } else {
203        // Subtract off the misc registers offset.
204        phys_reg = phys_reg - numPhysicalRegs;
205
206        return miscScoreboard[phys_reg];
207    }
208}
209
210// In this implementation the miscellaneous registers do not actually rename,
211// so this function does not allow you to try to change their mappings.
212void
213SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg)
214{
215    if (arch_reg < numLogicalIntRegs) {
216        DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n",
217                (int)arch_reg, renamed_reg);
218
219        intRenameMap[arch_reg].physical_reg = renamed_reg;
220    } else {
221//        assert(arch_reg < (numLogicalIntRegs + numLogicalFloatRegs));
222
223        // Subtract off the base FP offset.
224        arch_reg = arch_reg - numLogicalIntRegs;
225
226        DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n",
227                (int)arch_reg, renamed_reg);
228
229        floatRenameMap[arch_reg].physical_reg = renamed_reg;
230    }
231}
232
233void
234SimpleRenameMap::squash(vector<RegIndex> freed_regs,
235                        vector<UnmapInfo> unmaps)
236{
237    // Not sure the rename map should be able to access the free list
238    // like this.
239    while (!freed_regs.empty()) {
240        RegIndex free_register = freed_regs.back();
241
242        if (free_register < numPhysicalIntRegs) {
243            freeList->addIntReg(free_register);
244        } else {
245            // Subtract off the base FP dependence tag.
246            free_register = free_register - numPhysicalIntRegs;
247            freeList->addFloatReg(free_register);
248        }
249
250        freed_regs.pop_back();
251    }
252
253    // Take unmap info and roll back the rename map.
254}
255
256void
257SimpleRenameMap::markAsReady(PhysRegIndex ready_reg)
258{
259    DPRINTF(Rename, "Rename map: Marking register %i as ready.\n",
260            (int)ready_reg);
261
262    if (ready_reg < numPhysicalIntRegs) {
263        intScoreboard[ready_reg] = 1;
264    } else if (ready_reg < numPhysicalRegs) {
265
266        // Subtract off the base FP offset.
267        ready_reg = ready_reg - numPhysicalIntRegs;
268
269        floatScoreboard[ready_reg] = 1;
270    } else {
271        //Subtract off the misc registers offset.
272        ready_reg = ready_reg - numPhysicalRegs;
273
274        miscScoreboard[ready_reg] = 1;
275    }
276}
277
278int
279SimpleRenameMap::numFreeEntries()
280{
281    int free_int_regs = freeList->numFreeIntRegs();
282    int free_float_regs = freeList->numFreeFloatRegs();
283
284    if (free_int_regs < free_float_regs) {
285        return free_int_regs;
286    } else {
287        return free_float_regs;
288    }
289}
290