/// <summary> /// Creates a table to map from architectural register to a physical register. /// Initialized to have a mapping from every architectural register to a physical register. /// </summary> /// <param name="archRegisterCount">Number of architectural registers</param> /// <param name="freeList">Free table reference to calculate initial mapping</param> public MappingTable(int archRegisterCount, FreeList freeList) { Map = new int[archRegisterCount]; for (int i = 0; i < archRegisterCount; i++) { Map[i] = freeList.GetUnusedRegister(); } }
private void Rename() { int maxRename = 0; while (PhysFreeList.PhysicalRegisterAvailable() && !this.IQueue.IsFull() && !ROB.Full() && DE_RN.Ops.Count > 0 && maxRename < 4) { DecodedOp o = DE_RN.Ops.Dequeue(); byte op = o.Op; OpCodes.OpInfo opi = o.Meta; byte dst = 0; if (opi.HasOutput) { // TODO: Don't cast this. Do it properly. dst = (byte)PhysFreeList.GetUnusedRegister(); PhysRegisters.SetReady(dst, false); } byte src1 = (byte)ArchToPhysTable.GetPhysicalRegisterId(opi.Src1Dep ? o.Src1 : 0); byte src2 = (byte)ArchToPhysTable.GetPhysicalRegisterId(opi.Src2Dep ? o.Src2 : 0); bool rd1 = opi.Src1Dep ? PhysRegisters.IsReady(src1) : true; bool rd2 = opi.Src2Dep ? PhysRegisters.IsReady(src2) : true; if (opi.HasOutput) { byte archReg = 0; switch (opi.OutputSource) { case OpCodes.DstSource.Dst: archReg = o.Dst; break; case OpCodes.DstSource.Src1: archReg = o.Src1; break; case OpCodes.DstSource.Src2: archReg = o.Src2; break; } ArchToPhysTable.MapArchToPhys(archReg, dst); // Redirect dst register to the correct destination. o.Dst = archReg; } // Resulting register of this operation should be declared not ready until it has executed. Console.WriteLine("Rename: rd1={0}, rd2={1}, src1={2}, src2={3}, dst={4}", rd1, rd2, (int)src1, (int)src2, (int)dst); // Add entry to issue queue and re-order buffer this.IQueue.AddToQueue(o.PC, op, src1, src2, dst, rd1, rd2, o.Const, o.Meta); this.ROB.AddToQueue(o.PC, o.Dst, dst, o.Meta.HasOutput); maxRename++; } // Stallable by multiple resource hazards: re-order buffer full, issue queue full or lack of physical registers. // Therefore a stall may occur, resulting in wasted cycles. this.DE_RN.Stalled = !PhysFreeList.PhysicalRegisterAvailable() || this.IQueue.IsFull() || ROB.Full() || DE_RN.Ops.Count >= 4; this.StalledRenameCycles += (4 - maxRename); }