コード例 #1
0
        private void Inst_Add(MipsInstruction inst)
        {
            if (!MipsState.Operating64BitMode)
            {
                try
                {
                    MipsState.WriteGPR32Signed(inst.Rd, MipsState.ReadGPR32Signed(inst.Rs) + MipsState.ReadGPR32Signed(inst.Rt));
                }
                catch (OverflowException)
                {
                    CauseException = ExceptionCode.OverFlow;
                }

            }
            else
            {
                if (MipsState.ReadGPRUnsigned(inst.Rs).IsSigned32() && MipsState.ReadGPRUnsigned(inst.Rt).IsSigned32())
                {
                    try
                    {
                        MipsState.WriteGPRSigned(inst.Rd, MipsState.ReadGPRSigned(inst.Rs) + MipsState.ReadGPRSigned(inst.Rt));
                    }
                    catch (OverflowException)
                    {
                        CauseException = ExceptionCode.OverFlow;
                    }
                }
            }
        }
コード例 #2
0
        private void Inst_Dmfc1(MipsInstruction inst)
        {
            if (!CheckCop1Usable())
            {
                CauseException = ExceptionCode.CopUnstable;
                return;
            }

            if (!CheckEvenOddAllowed(inst.Fs))
            {
                CauseFPUException(FPUExceptionType.Unimplemented);
                return;
            }

            UInt64 value = 0;

            if (MipsState.CP0Regs.StatusReg.AdditionalFPR)
            {
                value = MipsState.Fpr.ReadFPRUnsigned(inst.Fs);
            }
            else
            {
                value = MipsState.Fpr.ReadFPR32Unsigned(inst.Fs + 1) << 32;
                value |= MipsState.Fpr.ReadFPR32Unsigned(inst.Fs);
            }

            MipsState.WriteGPRUnsigned(inst.Rt, value);
        }
コード例 #3
0
 private void Inst_Addi(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         try
         {
             MipsState.WriteGPR32Signed(inst.Rt, MipsState.ReadGPR32Signed(inst.Rs) + (Int32)(Int16)inst.Immediate);
         }
         catch (OverflowException)
         {
             CauseException = ExceptionCode.OverFlow;
         }
     }
     else
     {
         try
         {
             MipsState.WriteGPRSigned(inst.Rt, MipsState.ReadGPRSigned(inst.Rs) + (Int64)(Int16)inst.Immediate);
         }
         catch (OverflowException)
         {
             CauseException = ExceptionCode.OverFlow;
         }
     }
 }
コード例 #4
0
 private void Inst_Bgez(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         DoBranch(MipsState.ReadGPR32Signed(inst.Rs) >= 0, inst);
     }
     else
     {
         DoBranch(MipsState.ReadGPRSigned(inst.Rs) >= 0, inst);
     }
 }
コード例 #5
0
 private void Inst_Beql(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         DoBranchLikely(MipsState.ReadGPR32Unsigned(inst.Rs) == MipsState.ReadGPR32Unsigned(inst.Rt), inst);
     }
     else
     {
         DoBranchLikely(MipsState.ReadGPRUnsigned(inst.Rs) == MipsState.ReadGPRUnsigned(inst.Rt), inst);
     }
 }
コード例 #6
0
        private void Inst_Teq(MipsInstruction inst)
        {
            Boolean condition;

            if (!MipsState.Operating64BitMode)
                condition = MipsState.ReadGPR32Unsigned(inst.Rs) == MipsState.ReadGPR32Unsigned(inst.Rt);
            else
                condition = MipsState.ReadGPRUnsigned(inst.Rs) == MipsState.ReadGPRUnsigned(inst.Rt);

            if (condition)
                CauseException = ExceptionCode.Trap;
        }
コード例 #7
0
        private void Inst_Cfc1(MipsInstruction inst)
        {
            if (!CheckCop1Usable())
            {
                CauseException = ExceptionCode.CopUnstable;
                return;
            }

            if (inst.Rd == 0)
            {
                MipsState.WriteGPRUnsigned(inst.Rd, MipsState.FCR0);
            }

            if (inst.Rd == 31)
            {
                MipsState.WriteGPRUnsigned(inst.Rd, MipsState.FCR31.RegisterValue);
            }
        }
コード例 #8
0
        private void Inst_Ctc1(MipsInstruction inst)
        {
            if (!CheckCop1Usable())
            {
                CauseException = ExceptionCode.CopUnstable;
                return;
            }

            if (inst.Fs == 0)
            {
                MipsState.FCR0 = MipsState.ReadGPR32Unsigned(inst.Rt);
            }

            if (inst.Fs == 31)
            {
                MipsState.FCR31.RegisterValue = MipsState.ReadGPR32Unsigned(inst.Rt);
            }
        }
コード例 #9
0
        private void Inst_Eret(MipsInstruction inst)
        {
            if (MipsState.CP0Regs.StatusReg.CopUsable0)
                CauseException = ExceptionCode.CopUnstable;

            if (MipsState.CP0Regs.StatusReg.ExceptionLevel)
            {
                MipsState.PC = (Int64)MipsState.CP0Regs.ErrorEPC;
                MipsState.CP0Regs.StatusReg.ExceptionLevel = false;
            }
            else
            {
                MipsState.PC = (Int64)MipsState.CP0Regs.EPC;
                MipsState.CP0Regs.StatusReg.ExceptionLevel = false;
            }

            MipsState.LLBit = false;
        }
コード例 #10
0
        private void Inst_Sllv(MipsInstruction inst)
        {
            Int32 shiftAmount = MipsState.ReadGPR32Signed(inst.Rs) & 0x1F;

            if (!MipsState.Operating64BitMode)
            {
                MipsState.WriteGPR32Unsigned(inst.Rd, MipsState.ReadGPR32Unsigned(inst.Rt) << shiftAmount);
            }
            else
            {
                UInt64 result = MipsState.ReadGPRUnsigned(inst.Rt) << shiftAmount;

                /* Truncate */
                if (shiftAmount == 0)
                {
                    MipsState.WriteGPRSigned(inst.Rd, (Int32)(UInt32)result);
                }
                else
                {
                    MipsState.WriteGPRUnsigned(inst.Rd, result);
                }
            }
        }
コード例 #11
0
ファイル: Interpreter_FPU.cs プロジェクト: TylerCode/Soft64
        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);
                }
            }
        }
コード例 #12
0
ファイル: Interpreter_FPU.cs プロジェクト: TylerCode/Soft64
        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);
                }
            }
        }
コード例 #13
0
ファイル: Interpreter_CP0.cs プロジェクト: TylerCode/Soft64
        private void Inst_Mfc0(MipsInstruction inst)
        {
            if (MipsState.CP0Regs.StatusReg.CopUsable0)
            {
                if (!MipsState.Operating64BitMode)
                {
                    MipsState.WriteGPR32Unsigned(inst.Rt, (UInt32)MipsState.CP0Regs[inst.Rd]);

                    /* Count register */
                    if (inst.Rt == 9)
                    {
                        MupenHelper.UpdateCount();
                    }
                }
                else
                {
                    MipsState.WriteGPRUnsigned(inst.Rt, MipsState.CP0Regs[inst.Rd]);
                }
            }
            else
            {
                CauseException = ExceptionCode.CopUnstable;
            }
        }
コード例 #14
0
ファイル: Interpreter_FPU.cs プロジェクト: TylerCode/Soft64
        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);
                }
            }
        }
コード例 #15
0
 private void Inst_Lbu(MipsInstruction inst)
 {
     try
     {
         if (!MipsState.Operating64BitMode)
         {
             MipsState.WriteGPR32Signed(inst.Rt, DataManipulator.LoadByteUnsigned(ComputeAddress32(inst)));
         }
         else
         {
             MipsState.WriteGPRSigned(inst.Rt, DataManipulator.LoadByteUnsigned(ComputeAddress64(inst)));
         }
     }
     catch (TLBException tlbe)
     {
         switch (tlbe.ExceptionType)
         {
             case TLBExceptionType.Invalid: CauseException = ExceptionCode.Invalid; break;
             case TLBExceptionType.Mod: CauseException = ExceptionCode.TlbMod; break;
             case TLBExceptionType.Refill: CauseException = ExceptionCode.TlbStore; break;
             default: break;
         }
     }
 }
