📄 dispatchunit.cpp
字号:
#endif return nInstructionsToDispatch; } if(decodedInstructions[nInstructionsToDispatch].io.branch.outCTR) if(--nFreeCTRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free ctr rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case SystemRegisterUnitIdent: nFreeROBEntries--; switch(decodedInstructions[nInstructionsToDispatch].iclass) { case ICMoveToSpr: if(decodedInstructions[nInstructionsToDispatch].io.mtspr.dstSpr == 8) if(--nFreeLRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free lr rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } if(decodedInstructions[nInstructionsToDispatch].io.mtspr.dstSpr == 9) if(--nFreeCTRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free ctr rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case ICMoveFromSpr: if(decodedInstructions[nInstructionsToDispatch].io.mfspr.dstReg >= 0) if(--nFreeRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case ICMoveFromTbr: if(decodedInstructions[nInstructionsToDispatch].io.mftb.dstReg >= 0) if(--nFreeRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case ICCRLogical: if(--nFreeCRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free CR rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case ICMoveToCrf: if(decodedInstructions[nInstructionsToDispatch].io.mtcrf.dstCrf < 0) { /* this instruction set the interlock bit, no further instruction will be dispatched */ return nInstructionsToDispatch + 1; } else { if(--nFreeCRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free CR rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } } break; case ICMoveCrf: if(--nFreeCRRenameBuffers < 0) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Not enough free CR rename buffers to dispatch instruction IQ[" << nInstructionsToDispatch << "]" << endl;#endif return nInstructionsToDispatch; } break; case ICSystemCall: /* this instruction set the interlock bit, no further instruction will be dispatched */ return nInstructionsToDispatch + 1; } break; } } return nInstructionsToDispatch; }void DispatchUnit::Decode(){#ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": branch counter = " << branchCounter << endl; }#endif /* If the interlock bit is set then do not try to decode instructions */ /* Just return instead */ if(interlock) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Interlock set" << endl;#endif nDecodedInstructions = 0; outDispatchedInstructions = 0; outDispatchedBranchs = 0; return; } /* Decode instructions in the instruction queue as much as possible */ /* As much as nIQ instructions can be decoded */ int i, j, k; int nInstructions, nBranchs; int nInstructionsToDecode = inInstructionsInQueue; int nBranchsInQueue = inBranchsInQueue; int nBranchsToDecode = nBranchsInQueue; if(nBranchsToDecode > nIQBranchs) nBranchsToDecode = nIQBranchs; if(nInstructionsToDecode > nIQ) nInstructionsToDecode = nIQ; int nFreeROBEntries = rob->GetFreeSpace(); if(nInstructionsToDecode > nFreeROBEntries) nInstructionsToDecode = nFreeROBEntries; bool branchDetected = false; int nNonBranchInstructionsToDispatch = 0; int nBranchInstructionsToDispatch = 0; InstructionQueueEntry iq[nIQ]; const InstructionQueueEntry *queue[nIQ + nIQBranchs]; #ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": " << nInstructionsToDecode << " instructions to decode" << endl; if(Debug(DebugDispatchUnit)) cout << name() << ": " << nBranchsToDecode << " branchs to decode" << endl;#endif bool decodeBranchFollow = branchFollow; bool stopDecoding = false; for(i = 0, j = 0, k = 0; !stopDecoding && i < nIQ + nIQBranchs; i++) { bool newInstruction = false; if(k < nBranchsInQueue) { const InstructionQueueEntry& branchEntry = inBranchQueue[k]; if((branchEntry.priority || decodeBranchFollow) && branchEntry.branchCounter <= nMaxBranchsBeforeDispatchStall) { if(k < nBranchsToDecode) { k++; queue[i] = &branchEntry; newInstruction = true; decodeBranchFollow = false; } } } if(!decodeBranchFollow && !newInstruction) { if(j < nInstructionsToDecode) { iq[j] = inIQ[j]; InstructionQueueEntry& instructionEntry = iq[j]; bool ok = false; if(!ppc_is_a_branch(instructionEntry.instruction)) { ok = true; } else { if(instructionEntry.branchCounter <= nMaxBranchsBeforeDispatchStall) { if((!ppc_is_unconditional_branch(instructionEntry.instruction) && !ppc_is_conditional_branch(instructionEntry.instruction)) || instructionEntry.branchPredicted) { ok = true; } } } if(ok) { queue[i] = &instructionEntry; j++; newInstruction = true; decodeBranchFollow = instructionEntry.branchFollow; } } } if(!newInstruction) break; const InstructionQueueEntry& entry = *queue[i]; #ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": IQ[" << i << "] contains (" << entry.dbgInstructionCounter << ") "; /* Emulator code begins */ ppc_disassemble_to_stream(entry.instruction, entry.pc, stdout); /* Emulator code ends */ cout << endl; }#endif UInt32 instructionWord = entry.instruction; /* Emulator code begins */ ppc_translate(entry.instruction, &decodedInstructions[i]); /* Emulator code ends */ if(decodedInstructions[i].iclass & (ICIntALU | ICIntMul | ICIntDiv)) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Instruction will go to an integer unit" << endl;#endif units[i] = IntegerUnitIdent; } else if(decodedInstructions[i].iclass & ICFloat) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Instruction will go to a floating point unit" << endl;#endif units[i] = FloatingPointUnitIdent; } else if(decodedInstructions[i].iclass & ICLoadStore) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Instruction will go to the load/store unit" << endl;#endif units[i] = LoadStoreUnitIdent; } else if(decodedInstructions[i].iclass & ICBranch) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Instruction will go to the branch unit" << endl;#endif /* if(!queue[i]->branchPredicted) { i = i > 0 ? i - 1 : 0; break; } */ units[i] = BranchUnitIdent; branchDetected = true; } else if(decodedInstructions[i].iclass & (ICMoveToSpr | ICMoveFromSpr | ICCRLogical | ICMoveFromCR | ICMoveToCrf | ICSystemCall | ICMoveCrf | ICMoveFromTbr)) {#ifdef DEBUG if(Debug(DebugDispatchUnit)) cout << name() << ": Instruction will go to the system register unit" << endl;#endif units[i] = SystemRegisterUnitIdent; } else { /* Do not generate an error if the instruction is invalid and some branchs are not yet resolved */ if(branchCounter > 0 || branchDetected) { break; } else { cout << name() << ": Error : not a valid instruction (time stamp = " << sim_time_stamp() << ")" << endl;#ifdef EMULATE ppc_disassemble_to_stream(entry.instruction, entry.pc, stdout); cout << endl;#endif ABORT(); } } } /* Get the number of instructions that has been decoded */ nDecodedInstructions = i;#ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": " << nDecodedInstructions << " decoded instructions" << endl; cout << name() << ": Registers Binding" << endl << *registersBinding; }#endif if(nDecodedInstructions > 0) { /* Check and Allocate ressources in order to dispatch the decoded instructions */ nInstructionsToDispatch = AllocateRS(CheckResources(nDecodedInstructions)); #ifdef TRACE if(Trace(TraceDispatchUnit)) { trace_file->Begin("dispatch"); }#endif /* Now, we launch the readings on the register file, allocate some reorder buffer entries, and rename the registers */ int readRegisterPort = 0; int readFloatingPointRegisterPort = 0; int readRenamePort = 0; int readFloatingPointRenamePort = 0; int readRenameCRPort = 0; int readRenameLRPort = 0; int readRenameCTRPort = 0; for(i = 0; i < nInstructionsToDispatch; i++) { branchFollow = queue[i]->branchFollow;#ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": branch counter = " << branchCounter << endl; }#endif#ifdef DEBUG if(Debug(DebugDispatchUnit)) { cout << name() << ": Instruction #" << i << " :" << endl; { const InstructionQueueEntry& instructionQueueEntry = *queue[i]; cout << name() << ": (" << instructionQueueEntry.dbgInstructionCounter << ") "; ppc_disassemble_to_stream(instructionQueueEntry.instruction, instructionQueueEntry.pc, stdout); cout << endl; } }#endif#ifdef TRACE if(Trace(TraceDispatchUnit)) { trace_file->Begin("instruction"); }#endif /* Allocate a reorder buffer entry and fill in the entry */ ReorderBufferEntry *robEntry;#if defined(EMULATE) robEntry = &rob->Allocate();#else robEntry = (units[i] == BranchUnitIdent && !decodedInstructions[i].io.branch.outLR && !decodedInstructions[i].io.branch.outCTR) ? 0 : &rob->Allocate();// robEntry = &rob->Allocate();#endif if(robEntry) { robEntry->unitIdent = units[i]; robEntry->finished = false; /* Emulator code begins */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -