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; } } }
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; } } } }
private void Inst_Slt(MipsInstruction inst) { if (!MipsState.Operating64BitMode) { if (MipsState.ReadGPR32Signed(inst.Rs) < MipsState.ReadGPR32Signed(inst.Rt)) { MipsState.GPRRegs[inst.Rd] = 1; } else { MipsState.GPRRegs[inst.Rd] = 0; } } else { if (MipsState.ReadGPRSigned(inst.Rs) < MipsState.ReadGPRSigned(inst.Rt)) { MipsState.GPRRegs[inst.Rd] = 1; } else { MipsState.GPRRegs[inst.Rd] = 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); } }
private void Inst_Bgez(MipsInstruction inst) { if (!MipsState.Operating64BitMode) { DoBranch(MipsState.ReadGPR32Signed(inst.Rs) >= 0, inst); } else { DoBranch(MipsState.ReadGPRSigned(inst.Rs) >= 0, inst); } }
private void Inst_Bltzl(MipsInstruction inst) { if (!MipsState.Operating64BitMode) { DoBranchLikely(MipsState.ReadGPR32Signed(inst.Rs) < 0, inst); } else { DoBranchLikely(MipsState.ReadGPRSigned(inst.Rs) < 0, inst); } }
private void Inst_Sub(MipsInstruction inst) { try { MipsState.WriteGPR32Signed(inst.Rd, MipsState.ReadGPR32Signed(inst.Rs) - MipsState.ReadGPR32Signed(inst.Rt)); } catch (OverflowException) { CauseException = ExceptionCode.OverFlow; } }
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_Srav(MipsInstruction inst) { Int32 result = MipsState.ReadGPR32Signed(inst.Rt) >> (MipsState.ReadGPR32Signed(inst.Rs) & 0x1F); if (!MipsState.Operating64BitMode) { MipsState.WriteGPR32Signed(inst.Rd, result); } else { MipsState.WriteGPRSigned(inst.Rd, result); } }
private void Inst_Sra(MipsInstruction inst) { Int32 result = MipsState.ReadGPR32Signed(inst.Rt) >> inst.ShiftAmount; if (!MipsState.Operating64BitMode) { MipsState.WriteGPR32Signed(inst.Rd, result); } else { MipsState.WriteGPRSigned(inst.Rd, result); } }
private void Inst_Slti(MipsInstruction inst) { if (!MipsState.Operating64BitMode) { Boolean condition = MipsState.ReadGPR32Signed(inst.Rs) < ((Int32)(Int16)inst.Immediate); MipsState.WriteGPR32Unsigned(inst.Rt, condition ? 1U : 0U); } else { Boolean condition = MipsState.ReadGPRSigned(inst.Rs) < ((Int64)(Int16)inst.Immediate); MipsState.WriteGPRUnsigned(inst.Rt, condition ? 1UL : 0UL); } }
private void Inst_Mult(MipsInstruction inst) { if (!MipsState.Operating64BitMode) { Int64 product = MipsState.ReadGPR32Signed(inst.Rs) * MipsState.ReadGPR32Signed(inst.Rt); MipsState.Hi = (UInt64)(product >> 32); MipsState.Lo = (UInt64)(product & 0xFFFF); } else { Int64 product = (Int64)MipsState.ReadGPR32Signed(inst.Rs) * (Int64)MipsState.ReadGPR32Signed(inst.Rt); MipsState.Hi = (UInt64)(product >> 32); MipsState.Lo = (UInt64)(product & 0xFFFF); } }
private void Inst_Tlt(MipsInstruction inst) { Boolean condition; if (!MipsState.Operating64BitMode) { condition = MipsState.ReadGPR32Signed(inst.Rs) < MipsState.ReadGPR32Signed(inst.Rt); } else { condition = MipsState.ReadGPRSigned(inst.Rs) < MipsState.ReadGPRSigned(inst.Rt); } if (condition) { CauseException = ExceptionCode.Trap; } }
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; } }
private void Inst_Div(MipsInstruction inst) { try { unchecked { if (!MipsState.Addressing64BitMode || (MipsState.ReadGPRUnsigned(inst.Rs).IsSigned32() && MipsState.ReadGPRUnsigned(inst.Rt).IsSigned32())) { /* Data input is always the size of a MIPS word */ MipsState.Hi = (UInt64)(MipsState.ReadGPR32Signed(inst.Rs) / MipsState.ReadGPR32Signed(inst.Rt)); MipsState.Lo = (UInt64)(MipsState.ReadGPR32Signed(inst.Rs) % MipsState.ReadGPR32Signed(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_Dsrav(MipsInstruction inst) { if (MipsState.Operating64BitMode) { MipsState.WriteGPRSigned(inst.Rd, MipsState.ReadGPRSigned(inst.Rt) >> (MipsState.ReadGPR32Signed(inst.Rs) & 0x3F)); } else { CauseException = ExceptionCode.ReservedInstruction; } }