コード例 #16
0
 private void Inst_Syscall(MipsInstruction inst)
 {
     CauseException = ExceptionCode.Syscall;
 }
コード例 #17
0
 private void Inst_Mtlo(MipsInstruction inst)
 {
     MipsState.Lo = MipsState.ReadGPRUnsigned(inst.Rs);
 }
コード例 #18
0
ファイル: Interpreter.cs プロジェクト: TylerCode/Soft64
 protected void DoBranchLikely(Boolean condition, MipsInstruction inst)
 {
     MipsState.NullifyEnabled = !condition;
     DoBranch(condition, inst);
 }
コード例 #19
0
ファイル: Interpreter_Main.cs プロジェクト: TylerCode/Soft64
 private void Inst_Break(MipsInstruction inst)
 {
     CauseException = ExceptionCode.Breakpoint;
 }
コード例 #20
0
 protected void DoBranchLikely(Boolean condition, MipsInstruction inst)
 {
     MipsState.NullifyEnabled = !condition;
     DoBranch(condition, inst);
 }
コード例 #21
0
 protected Int64 ComputeAddress64(MipsInstruction inst)
 {
     return (((Int64)(Int16)inst.Immediate) + MipsState.ReadGPRSigned(inst.Rs));
 }
コード例 #22
0
 private void Inst_tlbr(MipsInstruction inst)
 {
     /* Read Indexed TLB Entry:  TLB Entry[index] => TLB Registers */
     ParentMips.Tlb.Read();
 }
コード例 #23
0
 private void Inst_Jalr(MipsInstruction inst)
 {
     DoJump(MipsState.ReadGPRSigned(inst.Rs));
     MipsState.WriteGPRSigned(inst.Rd, inst.Address + 8);
 }
コード例 #24
0
 private void Inst_J(MipsInstruction inst)
 {
     DoJump(JumpComputeTargetAddress(inst));
 }
コード例 #25
0
 private void Inst_Jal(MipsInstruction inst)
 {
     MipsState.WriteGPRSigned(31, inst.Address + 8);
     DoJump(JumpComputeTargetAddress(inst));
 }
コード例 #26
0
 private void Inst_tlbp(MipsInstruction inst)
 {
     /* Probe the TLB */
     ParentMips.Tlb.Probe();
 }
コード例 #27
0
 private void Inst_tlbwr(MipsInstruction inst)
 {
     /* Write Random TLB Entry: TLB Registers => TLB Entry[random_index] */
     ParentMips.Tlb.WriteRandom();
 }
コード例 #28
0
 private void Inst_tlbwi(MipsInstruction inst)
 {
     /* Write Indexed TLB Entry: TLB Registers => TLB Entry[index] */
     ParentMips.Tlb.Write();
 }
コード例 #29
0
        private void Inst_Teqi(MipsInstruction inst)
        {
            Boolean condition;

            if (!MipsState.Operating64BitMode)
                condition = MipsState.ReadGPR32Signed(inst.Rs) == (Int32)(Int16)inst.Immediate;
            else
                condition = MipsState.ReadGPRSigned(inst.Rs) == (Int64)(Int16)inst.Immediate;

            if (condition)
                CauseException = ExceptionCode.Trap;
        }
コード例 #30
0
        private void OpCall(MipsOp[] callTable, Int32 index, MipsInstruction inst)
        {
            /* NOP */
            if (inst.Instruction == 0)
                return;

            MipsOp call = callTable[index];

            if (call != null)
            {
                call(inst);
            }
            else
            {
                throw new InvalidOperationException("Unsupport Instruction: " + inst.ToString());
            }
        }
