📄 dispatchunit.cpp
字号:
const InstructionQueueEntry& instructionQueueEntry = *queue[i]; robEntry->inst = instructionQueueEntry.inst; robEntry->instPC = instructionQueueEntry.pc; /* Emulator code ends */ robEntry->nia = instructionQueueEntry.nia; } switch(units[i]) { case IntegerUnitIdent: { nNonBranchInstructionsToDispatch++;#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "unit : integer" << endl;#endif#ifdef TRACE if(Trace(TraceDispatchUnit)) { trace_file->Value("number", instructionQueueEntry.dbgInstructionCounter); trace_file->Value("pc", instructionQueueEntry.pc); trace_file->Value("unit", "integer"); trace_file->Value("unit_number", rs[i].integer->unitNumber); }#endif for(j = 0; j < 2; j++) { regnum_t srcReg = decodedInstructions[i].io.integer.srcReg[j]; /* Get the source register number */ if(srcReg >= 0) { /* Instruction has a source register number */#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "source register : r" << (int) srcReg << endl;#endif tag_t tag = registersBinding->GetRenameBuffer(srcReg); /* Get the tag of the source register */ rs[i].integer->operands[j].tag = tag; /* store the tag of the operand */ rs[i].integer->operands[j].valid = false; /* make the reservation station to wait for the operand */ if(tag < 0) { /* The source register is not renamed */#ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": Reading r" << (int) srcReg << " value from register file" << endl; if(readRegisterPort >= nReadRegisterPorts) { cout << name() << ": not enough read register ports" << endl; ABORT(); } }#endif integerReadingRegisters[i][j] = srcReg; /* To remember that we are reading the source register */ integerReadingRenameBuffers[i][j] = -1; /* No rename buffer is being read */ outReadRegisterNumber[readRegisterPort++] = srcReg; /* Ask to the register file the value of the source register */ } else { /* The source register is renamed */ if(registersBinding->RenameBufferValid(tag)) { /* The rename buffer yet contains the right value */ #ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": Reading r" << (int) srcReg << " value from rr" << (int) tag << endl; if(readRenamePort >= nReadRenamePorts) { cout << name() << ": not enough read rename buffer ports" << endl; ABORT(); } }#endif integerReadingRegisters[i][j] = -1; /* No register is being read */ integerReadingRenameBuffers[i][j] = tag; /* To remember that we are reading the source register value from the rename buffers */ outReadRenameNumber[readRenamePort++] = tag; /* Ask to the register file the value of the rename buffer containing the value of the source register */ } else {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Waiting for r" << (int) srcReg << " value hold by rr" << (int) tag << endl;#endif integerReadingRegisters[i][j] = -1; /* No register is being read */ integerReadingRenameBuffers[i][j] = -1; /* No rename buffer is being read */ /* Just wait for the value to be produce by functional units */ } } } else { /* No source register */ integerReadingRegisters[i][j] = -1; integerReadingRenameBuffers[i][j] = -1; rs[i].integer->operands[j].tag = -1; } } /* Store the integer operation into the reservation station */ rs[i].integer->operation = decodedInstructions[i].operation.integer;#if defined(DEBUG) || defined(TRACE) { const InstructionQueueEntry& instructionQueueEntry = *queue[i]; rs[i].integer->dbgInstructionCounter = instructionQueueEntry.dbgInstructionCounter; rs[i].integer->dbgProgramCounter = instructionQueueEntry.pc; rs[i].integer->dbgInstruction = instructionQueueEntry.instruction; }#endif if(decodedInstructions[i].hasImmed) rs[i].integer->operands[1].data = decodedInstructions[i].immed; /* Fill the reservation station with tag of the destination registers */ regnum_t dstReg = decodedInstructions[i].io.integer.dstReg; if(dstReg >= 0) { /* Instruction has a destination register number */#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "destination register : r" << (int) dstReg << endl;#endif /* Allocate a rename buffer and store its tag into the reservation station */ rs[i].integer->tags.resultTag = registersBinding->AllocateRenameBuffer(dstReg); } else { /* Instruction has no destination register */ rs[i].integer->tags.resultTag = -1; } if(decodedInstructions[i].io.integer.outCR) { /* Instruction has a destination CR field */ fieldnum_t crf = decodedInstructions[i].io.integer.crf;#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "destination register : CR" << (int) crf << endl;#endif /* Allocate a rename buffer and store its tag into the reservation station */ rs[i].integer->tags.CRTag = registersBinding->AllocateCRRenameBuffer(crf); } else { /* Instruction has no destination CR field */ rs[i].integer->tags.CRTag = -1; } /* Store the instruction tag into the reservation station */ rs[i].integer->tags.tag = rob->GetIndex(*robEntry); rs[i].integer->branchCounter = branchCounter; robEntry->extra.integer.tags = rs[i].integer->tags; if(decodedInstructions[i].io.integer.inCarry) { /* Instruction reads the carry bit XER[CA], so it is execution serialized */ robEntry->executionSerialized = true; rs[i].integer->executionSerialized = true; } else { /* Instruction does not read the carry bit XER[CA], so it is not execution serialized */ robEntry->executionSerialized = false; rs[i].integer->executionSerialized = false; } /* To remember whether the instruction modifies the overflow bit XER[OV], or the carry bit XER[CA] */ if(decodedInstructions[i].io.integer.outOverflow) robEntry->extra.integer.writeOverflow = true; else robEntry->extra.integer.writeOverflow = false; if(decodedInstructions[i].io.integer.outCarry) robEntry->extra.integer.writeCarry = true; else robEntry->extra.integer.writeCarry = false; /* Fill the reorder buffer entry with some other usefull informations */ robEntry->branchCounter = rs[i].integer->branchCounter; robEntry->extra.integer.unitNumber = rs[i].integer->unitNumber;#if defined(DEBUG) || defined(TRACE) robEntry->dbgInstructionCounter = rs[i].integer->dbgInstructionCounter; robEntry->dbgProgramCounter = rs[i].integer->dbgProgramCounter; robEntry->dbgInstruction = rs[i].integer->dbgInstruction;#endif } break; case FloatingPointUnitIdent: { nNonBranchInstructionsToDispatch++;#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "unit : floating point" << endl;#endif#ifdef TRACE if(Trace(TraceDispatchUnit)) { trace_file->Value("number", instructionQueueEntry.dbgInstructionCounter); trace_file->Value("pc", instructionQueueEntry.pc); trace_file->Value("unit", "floating point"); trace_file->Value("unit_number", rs[i].floatingPoint->unitNumber); }#endif for(j = 0; j < 3; j++) { regnum_t srcReg = decodedInstructions[i].io.floatingPoint.srcReg[j]; /* Get the source register number */ if(srcReg >= 0) { /* Instruction a source register */#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "source register : fp" << (int) srcReg << endl;#endif tag_t tag = registersBinding->GetFloatingPointRenameBuffer(srcReg); /* Get the tag of the source register */ rs[i].floatingPoint->operands[j].tag = tag; /* store the tag of the operand */ rs[i].floatingPoint->operands[j].valid = false; /* make the reservation station to wait for the operand */ if(tag < 0) { /* The source register is not renamed */#ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": Reading rfp" << (int) srcReg << " value from register file" << endl; if(readFloatingPointRegisterPort >= nReadFloatingPointRegisterPorts) { cout << name() << ": not enough read floating point register ports" << endl; ABORT(); } }#endif floatingPointReadingFloatingPointRegisters[i][j] = srcReg; /* To remember that we are reading the source register */ floatingPointReadingFloatingPointRenameBuffers[i][j] = -1; /* No rename buffer is being read */ outReadFloatingPointRegisterNumber[readFloatingPointRegisterPort++] = srcReg; /* Ask to the register file the value of the source register */ } else { /* The source register is renamed */ if(registersBinding->FloatingPointRenameBufferValid(tag)) { /* The rename buffer yet contains the right value */#ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": Reading fp" << (int) srcReg << " value from rfp" << (int) tag << endl; if(readFloatingPointRenamePort >= nReadFloatingPointRenamePorts) { cout << name() << ": not enough read floating point rename buffer ports" << endl; ABORT(); } }#endif floatingPointReadingFloatingPointRegisters[i][j] = -1; /* No register is being read */ floatingPointReadingFloatingPointRenameBuffers[i][j] = tag; /* Remember that we are reading the source register value from the rename buffers */ outReadFloatingPointRenameNumber[readFloatingPointRenamePort++] = tag; /* Ask to register file the value of the rename buffer containing the value of the source register */ } else {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Waiting for fp" << (int) srcReg << " value hold by rfp" << (int) tag << endl;#endif floatingPointReadingFloatingPointRegisters[i][j] = -1; /* No register is being read */ floatingPointReadingFloatingPointRenameBuffers[i][j] = -1; /* No rename buffer is being read */ /* Just wait for the value to be produce by functional units */ } } } else { /* No source register */ floatingPointReadingFloatingPointRegisters[i][j] = -1; floatingPointReadingFloatingPointRenameBuffers[i][j] = -1; rs[i].floatingPoint->operands[j].tag = -1; } } /* Store the floating point operation into the reservation station */ rs[i].floatingPoint->operation = decodedInstructions[i].operation.floatingPoint;#if defined(DEBUG) || defined(TRACE) { const InstructionQueueEntry& instructionQueueEntry = *queue[i]; rs[i].floatingPoint->dbgInstructionCounter = instructionQueueEntry.dbgInstructionCounter; rs[i].floatingPoint->dbgProgramCounter = instructionQueueEntry.pc; rs[i].floatingPoint->dbgInstruction = instructionQueueEntry.instruction; }#endif /* Fill the reservation station with tag of the destination registers */ regnum_t dstReg = decodedInstructions[i].io.floatingPoint.dstReg; if(dstReg >= 0) { /* Instruction has a destination register */#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "destination register : fp" << (int) dstReg << endl;#endif /* Allocate a floating point rename buffer and store its tag into the reservation station */ rs[i].floatingPoint->tags.resultTag = registersBinding->AllocateFloatingPointRenameBuffer(dstReg); } else { /* Instruction has no destination register */ rs[i].floatingPoint->tags.resultTag = -1; } if(decodedInstructions[i].io.floatingPoint.outCR) { /* Instruction has a destination CR field */ fieldnum_t crf = decodedInstructions[i].io.floatingPoint.crf;#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "destination register : CR" << (int) crf << endl;#endif /* Allocate a rename buffer and store its tag into the reservation station */ rs[i].floatingPoint->tags.CRTag = registersBinding->AllocateCRRenameBuffer(crf); } else { /* Instruction has no destination CR field */ rs[i].floatingPoint->tags.CRTag = -1; } /* Store the instruction tag into the reservation station */ rs[i].floatingPoint->tags.tag = rob->GetIndex(*robEntry); rs[i].floatingPoint->branchCounter = branchCounter; robEntry->extra.floatingPoint.tags = rs[i].floatingPoint->tags; if(decodedInstructions[i].io.floatingPoint.inFPSCR) robEntry->executionSerialized = true; else robEntry->executionSerialized = false; /* Fill the reorder buffer entry with some other usefull informations */ robEntry->branchCounter = rs[i].floatingPoint->branchCounter; robEntry->extra.integer.unitNumber = rs[i].floatingPoint->unitNumber;#if defined(DEBUG) || defined(TRACE) robEntry->dbgInstructionCounter = rs[i].floatingPoint->dbgInstructionCounter; robEntry->dbgProgramCounter = rs[i].floatingPoint->dbgProgramCounter; robEntry->dbgInstruction = rs[i].floatingPoint->dbgInstruction;#endif } break; case LoadStoreUnitIdent: { nNonBranchInstructionsToDispatch++;#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << "unit : load/store" << endl;#endif#ifdef TRACE if(Trace(TraceDispatchUnit)) { trace_file->Value("number", instructionQueueEntry.dbgInstructionCounter); trace_file->Value("pc", instructionQueueEntry.pc); trace_file->Value("unit", "load/store"); }#endif regnum_t srcReg; /* First operand can be either a floating point register or a general purpose register */ if(decodedInstructions[i].operation.loadStore.floatingPoint) { srcReg = decodedInstructions[i].io.loadStore.srcReg[0]; if(srcReg >= 0) { /* First operand is a floating point register */#ifdef DEBUG if(Debug(DebugDispatchUnit))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -