📄 integerunit.cpp
字号:
latency = 1; } break; case ID_ADDMEOD: { UInt32 a = operands.data[0]; UInt32 c = inCarry ? 1 : 0; result32 = a + c - 1; ca = Carry(a, c - 1); ov = Overflow(a, c - 1); lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; } break; case ID_MULLW: result32 = operands.data[0] * operands.data[1]; latency = GetMulLatency(operands.data[0], operands.data[1]); break; case ID_MULLWD: result32 = operands.data[0] * operands.data[1]; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = GetMulLatency(operands.data[0], operands.data[1]); break; case ID_MULLWO: result64 = operands.data[0] * operands.data[1]; ov = (SInt64) result64 > 0x7fffffff || (SInt64) result64 < 0x80000000; result32 = (UInt32) result64; latency = GetMulLatency(operands.data[0], operands.data[1]); break; case ID_MULLWOD: result64 = operands.data[0] * operands.data[1]; ov = (SInt64) result64 > 0x7fffffff || (SInt64) result64 < 0x80000000; lt = ((SInt32) result64 < 0); gt = ((SInt32) result64 > 0); eq = ((UInt32) result64 == 0); result32 = (UInt32) result64; latency = GetMulLatency(operands.data[0], operands.data[1]); break; case ID_ADD: result32 = operands.data[0] + operands.data[1]; latency = 1; break; case ID_ADDD: result32 = operands.data[0] + operands.data[1]; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_ADDO: result64 = operands.data[0] + operands.data[1]; ca = (result64 > 0xffffffff); ov = ((ca != 0) != (((UInt32) result64 & 0x8000000) != 0)); result32 = (UInt32) result64; latency = 1; break; case ID_ADDOD: result64 = operands.data[0] + operands.data[1]; ca = (result64 > 0xffffffff); ov = ((ca != 0) != (((UInt32) result64 & 0x8000000) != 0)); lt = ((SInt32) result64 < 0); gt = ((SInt32) result64 > 0); eq = ((UInt32) result64 == 0); result32 = (UInt32) result64; latency = 1; break; case ID_EQV: result32 = ~(operands.data[0] ^ operands.data[1]); latency = 1; break; case ID_EQVD: result32 = ~(operands.data[0] ^ operands.data[1]); lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_XOR: result32 = operands.data[0] ^ operands.data[1]; latency = 1; break; case ID_XORD: result32 = operands.data[0] ^ operands.data[1]; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_ORC: result32 = operands.data[0] | (~operands.data[1]); latency = 1; break; case ID_ORCD: result32 = operands.data[0] | (~operands.data[1]); lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_OR: result32 = operands.data[0] | operands.data[1]; latency = 1; break; case ID_ORD: result32 = operands.data[0] | operands.data[1]; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_DIVWU: if(operands.data[1] == 0) { result32 = 0; latency = 2; } else { result32 = operands.data[0] / operands.data[1]; latency = 19; } break; case ID_DIVWUD: if(operands.data[1] == 0) { result32 = 0; latency = 2; } else { result32 = operands.data[0] / operands.data[1]; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 19; } break; case ID_DIVWUO: if(operands.data[1] == 0) { ov = true; result32 = 0; latency = 2; } else { result32 = operands.data[0] / operands.data[1]; ov = false; latency = 19; } break; case ID_DIVWUOD: if(operands.data[1] == 0) { ov = true; result32 = 0; latency = 2; } else { result32 = operands.data[0] / operands.data[1]; ov = false; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 19; } break; case ID_NAND: result32 = ~(operands.data[0] & operands.data[1]); latency = 1; break; case ID_NANDD: result32 = ~(operands.data[0] & operands.data[1]); lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_EXTSB: result32 = (SInt32)(SInt8) operands.data[0]; latency = 1; break; case ID_EXTSBD: result32 = (SInt32)(SInt8) operands.data[0]; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_EXTSH: result32 = (SInt32)(SInt16) operands.data[0]; latency = 1; break; case ID_EXTSHD: result32 = (SInt32)(SInt16) operands.data[0]; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); latency = 1; break; case ID_DIVW: { SInt32 a = operands.data[0]; SInt32 b = operands.data[1]; if(b == 0) { result32 = 0; latency = 2; } else { if(a == 0x80000000 && b == 0xffffffff) { } else { result32 = a / b; } latency = 19; } } break; case ID_DIVWD: { SInt32 a = operands.data[0]; SInt32 b = operands.data[1]; if(b == 0) { result32 = 0; latency = 2; } else { if(a == 0x80000000 && b == 0xffffffff) { } else { result32 = a / b; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); } latency = 19; } } break; case ID_DIVWO: { SInt32 a = operands.data[0]; SInt32 b = operands.data[1]; if(b == 0) { ov = true; result32 = 0; latency = 2; } else { if(a == 0x80000000 && b == 0xffffffff) { ov = true; } else { result32 = a / b; ov = false; } latency = 19; } } break; case ID_DIVWOD: { SInt32 a = operands.data[0]; SInt32 b = operands.data[1]; if(b == 0) { ov = true; result32 = 0; latency = 2; } else { if(a == 0x80000000 && b == 0xffffffff) { ov = true; } else { result32 = a / b; ov = false; lt = ((SInt32) result32 < 0); gt = ((SInt32) result32 > 0); eq = ((UInt32) result32 == 0); } latency = 19; } } break; default:#ifdef DEBUG if(Debug(DebugIntegerUnit)) { cout << name() << ": Simulator does not support this instruction (tag = " << (int) tags.tag << ", op = " << operation.ident << ") (" << dbgInstructionCounter << ") "; ppc_disassemble_to_stream(dbgInstruction, dbgProgramCounter, stdout); cout << endl; }#endif ABORT(); } /* switch */ #ifdef DEBUG if(Debug(DebugIntegerUnit)) if(latency <= 0) { cout << name() << "Latency is " << latency << endl; ABORT(); }#endif } /* if(latency == 0) */ if(--latency == 0) { /* the instruction has finished its execution */ if(tags.resultTag >= 0) {#ifdef DEBUG if(Debug(DebugIntegerUnit)) { cout << name() << ": producing rr" << (int) tags.resultTag << "("; WriteHex(cout, result32); cout << ")" << endl; }#endif outResultValid = true; outResultTag = tags.resultTag; outResultData = result32; } else { outResultValid = false; } if(tags.CRTag >= 0) {#ifdef DEBUG if(Debug(DebugIntegerUnit)) { cout << name() << ": producing CR rename buffer #" << (int) tags.CRTag << "("; WriteHex(cout, (UInt8)((lt ? 8:0) | (gt ? 4:0) | (eq ? 2:0))); cout << ")" << endl; }#endif outResultCRValid = true; outResultCRTag = tags.CRTag; outResultCRData = (lt ? 8:0) | (gt ? 4:0) | (eq ? 2:0); } else { outResultCRValid = false; } outCarry = ca; outOverflow = ov; outBusy = false; outTag = tags.tag; outFinished = true; dispatched = false;#ifdef DEBUG if(Debug(DebugIntegerUnit)) { cout << name() << ": Finishing an instruction (tag = " << (int) tags.tag << ") (" << dbgInstructionCounter << ") "; ppc_disassemble_to_stream(dbgInstruction, dbgProgramCounter, stdout); cout << endl; }#endif return; } outResultValid = false; outResultCRValid = false; outFinished = false; outBusy = true; return; } outResultValid = false; outResultCRValid = false; outFinished = false; outBusy = false;}void IntegerUnit::OnFallingEdge(){ if(inBranchFinished) { if(inMispredictedBranch && branchCounter > 0) { branchCounter = 0; latency = 0; dispatched = false; outResultValid = false; outResultCRValid = false; outFinished = false; outBusy = false; } if(branchCounter > 0) branchCounter--; }}void IntegerUnit::Reset(){ branchCounter = 0; latency = 0; dispatched = false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -