Example #1
0
        private void Inst_Dmtc1(MipsInstruction inst)
        {
            if (!CheckCop1Usable())
            {
                CauseException = ExceptionCode.CopUnstable;
                return;
            }

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

            UInt64 value = MipsState.ReadGPRUnsigned(inst.Rt);

            if (MipsState.CP0Regs.StatusReg.AdditionalFPR)
            {
                MipsState.Fpr.WriteFPRUnsigned(inst.Fs, value);
            }
            else
            {
                MipsState.Fpr.WriteFPR32Unsigned(inst.Fs + 1, (UInt32)(value >> 32));
                MipsState.Fpr.WriteFPR32Unsigned(inst.Fs, (UInt32)(value & 0xFFFFFFFF));
            }
        }
Example #2
0
 private void Inst_Sltu(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         if (MipsState.ReadGPR32Unsigned(inst.Rs) < MipsState.ReadGPR32Unsigned(inst.Rt))
         {
             MipsState.GPRRegs[inst.Rd] = 1;
         }
         else
         {
             MipsState.GPRRegs[inst.Rd] = 0;
         }
     }
     else
     {
         if (MipsState.ReadGPRUnsigned(inst.Rs) < MipsState.ReadGPRUnsigned(inst.Rt))
         {
             MipsState.GPRRegs[inst.Rd] = 1;
         }
         else
         {
             MipsState.GPRRegs[inst.Rd] = 0;
         }
     }
 }
Example #3
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;
             }
         }
     }
 }
Example #4
0
        private void Inst_Mtc0(MipsInstruction inst)
        {
            if (MipsState.CP0Regs.StatusReg.CopUsable0)
            {
                var regType = (CP0RegName)inst.Rd;

                switch (regType)
                {
                default: MipsState.CP0Regs[inst.Rd] = MipsState.ReadGPRUnsigned(inst.Rt); break;

                case CP0RegName.Count:
                {
                    UInt32 count    = (UInt32)MipsState.CP0Regs[inst.Rd];
                    UInt32 newCount = (UInt32)MipsState.ReadGPRUnsigned(inst.Rt);
                    MipsState.CP0Regs.Count = newCount;
                    MupenHelper.UpdateCount();

                    if (MupenHelper.NextInterrupt <= count)
                    {
                        MupenHelper.GenInterrupt();
                    }

                    MupenHelper.TranslateEventQueue(newCount);
                    break;
                }

                case CP0RegName.Compare:
                {
                    UInt32 newCompare = (UInt32)MipsState.ReadGPRUnsigned(inst.Rt);
                    MipsState.CP0Regs.Compare = newCompare;
                    MupenHelper.UpdateCount();
                    MupenHelper.RemoveEvent(MupenHelper.COMPARE_INT);
                    MupenHelper.AddInterruptEventCount(MupenHelper.COMPARE_INT, newCompare);
                    MipsState.CP0Regs.Cause &= 0xFFFF7FFFU;
                    break;
                }

                case CP0RegName.SR:
                {
                    UInt32 newStatus = (UInt32)MipsState.ReadGPRUnsigned(inst.Rt);
                    MipsState.CP0Regs.Status = newStatus;

                    MupenHelper.UpdateCount();
                    MupenHelper.CheckInterrupt();

                    if (MupenHelper.NextInterrupt <= MipsState.CP0Regs.Count)
                    {
                        MupenHelper.GenInterrupt();
                    }

                    break;
                }
                }
            }
            else
            {
                CauseException = ExceptionCode.CopUnstable;
            }
        }
Example #5
0
 private void Inst_Dmtc0(MipsInstruction inst)
 {
     if (MipsState.Operating64BitMode)
     {
         MipsState.CP0Regs[inst.Rd] = MipsState.ReadGPRUnsigned(inst.Rt);
     }
     else
     {
         CauseException = ExceptionCode.ReservedInstruction;
     }
 }
Example #6
0
 private void Inst_Bnel(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);
     }
 }
Example #7
0
 private void Inst_Dsrl32(MipsInstruction inst)
 {
     if (MipsState.Operating64BitMode)
     {
         MipsState.WriteGPRUnsigned(inst.Rd, MipsState.ReadGPRUnsigned(inst.Rt) >> (32 + inst.ShiftAmount));
     }
     else
     {
         CauseException = ExceptionCode.ReservedInstruction;
     }
 }
Example #8
0
 private void Inst_Dsrlv(MipsInstruction inst)
 {
     if (MipsState.Operating64BitMode)
     {
         MipsState.WriteGPRUnsigned(inst.Rd, MipsState.ReadGPRUnsigned(inst.Rt) >> (Int32)(MipsState.ReadGPR32Unsigned(inst.Rs) & 0x3FUL));
     }
     else
     {
         CauseException = ExceptionCode.ReservedInstruction;
     }
 }
Example #9
0
 private void Inst_Xor(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         MipsState.WriteGPR32Unsigned(inst.Rd, MipsState.ReadGPR32Unsigned(inst.Rs) ^ MipsState.ReadGPR32Unsigned(inst.Rt));
     }
     else
     {
         MipsState.WriteGPRUnsigned(inst.Rd, MipsState.ReadGPRUnsigned(inst.Rs) ^ MipsState.ReadGPRUnsigned(inst.Rt));
     }
 }
Example #10
0
 private void Inst_Andi(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         MipsState.WriteGPR32Unsigned(inst.Rt, MipsState.ReadGPR32Unsigned(inst.Rs) & (UInt32)inst.Immediate);
     }
     else
     {
         MipsState.WriteGPRUnsigned(inst.Rt, MipsState.ReadGPRUnsigned(inst.Rs) & (UInt64)inst.Immediate);
     }
 }
Example #11
0
        private void Inst_Sh(MipsInstruction inst)
        {
            Int64 address = ComputeAddress(inst);

            if ((address & 1) != 0)
            {
                CauseException = ExceptionCode.AddressErrorStore;
                return;
            }

            DataManipulator.Store(address, (UInt16)MipsState.ReadGPRUnsigned(inst.Rt));
        }
Example #12
0
 private void Inst_Sltiu(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         Boolean condition = MipsState.ReadGPR32Unsigned(inst.Rs) < ((UInt32)(Int32)(Int16)inst.Immediate);
         MipsState.WriteGPR32Unsigned(inst.Rt, condition ? 1U : 0U);
     }
     else
     {
         Boolean condition = MipsState.ReadGPRUnsigned(inst.Rs) < ((UInt64)(Int64)(Int16)inst.Immediate);
         MipsState.WriteGPRUnsigned(inst.Rt, condition ? 1UL : 0UL);
     }
 }
Example #13
0
 private void Inst_Dsubu(MipsInstruction inst)
 {
     if (MipsState.Operating64BitMode)
     {
         unchecked
         {
             MipsState.WriteGPRUnsigned(inst.Rd, MipsState.ReadGPRUnsigned(inst.Rs) - MipsState.ReadGPRUnsigned(inst.Rt));
         }
     }
     else
     {
         CauseException = ExceptionCode.ReservedInstruction;
     }
 }
Example #14
0
 private void Inst_Daddiu(MipsInstruction inst)
 {
     if (!MipsState.Operating64BitMode)
     {
         CauseException = ExceptionCode.ReservedInstruction;
     }
     else
     {
         unchecked
         {
             MipsState.WriteGPRUnsigned(inst.Rd, MipsState.ReadGPRUnsigned(inst.Rs) + (UInt64)(Int64)(Int16)inst.Immediate);
         }
     }
 }
Example #15
0
        private void Inst_Dmultu(MipsInstruction inst)
        {
            if (MipsState.Operating64BitMode)
            {
                BigInteger product = BigInteger.Multiply(
                    new BigInteger(MipsState.ReadGPRUnsigned(inst.Rs)),
                    new BigInteger(MipsState.ReadGPRUnsigned(inst.Rt)));

                MipsState.Lo = (UInt64)(product & 0xFFFFFFFFFFFFFFFFUL);
                MipsState.Hi = (UInt64)((product >> 64) & 0xFFFFFFFFFFFFFFFFUL);
            }
            else
            {
                CauseException = ExceptionCode.ReservedInstruction;
            }
        }
Example #16
0
 private void Inst_Ldr(MipsInstruction inst)
 {
     if (MipsState.Operating64BitMode)
     {
         /* Thanks to PJ64 Implementation */
         Int64  address = ComputeAddress(inst);
         Int32  offset  = (Int32)(address & 7);
         UInt64 value   = DataManipulator.LoadDoublewordUnsigned(address & ~7);
         MipsState.WriteGPRUnsigned(inst.Rt, MipsState.ReadGPRUnsigned(inst.Rt) & LDRMask[offset]);
         MipsState.WriteGPRUnsigned(inst.Rt, MipsState.ReadGPRUnsigned(inst.Rt) + (value >> LDRShift[offset]));
     }
     else
     {
         CauseException = ExceptionCode.ReservedInstruction;
     }
 }
