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