private void populateJTypeExecutors() { JTypeExecutors = new Dictionary <JumpType, Action <JTypeInstruction, IStateAccessor> > { { JumpType.Jump, (x, StateAccessor) => { var pc = StateAccessor.GetPc() & 0xFC000000; pc |= x.Target << 2; StateAccessor.SetPc(pc); } }, { JumpType.JumpAndLink, (x, StateAccessor) => { StateAccessor.WriteRegister(31, StateAccessor.GetPc() + 4); var pc = StateAccessor.GetPc() & 0xFC000000; pc |= x.Target << 2; StateAccessor.SetPc(pc); } }, }; }
private void populateRTypeExecutors() { RTypeExecutors = new Dictionary <RTypeFunction, Action <RTypeInstruction, IStateAccessor> > { { RTypeFunction.Add, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, (uint)(((int)StateAccessor.ReadRegister(r.Rs)) + (int)(StateAccessor.ReadRegister(r.Rt)))); } }, { RTypeFunction.UnsignedAdd, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, StateAccessor.ReadRegister(r.Rs) + StateAccessor.ReadRegister(r.Rt)); } }, { RTypeFunction.BitwiseAnd, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, StateAccessor.ReadRegister(r.Rs) & StateAccessor.ReadRegister(r.Rt)); } }, { RTypeFunction.Break, (r, StateAccessor) => { StateAccessor.SetEpc(StateAccessor.GetPc()); StateAccessor.SetPc(0x3c); StateAccessor.Skip(); } }, { RTypeFunction.Divide, (r, StateAccessor) => { var dividend = (int)StateAccessor.ReadRegister(r.Rs); var divisor = (int)StateAccessor.ReadRegister(r.Rt); StateAccessor.SetHi((uint)(dividend % divisor)); StateAccessor.SetLo((uint)(dividend / divisor)); } }, { RTypeFunction.UnsignedDivide, (r, StateAccessor) => { var dividend = StateAccessor.ReadRegister(r.Rs); var divisor = StateAccessor.ReadRegister(r.Rt); StateAccessor.SetHi(dividend % divisor); StateAccessor.SetLo(dividend / divisor); } }, { RTypeFunction.JumpAndLinkRegister, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, StateAccessor.GetPc() + 4); StateAccessor.SetPc(StateAccessor.ReadRegister(r.Rs)); } }, { RTypeFunction.JumpRegister, (r, StateAccessor) => { StateAccessor.SetPc(StateAccessor.ReadRegister(r.Rs)); } }, { RTypeFunction.MoveFromHi, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, StateAccessor.GetHi()); } }, { RTypeFunction.MoveFromLo, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, StateAccessor.GetLo()); } }, { RTypeFunction.MoveToHi, (r, StateAccessor) => { StateAccessor.SetHi(StateAccessor.ReadRegister(r.Rs)); } }, { RTypeFunction.MoveToLo, (r, StateAccessor) => { StateAccessor.SetLo(StateAccessor.ReadRegister(r.Rs)); } }, { RTypeFunction.Multiply, (r, StateAccessor) => { var a = (long)(int)StateAccessor.ReadRegister(r.Rs); var b = (long)(int)StateAccessor.ReadRegister(r.Rt); long result = a * b; StateAccessor.SetLo((uint)((int)result)); StateAccessor.SetHi((uint)(result >> 32)); } }, { RTypeFunction.UnsignedMultiply, (r, StateAccessor) => { var a = (ulong)StateAccessor.ReadRegister(r.Rs); var b = (ulong)StateAccessor.ReadRegister(r.Rt); var result = a * b; StateAccessor.SetLo((uint)result); StateAccessor.SetHi((uint)(result >> 32)); } }, { RTypeFunction.BitwiseNor, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, ~(StateAccessor.ReadRegister(r.Rs) | StateAccessor.ReadRegister(r.Rt))); } }, { RTypeFunction.BitwiseOr, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, (StateAccessor.ReadRegister(r.Rs) | StateAccessor.ReadRegister(r.Rt))); } }, { RTypeFunction.ShiftLeftLogical, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rt); var b = (int)r.Sa; StateAccessor.WriteRegister(r.Rd, a << b); } }, { RTypeFunction.ShiftLeftLogicalVariable, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rt); var b = (int)StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rd, a << b); } }, { RTypeFunction.SetOnLessThan, (r, StateAccessor) => { var a = (int)StateAccessor.ReadRegister(r.Rs); var b = (int)StateAccessor.ReadRegister(r.Rt); StateAccessor.WriteRegister(r.Rd, a < b ? 1u : 0u); } }, { RTypeFunction.UnsignedSetOnLessThan, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rs); var b = StateAccessor.ReadRegister(r.Rt); StateAccessor.WriteRegister(r.Rd, a < b ? 1u : 0u); } }, { RTypeFunction.ShiftRightArithmetic, (r, StateAccessor) => { var a = (int)StateAccessor.ReadRegister(r.Rt); var b = (int)r.Sa; StateAccessor.WriteRegister(r.Rd, (uint)(a >> b)); } }, { RTypeFunction.ShiftRightArithmeticVariable, (r, StateAccessor) => { var a = (int)StateAccessor.ReadRegister(r.Rt); var b = (int)StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rd, (uint)(a >> b)); } }, { RTypeFunction.ShiftRightLogical, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rt); var b = (int)r.Sa; StateAccessor.WriteRegister(r.Rd, a >> b); } }, { RTypeFunction.ShiftRightLogicalVariable, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rt); var b = (int)StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rd, a >> b); } }, { RTypeFunction.Subtract, (r, StateAccessor) => { var a = (int)StateAccessor.ReadRegister(r.Rs); var b = (int)StateAccessor.ReadRegister(r.Rt); StateAccessor.WriteRegister(r.Rd, (uint)(a - b)); } }, { RTypeFunction.UnsignedSubtract, (r, StateAccessor) => { var a = (int)StateAccessor.ReadRegister(r.Rs); var b = (int)StateAccessor.ReadRegister(r.Rt); StateAccessor.WriteRegister(r.Rd, (uint)(a - b)); } }, { RTypeFunction.Syscall, (r, StateAccessor) => { StateAccessor.SetEpc(StateAccessor.GetPc()); StateAccessor.SetPc(0x3c); StateAccessor.Skip(); } }, { RTypeFunction.BitwiseExclusiveOr, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rd, (StateAccessor.ReadRegister(r.Rs) ^ StateAccessor.ReadRegister(r.Rt))); } }, }; }
private void populateITypeExecutors() { ITypeExecutors = new Dictionary <Opcode, Action <ITypeInstruction, IStateAccessor> > { { Opcode.AddImmediate, (r, StateAccessor) => { var a = (int)StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rt, (uint)(a + ((short)r.Immediate))); } }, { Opcode.UnsignedAddImmediate, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rt, (uint)(a + (short)r.Immediate)); } }, { Opcode.BitwiseAndImmediate, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rt, a & r.Immediate); } }, { Opcode.BranchOnEqual, (r, StateAccessor) => { var rs = StateAccessor.ReadRegister(r.Rs); var rt = StateAccessor.ReadRegister(r.Rt); if (rs == rt) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } } }, { Opcode.Branch, (r, StateAccessor) => { var rs = (int)StateAccessor.ReadRegister(r.Rs); var rt = r.Rt; switch (rt) { case 0: if (rs < 0) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } break; case 1: if (rs >= 0) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } break; case 16: StateAccessor.WriteRegister(31, StateAccessor.GetPc() + 4); if (rs < 0) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } break; case 17: StateAccessor.WriteRegister(31, StateAccessor.GetPc() + 4); if (rs >= 0) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } break; default: throw new InvalidOperationException(String.Format("Invalid Branch {0}", rt)); } } }, { Opcode.BranchOnGreaterThanZero, (r, StateAccessor) => { var rs = (int)StateAccessor.ReadRegister(r.Rs); var rt = StateAccessor.ReadRegister(r.Rt); if (rs > 0) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } } }, { Opcode.BranchOnLessThanOrEqualToZero, (r, StateAccessor) => { var rs = (int)StateAccessor.ReadRegister(r.Rs); var rt = StateAccessor.ReadRegister(r.Rt); if (rs <= 0) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } } }, { Opcode.BranchOnNotEqual, (r, StateAccessor) => { var rs = StateAccessor.ReadRegister(r.Rs); var rt = StateAccessor.ReadRegister(r.Rt); if (rs != rt) { StateAccessor.SetPc((uint)(StateAccessor.GetPc() + (short)(r.Immediate << 2))); } } }, { Opcode.LoadByte, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); byte dt; StateAccessor.GetMemoryData(ptr, out dt); var data = (uint)((int)((sbyte)(dt))); StateAccessor.WriteRegister(r.Rt, data); } }, { Opcode.UnsignedLoadByte, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); byte dt; StateAccessor.GetMemoryData(ptr, out dt); var data = (uint)dt; StateAccessor.WriteRegister(r.Rt, data); } }, { Opcode.LoadHalfword, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); UInt16 dt; StateAccessor.GetMemoryData(ptr, out dt); var data = (uint)((int)((short)DataConverterUInt16(dt))); StateAccessor.WriteRegister(r.Rt, data); } }, { Opcode.UnsignedLoadHalfword, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); UInt16 dt; StateAccessor.GetMemoryData(ptr, out dt); var data = DataConverterUInt16(dt); StateAccessor.WriteRegister(r.Rt, data); } }, { Opcode.LoadUpperImmediate, (r, StateAccessor) => { StateAccessor.WriteRegister(r.Rt, r.Immediate << 16); } }, { Opcode.LoadWord, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); UInt32 data; StateAccessor.GetMemoryData(ptr, out data); data = DataConverterUInt32(data); StateAccessor.WriteRegister(r.Rt, data); } }, { Opcode.BitwiseOrImmediate, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rt, a | r.Immediate); } }, { Opcode.StoreByte, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); var data = (byte)(StateAccessor.ReadRegister(r.Rt)); StateAccessor.SetMemoryData(ptr, data); } }, { Opcode.SetOnLessThanImmediate, (r, StateAccessor) => { var a = (int)StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rt, a < (short)r.Immediate ? 1u : 0u); } }, { Opcode.UnsignedSetOnLessThanImmediate, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rt, a < r.Immediate ? 1u : 0u); } }, { Opcode.StoreHalfword, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); var dt = (ushort)StateAccessor.ReadRegister(r.Rt); dt = DataConverterUInt16(dt); StateAccessor.SetMemoryData(ptr, (ushort)dt); } }, { Opcode.StoreWord, (r, StateAccessor) => { var ptr = (uint)(((short)r.Immediate) + (int)StateAccessor.ReadRegister(r.Rs)); var data = DataConverterUInt32(StateAccessor.ReadRegister(r.Rt)); StateAccessor.SetMemoryData(ptr, data); } }, { Opcode.BitwiseExclusiveOrImmediate, (r, StateAccessor) => { var a = StateAccessor.ReadRegister(r.Rs); StateAccessor.WriteRegister(r.Rt, a ^ r.Immediate); } }, }; }