private void Inst_FpuAdd(MipsInstruction inst) { unchecked { if (!CheckCop1Usable()) { CauseException = ExceptionCode.CopUnstable; return; } if (!CheckEvenOddAllowed(inst)) { return; } DataFormat format = inst.DecodeDataFormat(); if (format == DataFormat.Single || format == DataFormat.Double) { FPUHardware.SetRoundingMode(MipsState.FCR31.RM); FPUEntity left = new FPUEntity(format, MipsState); FPUEntity right = new FPUEntity(format, MipsState); FPUEntity result = new FPUEntity(format, MipsState); left.Load(inst.Fs); right.Load(inst.Ft); try { result.Value = left + right; result.Store(inst.Fd); } catch (OverflowException) { if (FPUHardware.CheckFPUException()) { CauseFPUException(FPUHardware.GetFPUException()); } } } else { CauseFPUException(FPUExceptionType.Unimplemented); } } }
private void SetInitialState() { if (m_ExecEngine == null) { throw new InvalidOperationException("Execution engine cannot be null"); } /* MIPS Registers */ m_State.GPRRegs.Clear(); m_State.LLBit = false; m_State.Hi = 0; m_State.Lo = 0; /* Setup Cop0 Registers */ m_State.CP0Regs.Cause = 0x5C; m_State.CP0Regs.Status = 0x34000000; m_State.CP0Regs.Config = 0x0006E463; m_State.CP0Regs.PRId = 0xB00; m_State.CP0Regs.Count = 0x5000; m_State.CP0Regs.Context = 0x7FFFF0; m_State.CP0Regs.ErrorEPC = 0xFFFFFFFF; m_State.CP0Regs.EPC = 0xFFFFFFFF; /* Setup Cop1 Registers */ m_State.FCR0 = 0x511; m_State.FCR31.RegisterValue = 0; m_State.Fpr.Clear(); FPUHardware.SetRoundingMode(m_State.FCR31.RM); /* Initialize the execution engine */ m_ExecEngine.SetParent(this); /* Initialize the MMU */ m_MMU.Initialize(); /* Initialize the engine */ m_ExecEngine.Initialize(); }
private void Inst_FpuRoundW(MipsInstruction inst) { unchecked { if (!CheckCop1Usable()) { CauseException = ExceptionCode.CopUnstable; return; } if (!CheckEvenOddAllowed(inst)) { return; } DataFormat format = inst.DecodeDataFormat(); if (format == DataFormat.Single || format == DataFormat.Double) { FPUHardware.SetRoundingMode(FPURoundMode.Near); FPUEntity value = new FPUEntity(format, MipsState); FPUEntity result = new FPUEntity(DataFormat.Word, MipsState); value.Load(inst.Fs); result.Value = (UInt32)Math.Round(value.Value, MidpointRounding.ToEven); result.Store(inst.Fd); if (FPUHardware.CheckFPUException()) { CauseFPUException(FPUHardware.GetFPUException()); } } else { CauseFPUException(FPUExceptionType.Unimplemented); } } }
private void Inst_FpuSqrt(MipsInstruction inst) { if (!CheckCop1Usable()) { CauseException = ExceptionCode.CopUnstable; return; } if (!CheckEvenOddAllowed(inst)) { return; } unchecked { DataFormat format = inst.DecodeDataFormat(); if (format == DataFormat.Single || format == DataFormat.Double) { FPUEntity value = new FPUEntity(format, MipsState); value.Load(inst.Fs); FPUHardware.SetRoundingMode(MipsState.FCR31.RM); value.Value = Math.Sqrt(value.Value); value.Store(inst.Fd); if (FPUHardware.CheckFPUException()) { CauseFPUException(FPUHardware.GetFPUException()); } } else { CauseFPUException(FPUExceptionType.Unimplemented); } } }
private void Inst_FpuConvertW(MipsInstruction inst) { unchecked { if (!CheckCop1Usable()) { CauseException = ExceptionCode.CopUnstable; return; } if (!CheckEvenOddAllowed(inst)) { return; } DataFormat format = inst.DecodeDataFormat(); if (format != DataFormat.Reserved || format != DataFormat.Word) { FPUEntity value = new FPUEntity(format, MipsState); FPUEntity result = new FPUEntity(DataFormat.Word, MipsState); value.Load(inst.Fs); result.Value = Convert.ToUInt32(value.Value); value.Store(inst.Fd); if (FPUHardware.CheckFPUException()) { CauseFPUException(FPUHardware.GetFPUException()); } } else { CauseFPUException(FPUExceptionType.Unimplemented); } } }