rename_map.cc (9479:f9e76b1eb79a) | rename_map.cc (9919:803903a8dac1) |
---|---|
1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan | 1/* 2 * Copyright (c) 2004-2005 The Regents of The University of Michigan |
3 * Copyright (c) 2013 Advanced Micro Devices, Inc. |
|
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 --- 19 unchanged lines hidden (view full) --- 30 31#include <vector> 32 33#include "cpu/o3/rename_map.hh" 34#include "debug/Rename.hh" 35 36using namespace std; 37 | 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 --- 19 unchanged lines hidden (view full) --- 31 32#include <vector> 33 34#include "cpu/o3/rename_map.hh" 35#include "debug/Rename.hh" 36 37using namespace std; 38 |
38// @todo: Consider making inline bool functions that determine if the 39// register is a logical int, logical fp, physical int, physical fp, 40// etc. | 39/**** SimpleRenameMap methods ****/ |
41 | 40 |
42SimpleRenameMap::~SimpleRenameMap() | 41SimpleRenameMap::SimpleRenameMap() 42 : freeList(NULL) |
43{ 44} 45 | 43{ 44} 45 |
46 |
|
46void | 47void |
47SimpleRenameMap::init(unsigned _numLogicalIntRegs, 48 unsigned _numPhysicalIntRegs, 49 PhysRegIndex &ireg_idx, | 48SimpleRenameMap::init(unsigned size, SimpleFreeList *_freeList, 49 RegIndex _zeroReg) 50{ 51 assert(freeList == NULL); 52 assert(map.empty()); |
50 | 53 |
51 unsigned _numLogicalFloatRegs, 52 unsigned _numPhysicalFloatRegs, 53 PhysRegIndex &freg_idx, | 54 map.resize(size); 55 freeList = _freeList; 56 zeroReg = _zeroReg; 57} |
54 | 58 |
55 unsigned _numMiscRegs, 56 57 RegIndex _intZeroReg, 58 RegIndex _floatZeroReg, 59 60 int map_id, 61 bool bindRegs) | 59SimpleRenameMap::RenameInfo 60SimpleRenameMap::rename(RegIndex arch_reg) |
62{ | 61{ |
63 id = map_id; | 62 PhysRegIndex renamed_reg; |
64 | 63 |
65 numLogicalIntRegs = _numLogicalIntRegs; | 64 // Record the current physical register that is renamed to the 65 // requested architected register. 66 PhysRegIndex prev_reg = map[arch_reg]; |
66 | 67 |
67 numLogicalFloatRegs = _numLogicalFloatRegs; | 68 // If it's not referencing the zero register, then rename the 69 // register. 70 if (arch_reg != zeroReg) { 71 renamed_reg = freeList->getReg(); |
68 | 72 |
69 numPhysicalIntRegs = _numPhysicalIntRegs; | 73 map[arch_reg] = renamed_reg; 74 } else { 75 // Otherwise return the zero register so nothing bad happens. 76 assert(prev_reg == zeroReg); 77 renamed_reg = zeroReg; 78 } |
70 | 79 |
71 numPhysicalFloatRegs = _numPhysicalFloatRegs; | 80 DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping was %d\n", 81 arch_reg, renamed_reg, prev_reg); |
72 | 82 |
73 numMiscRegs = _numMiscRegs; | 83 return RenameInfo(renamed_reg, prev_reg); 84} |
74 | 85 |
75 intZeroReg = _intZeroReg; 76 floatZeroReg = _floatZeroReg; | |
77 | 86 |
78 DPRINTF(Rename, "Creating rename map %i. Phys: %i / %i, Float: " 79 "%i / %i.\n", id, numLogicalIntRegs, numPhysicalIntRegs, 80 numLogicalFloatRegs, numPhysicalFloatRegs); | 87/**** UnifiedRenameMap methods ****/ |
81 | 88 |
82 numLogicalRegs = numLogicalIntRegs + numLogicalFloatRegs; | 89void 90UnifiedRenameMap::init(PhysRegFile *_regFile, 91 RegIndex _intZeroReg, 92 RegIndex _floatZeroReg, 93 UnifiedFreeList *freeList) 94{ 95 regFile = _regFile; |
83 | 96 |
84 numPhysicalRegs = numPhysicalIntRegs + numPhysicalFloatRegs; | 97 intMap.init(TheISA::NumIntRegs, &(freeList->intList), _intZeroReg); |
85 | 98 |
86 //Create the rename maps 87 intRenameMap.resize(numLogicalIntRegs); 88 floatRenameMap.resize(numLogicalRegs); | 99 floatMap.init(TheISA::NumFloatRegs, &(freeList->floatList), _floatZeroReg); 100} |
89 | 101 |
90 if (bindRegs) { 91 DPRINTF(Rename, "Binding registers into rename map %i\n",id); | |
92 | 102 |
93 // Initialize the entries in the integer rename map to point to the 94 // physical registers of the same index 95 for (RegIndex index = 0; index < numLogicalIntRegs; ++index) 96 { 97 intRenameMap[index].physical_reg = ireg_idx++; 98 } | 103UnifiedRenameMap::RenameInfo 104UnifiedRenameMap::rename(RegIndex arch_reg) 105{ 106 RegIndex rel_arch_reg; |
99 | 107 |
100 // Initialize the entries in the floating point rename map to point to 101 // the physical registers of the same index 102 // Although the index refers purely to architected registers, because 103 // the floating reg indices come after the integer reg indices, they 104 // may exceed the size of a normal RegIndex (short). 105 for (PhysRegIndex index = numLogicalIntRegs; 106 index < numLogicalRegs; ++index) 107 { 108 floatRenameMap[index].physical_reg = freg_idx++; 109 } 110 } else { 111 DPRINTF(Rename, "Binding registers into rename map %i\n",id); | 108 switch (regIdxToClass(arch_reg, &rel_arch_reg)) { 109 case IntRegClass: 110 return renameInt(rel_arch_reg); |
112 | 111 |
113 PhysRegIndex temp_ireg = ireg_idx; | 112 case FloatRegClass: 113 return renameFloat(rel_arch_reg); |
114 | 114 |
115 for (RegIndex index = 0; index < numLogicalIntRegs; ++index) 116 { 117 intRenameMap[index].physical_reg = temp_ireg++; 118 } | 115 case MiscRegClass: 116 return renameMisc(rel_arch_reg); |
119 | 117 |
120 PhysRegIndex temp_freg = freg_idx; 121 122 for (PhysRegIndex index = numLogicalIntRegs; 123 index < numLogicalRegs; ++index) 124 { 125 floatRenameMap[index].physical_reg = temp_freg++; 126 } | 118 default: 119 panic("rename rename(): unknown reg class %s\n", 120 RegClassStrings[regIdxToClass(arch_reg)]); |
127 } 128} 129 | 121 } 122} 123 |
130void 131SimpleRenameMap::setFreeList(SimpleFreeList *fl_ptr) 132{ 133 freeList = fl_ptr; 134} | |
135 | 124 |
136 137SimpleRenameMap::RenameInfo 138SimpleRenameMap::rename(RegIndex arch_reg) | 125PhysRegIndex 126UnifiedRenameMap::lookup(RegIndex arch_reg) const |
139{ | 127{ |
140 PhysRegIndex renamed_reg; 141 PhysRegIndex prev_reg; | 128 RegIndex rel_arch_reg; |
142 | 129 |
143 if (arch_reg < numLogicalIntRegs) { | 130 switch (regIdxToClass(arch_reg, &rel_arch_reg)) { 131 case IntRegClass: 132 return lookupInt(rel_arch_reg); |
144 | 133 |
145 // Record the current physical register that is renamed to the 146 // requested architected register. 147 prev_reg = intRenameMap[arch_reg].physical_reg; | 134 case FloatRegClass: 135 return lookupFloat(rel_arch_reg); |
148 | 136 |
149 // If it's not referencing the zero register, then rename the 150 // register. 151 if (arch_reg != intZeroReg) { 152 renamed_reg = freeList->getIntReg(); | 137 case MiscRegClass: 138 return lookupMisc(rel_arch_reg); |
153 | 139 |
154 intRenameMap[arch_reg].physical_reg = renamed_reg; 155 156 assert(renamed_reg >= 0 && renamed_reg < numPhysicalIntRegs); 157 158 } else { 159 // Otherwise return the zero register so nothing bad happens. 160 renamed_reg = intZeroReg; 161 prev_reg = intZeroReg; 162 } 163 } else if (arch_reg < numLogicalRegs) { 164 // Record the current physical register that is renamed to the 165 // requested architected register. 166 prev_reg = floatRenameMap[arch_reg].physical_reg; 167 168 // If it's not referencing the zero register, then rename the 169 // register. 170#if THE_ISA == ALPHA_ISA 171 if (arch_reg != floatZeroReg) { 172#endif 173 renamed_reg = freeList->getFloatReg(); 174 175 floatRenameMap[arch_reg].physical_reg = renamed_reg; 176 177 assert(renamed_reg < numPhysicalRegs && 178 renamed_reg >= numPhysicalIntRegs); 179#if THE_ISA == ALPHA_ISA 180 } else { 181 // Otherwise return the zero register so nothing bad happens. 182 renamed_reg = floatZeroReg; 183 } 184#endif 185 } else { 186 // Subtract off the base offset for miscellaneous registers. 187 arch_reg = arch_reg - numLogicalRegs; 188 189 DPRINTF(Rename, "Renamed misc reg %d\n", arch_reg); 190 191 // No renaming happens to the misc. registers. They are 192 // simply the registers that come after all the physical 193 // registers; thus take the base architected register and add 194 // the physical registers to it. 195 renamed_reg = arch_reg + numPhysicalRegs; 196 197 // Set the previous register to the same register; mainly it must be 198 // known that the prev reg was outside the range of normal registers 199 // so the free list can avoid adding it. 200 prev_reg = renamed_reg; | 140 default: 141 panic("rename lookup(): unknown reg class %s\n", 142 RegClassStrings[regIdxToClass(arch_reg)]); |
201 } | 143 } |
202 203 DPRINTF(Rename, "Renamed reg %d to physical reg %d old mapping was %d\n", 204 arch_reg, renamed_reg, prev_reg); 205 206 return RenameInfo(renamed_reg, prev_reg); | |
207} 208 | 144} 145 |
209PhysRegIndex 210SimpleRenameMap::lookup(RegIndex arch_reg) 211{ 212 if (arch_reg < numLogicalIntRegs) { 213 return intRenameMap[arch_reg].physical_reg; 214 } else if (arch_reg < numLogicalRegs) { 215 return floatRenameMap[arch_reg].physical_reg; 216 } else { 217 // Subtract off the misc registers offset. 218 arch_reg = arch_reg - numLogicalRegs; 219 220 // Misc. regs don't rename, so simply add the base arch reg to 221 // the number of physical registers. 222 return numPhysicalRegs + arch_reg; 223 } 224} 225 | |
226void | 146void |
227SimpleRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex renamed_reg) | 147UnifiedRenameMap::setEntry(RegIndex arch_reg, PhysRegIndex phys_reg) |
228{ | 148{ |
229 // In this implementation the miscellaneous registers do not 230 // actually rename, so this function does not allow you to try to 231 // change their mappings. 232 if (arch_reg < numLogicalIntRegs) { 233 DPRINTF(Rename, "Rename Map: Integer register %i being set to %i.\n", 234 (int)arch_reg, renamed_reg); | 149 RegIndex rel_arch_reg; |
235 | 150 |
236 intRenameMap[arch_reg].physical_reg = renamed_reg; 237 } else if (arch_reg < numLogicalIntRegs + numLogicalFloatRegs) { 238 DPRINTF(Rename, "Rename Map: Float register %i being set to %i.\n", 239 (int)arch_reg - numLogicalIntRegs, renamed_reg); | 151 switch (regIdxToClass(arch_reg, &rel_arch_reg)) { 152 case IntRegClass: 153 return setIntEntry(rel_arch_reg, phys_reg); |
240 | 154 |
241 floatRenameMap[arch_reg].physical_reg = renamed_reg; 242 } 243} | 155 case FloatRegClass: 156 return setFloatEntry(rel_arch_reg, phys_reg); |
244 | 157 |
245int 246SimpleRenameMap::numFreeEntries() 247{ 248 int free_int_regs = freeList->numFreeIntRegs(); 249 int free_float_regs = freeList->numFreeFloatRegs(); | 158 case MiscRegClass: 159 // Misc registers do not actually rename, so don't change 160 // their mappings. We end up here when a commit or squash 161 // tries to update or undo a hardwired misc reg nmapping, 162 // which should always be setting it to what it already is. 163 assert(phys_reg == lookupMisc(rel_arch_reg)); 164 return; |
250 | 165 |
251 if (free_int_regs < free_float_regs) { 252 return free_int_regs; 253 } else { 254 return free_float_regs; | 166 default: 167 panic("rename setEntry(): unknown reg class %s\n", 168 RegClassStrings[regIdxToClass(arch_reg)]); |
255 } 256} | 169 } 170} |