Example #17
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);
             }
         }
     }
 }
Example #18
0
 private void Inst_Sdr(MipsInstruction inst)
 {
     if (MipsState.Operating64BitMode)
     {
         /* Thanks to PJ64 implementation */
         Int64  address = ComputeAddress(inst);
         Int32  offset  = (Int32)(address & 7);
         UInt64 value   = DataManipulator.LoadDoublewordUnsigned(address & ~7);
         value &= SDRMask[offset];
         value += MipsState.ReadGPRUnsigned(inst.Rt) << SDLShift[offset];
         DataManipulator.Store(address & ~7, value);
     }
     else
     {
         CauseException = ExceptionCode.ReservedInstruction;
     }
 }
Example #19
0
 private void Inst_Addu(MipsInstruction inst)
 {
     unchecked
     {
         if (!MipsState.Operating64BitMode)
         {
             MipsState.WriteGPR32Unsigned(inst.Rd, MipsState.ReadGPR32Unsigned(inst.Rs) + MipsState.ReadGPR32Unsigned(inst.Rt));
         }
         else
         {
             if (MipsState.ReadGPRUnsigned(inst.Rs).IsSigned32() && MipsState.ReadGPRUnsigned(inst.Rt).IsSigned32())
             {
                 MipsState.WriteGPRUnsigned(inst.Rd, MipsState.ReadGPRUnsigned(inst.Rs) + MipsState.ReadGPRUnsigned(inst.Rt));
             }
         }
     }
 }
Example #20
0
        private void Inst_Tltiu(MipsInstruction inst)
        {
            Boolean condition;

            if (!MipsState.Operating64BitMode)
            {
                condition = MipsState.ReadGPR32Unsigned(inst.Rs) < (UInt32)(Int32)(Int16)inst.Immediate;
            }
            else
            {
                condition = MipsState.ReadGPRUnsigned(inst.Rs) < (UInt64)(Int64)(Int16)inst.Immediate;
            }

            if (condition)
            {
                CauseException = ExceptionCode.Trap;
            }
        }
Example #21
0
        private void Inst_Sd(MipsInstruction inst)
        {
            if (!MipsState.Operating64BitMode)
            {
                throw new InvalidOperationException("Instruction reserved");
            }

            Int64 address = (MipsState.ReadGPRSigned(inst.Rs) + (Int64)inst.Immediate);

            if ((address & 7) != 0)
            {
                CauseException = ExceptionCode.AddressErrorStore;
            }
            else
            {
                DataManipulator.Store(address, MipsState.ReadGPRUnsigned(inst.Rt));
            }
        }
Example #22
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;
            }
        }
Example #23
0
 private void Inst_Divu(MipsInstruction inst)
 {
     try
     {
         unchecked
         {
             if (!MipsState.Operating64BitMode || (MipsState.ReadGPRUnsigned(inst.Rs).IsSigned32() && MipsState.ReadGPRUnsigned(inst.Rt).IsSigned32()))
             {
                 /* Data input is always the size of a MIPS word */
                 MipsState.Hi = (UInt64)(MipsState.ReadGPR32Unsigned(inst.Rs) / MipsState.ReadGPR32Unsigned(inst.Rt));
                 MipsState.Lo = (UInt64)(MipsState.ReadGPR32Unsigned(inst.Rs) % MipsState.ReadGPR32Unsigned(inst.Rt));
             }
         }
     }
     catch (DivideByZeroException)
     {
         MipsState.Hi = 0;
         MipsState.Lo = 0;
         return;
     }
 }
Example #24
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);
                }
            }
        }
Example #25
0
        private void Inst_Sb(MipsInstruction inst)
        {
            Int64 address = ComputeAddress(inst);

            DataManipulator.Store(address, MipsState.ReadGPRUnsigned(inst.Rt) & 0xFF);
        }
Example #26
0
 private void Inst_Nor(MipsInstruction inst)
 {
     MipsState.WriteGPRUnsigned(inst.Rd, ~(MipsState.ReadGPRUnsigned(inst.Rs) | MipsState.ReadGPRUnsigned(inst.Rt)));
 }
Example #27
0
 private void Inst_Mtlo(MipsInstruction inst)
 {
     MipsState.Lo = MipsState.ReadGPRUnsigned(inst.Rs);
 }