private void Inst_Subu(MipsInstruction inst) { unchecked { MipsState.WriteGPR32Unsigned(inst.Rd, MipsState.ReadGPR32Unsigned(inst.Rs) - MipsState.ReadGPR32Unsigned(inst.Rt)); } }
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; } } }
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); } }
private void Inst_Swr(MipsInstruction inst) { /* Thanks to PJ64 */ Int64 address = ComputeAddress(inst); Int32 offset = (Int32)(address & 3); UInt32 value = DataManipulator.LoadWordUnsigned(address & ~3); value &= SWRMask[offset]; value += MipsState.ReadGPR32Unsigned(inst.Rt) << SWRShift[offset]; DataManipulator.Store(address & ~3, value); }
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)); } }
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); } }
private void Inst_Srl(MipsInstruction inst) { UInt32 result = MipsState.ReadGPR32Unsigned(inst.Rt) >> inst.ShiftAmount; if (!MipsState.Operating64BitMode) { MipsState.WriteGPR32Unsigned(inst.Rd, result); } else { MipsState.WriteGPRUnsigned(inst.Rd, (UInt64)(Int64)(Int16)result); } }
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); } }
private void Inst_Srvl(MipsInstruction inst) { UInt32 result = MipsState.ReadGPR32Unsigned(inst.Rt) >> MipsState.ReadGPR32Signed(inst.Rs) & 0x1F; if (!MipsState.Operating64BitMode) { MipsState.WriteGPR32Unsigned(inst.Rd, result); } else { MipsState.WriteGPRUnsigned(inst.Rd, (UInt32)(Int32)result); } }
private void Inst_Sw(MipsInstruction inst) { Int64 address = ComputeAddress(inst); if ((address & 3) != 0) { CauseException = ExceptionCode.AddressErrorStore; } else { DataManipulator.Store(address, MipsState.ReadGPR32Unsigned(inst.Rt)); } }
private void Inst_Multu(MipsInstruction inst) { if (!MipsState.Operating64BitMode) { UInt64 product = MipsState.ReadGPR32Unsigned(inst.Rs) * MipsState.ReadGPR32Unsigned(inst.Rt); MipsState.Hi = product >> 32; MipsState.Lo = product & 0xFFFF; } else { UInt64 product = (UInt64)(Int64)(Int32)MipsState.ReadGPR32Unsigned(inst.Rs) * (UInt64)(Int64)(Int32)MipsState.ReadGPR32Unsigned(inst.Rt); MipsState.Hi = product >> 32; MipsState.Lo = product & 0xFFFF; } }
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)); } } } }
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); } } } }
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); } }
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; } }
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; } }
private void Inst_Mtc1(MipsInstruction inst) { if (!CheckCop1Usable()) { CauseException = ExceptionCode.CopUnstable; return; } UInt32 value = MipsState.ReadGPR32Unsigned(inst.Rt); if (MipsState.CP0Regs.StatusReg.AdditionalFPR) { MipsState.Fpr.WriteFPRUnsigned(inst.Fs, value); } else { MipsState.Fpr.WriteFPR32Unsigned(inst.Fs, value); } }
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; } }
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); } } }
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; } }