コード例 #31
0
ファイル: Interpreter.cs プロジェクト: TylerCode/Soft64
 public static Int64 BranchComputeTargetAddress(MipsInstruction inst)
 {
     return((inst.Address + 4) + (((Int64)(Int16)inst.Immediate) << 2));
 }
コード例 #32
0
ファイル: Interpreter.cs プロジェクト: TylerCode/Soft64
 protected Int64 ComputeAddress(MipsInstruction inst)
 {
     return(((Int64)(Int16)inst.Immediate) + MipsState.ReadGPRSigned(inst.Rs));
 }
コード例 #33
0
 private Boolean CheckEvenOddAllowed(MipsInstruction inst)
 {
     if (MipsState.CP0Regs.StatusReg.AdditionalFPR)
     {
         return true;
     }
     else
     {
         return
             (inst.Fd % 2 == 0) &&
             (inst.Fs % 2 == 0) &&
             (inst.Ft % 2 == 0);
     }
 }
コード例 #34
0
ファイル: Interpreter.cs プロジェクト: TylerCode/Soft64
 public static Int64 JumpComputeTargetAddress(MipsInstruction inst)
 {
     return((inst.Target << 2) | ((inst.Address + 4) & 0xFFFF0000));
 }
コード例 #35
0
 protected void CallInstruction(MipsInstruction inst)
 {
     OpCall(m_OpsTableMain, inst.Opcode, inst);
 }
コード例 #36
0
ファイル: Interpreter_Main.cs プロジェクト: TylerCode/Soft64
 private void Inst_Mtlo(MipsInstruction inst)
 {
     MipsState.Lo = MipsState.ReadGPRUnsigned(inst.Rs);
 }
コード例 #37
0
 protected void DoBranch(Boolean condition, MipsInstruction inst)
 {
     MipsState.BranchEnabled = true;
     MipsState.BranchDelaySlot = MipsState.PC + 4;
     MipsState.BranchTarget = condition ? BranchComputeTargetAddress(inst.Address, inst.Immediate): MipsState.PC + 8;
 }
コード例 #38
0
ファイル: Interpreter_Main.cs プロジェクト: TylerCode/Soft64
 private void Inst_Syscall(MipsInstruction inst)
 {
     CauseException = ExceptionCode.Syscall;
 }
コード例 #39
0
ファイル: Interpreter_Main.cs プロジェクト: TylerCode/Soft64
 private void Inst_Cache(MipsInstruction inst)
 {
     logger.Debug("Cache instruction ignored");
 }
コード例 #40
0
 private void Inst_Cache(MipsInstruction inst)
 {
     logger.Debug("Cache instruction ignored");
 }
コード例 #41
0
ファイル: Interpreter_Main.cs プロジェクト: TylerCode/Soft64
 private void Inst_Mflo(MipsInstruction inst)
 {
     MipsState.WriteGPRUnsigned(inst.Rd, MipsState.Lo);
 }
コード例 #42
0
ファイル: Interpreter.cs プロジェクト: TylerCode/Soft64
 protected void DoBranch(Boolean condition, MipsInstruction inst)
 {
     MipsState.BranchEnabled   = true;
     MipsState.BranchDelaySlot = MipsState.PC + 4;
     MipsState.BranchTarget    = condition ? MapAddress(BranchComputeTargetAddress(inst)) : MipsState.PC + 8;
 }
コード例 #43
0
ファイル: Interpreter_Main.cs プロジェクト: TylerCode/Soft64
 private void Inst_Sync(MipsInstruction inst)
 {
     /* LOL Just ignore this, we know loads and stores always finish before SYNC opcode */
     return;
 }
コード例 #44
0
 private void Inst_Scd(MipsInstruction inst)
 {
     /* This is used in atomic operations, for now let it always pass */
     MipsState.WriteGPRUnsigned(inst.Rt, 1);
     Inst_Sd(inst);
 }
コード例 #45
0
 private void Inst_Break(MipsInstruction inst)
 {
     CauseException = ExceptionCode.Breakpoint;
 }
コード例 #46
0
        private void Inst_Sb(MipsInstruction inst)
        {
            Int64 address = ComputeAddress(inst);

            DataManipulator.Store(address, MipsState.ReadGPRUnsigned(inst.Rt) & 0xFF);
        }
コード例 #47
0
 private void Inst_Mflo(MipsInstruction inst)
 {
     MipsState.WriteGPRUnsigned(inst.Rd, MipsState.Lo);
 }
コード例 #48
0
 private void Inst_Bc1tl(MipsInstruction inst)
 {
     DoBranchLikely(MipsState.FCR31.Condition, inst);
 }
コード例 #49
0
 private void Inst_Sync(MipsInstruction inst)
 {
     /* LOL Just ignore this, we know loads and stores always finish before SYNC opcode */
     return;
 }
コード例 #50
0
 private void Inst_tlbp(MipsInstruction inst)
 {
     /* Probe the TLB */
     ParentMips.Tlb.Probe();
 }
コード例 #51
0
 private void Inst_Bc1f(MipsInstruction inst)
 {
     DoBranch(MipsState.FCR31.Condition, inst);
 }
コード例 #52
0
 private void Inst_tlbwi(MipsInstruction inst)
 {
     /* Write Indexed TLB Entry: TLB Registers => TLB Entry[index] */
     ParentMips.Tlb.Write();
 }
コード例 #53
0
 private void Inst_Addiu(MipsInstruction inst)
 {
     unchecked
     {
         if (!MipsState.Operating64BitMode)
         {
             MipsState.WriteGPR32Unsigned(inst.Rt, MipsState.ReadGPR32Unsigned(inst.Rs) + (UInt32)(Int32)(Int16)inst.Immediate);
         }
         else
         {
             if (MipsState.ReadGPRUnsigned(inst.Rs).IsSigned32())
             {
                 MipsState.WriteGPRUnsigned(inst.Rt, MipsState.ReadGPRUnsigned(inst.Rs) + (UInt64)(Int64)(Int16)inst.Immediate);
             }
         }
     }
 }
コード例 #54
0
ファイル: Interpreter.cs プロジェクト: TylerCode/Soft64
 protected void CallInstruction(MipsInstruction inst)
 {
     OpCall(m_OpsTableMain, inst.Opcode, inst);
 }
コード例 #55
0
 private void Inst_tlbr(MipsInstruction inst)
 {
     /* Read Indexed TLB Entry:  TLB Entry[index] => TLB Registers */
     ParentMips.Tlb.Read();
 }
コード例 #56
0
 protected void TraceOp(Int64 pc, MipsInstruction inst)
 {
     if (logger.IsDebugEnabled)
         logger.Debug("{0:X8} {1:X4} {2:X4} {3}", pc, inst.Instruction >> 16, inst.Instruction & 0xFFFF, inst.ToString());
 }
コード例 #57
0
 private void Inst_tlbwr(MipsInstruction inst)
 {
     /* Write Random TLB Entry: TLB Registers => TLB Entry[random_index] */
     ParentMips.Tlb.WriteRandom();
 }
コード例 #58
0
 private void Inst_Jr(MipsInstruction inst)
 {
     DoJump(MipsState.ReadGPRSigned(inst.Rs));
 }
コード例 #59
0
 private void Inst_Nor(MipsInstruction inst)
 {
     MipsState.WriteGPRUnsigned(inst.Rd, ~(MipsState.ReadGPRUnsigned(inst.Rs) | MipsState.ReadGPRUnsigned(inst.Rt)));
 }
コード例 #60
0
 private void Inst_Xori(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         MipsState.WriteGPR32Signed(inst.Rt, MipsState.ReadGPR32Signed(inst.Rs) ^ (Int32)(Int16)inst.Immediate);
     }
     else
     {
         MipsState.WriteGPRSigned(inst.Rt, MipsState.ReadGPRSigned(inst.Rs) ^ (Int64)(Int16)inst.Immediate);
     }
 }