/// <summary> /// Decodes and emits the given R-format instruction /// </summary> /// <param name="index">The index of the instruction</param> /// <param name="instructionData">The instruction data</param> /// <param name="generatorData">The method generator data</param> /// <param name="emiter">The executor</param> private void DecodeAndEmitRFormat(int index, int instructionData, MethodGeneratorData generatorData, InstructionEmiter emiter) { //Decode it RFormatInstruction instruction = RFormatInstruction.Decode(instructionData); //Find the R-format emiter RFormatInstructionEmiter opxEmiter = null; //Check if maskers exists if (emiter.RFormatOpxMaskers.Count == 0) { if (emiter.RFormatInstructionEmiters.TryGetValue(instruction.OpxCode, out opxEmiter)) { opxEmiter(index, instruction, generatorData); } } else { //Loop until an executor is found foreach (int currentMask in emiter.RFormatOpxMaskers) { int opxCode = instruction.OpxCode & currentMask; if (emiter.RFormatInstructionEmiters.TryGetValue(opxCode, out opxEmiter)) { opxEmiter(index, instruction, generatorData); break; } } } }
public void TestSlli() { this.virtualMachine.SetRegisterValue(Registers.R8, 2); RFormatInstruction slliInstruction = new RFormatInstruction( OperationCodes.Slli.Code(), OperationXCodes.Slli | 2, Registers.R8.Number(), 0, Registers.R9.Number()); this.virtualMachine.ExecuteInstruction(slliInstruction.Encode()); Assert.AreEqual(8, this.virtualMachine.GetRegisterValue(Registers.R9)); }
public void TestSub() { this.virtualMachine.SetRegisterValue(Registers.R8, 2); this.virtualMachine.SetRegisterValue(Registers.R9, 8); RFormatInstruction slliInstruction = new RFormatInstruction( OperationCodes.Sub.Code(), OperationXCodes.Sub, Registers.R8.Number(), Registers.R9.Number(), Registers.R10.Number()); this.virtualMachine.ExecuteInstruction(slliInstruction.Encode()); Assert.AreEqual(-6, this.virtualMachine.GetRegisterValue(Registers.R10)); }
public void TestRFormat() { RFormatInstruction test = new RFormatInstruction(25, 2047, 12, 15, 17); RFormatInstruction decodedTest = RFormatInstruction.Decode(test.Encode()); Assert.AreEqual(test.OpCode, decodedTest.OpCode); Assert.AreEqual(test.OpxCode, decodedTest.OpxCode); Assert.AreEqual(test.RegisterA, decodedTest.RegisterA); Assert.AreEqual(test.RegisterB, decodedTest.RegisterB); Assert.AreEqual(test.RegisterC, decodedTest.RegisterC); Assert.AreEqual(25, decodedTest.OpCode); Assert.AreEqual(2047, decodedTest.OpxCode); Assert.AreEqual(12, decodedTest.RegisterA); Assert.AreEqual(15, decodedTest.RegisterB); Assert.AreEqual(17, decodedTest.RegisterC); }
/// <summary> /// Creates a new jitted method /// </summary> /// <param name="entryPoint">The entry point</param> public void JitMethod(uint entryPoint) { //Don't try to jit functions that already tried being jitted if (!this.failedJittedFunctions.Contains(entryPoint)) { //Loop until a RET instruction is found uint currentAddr = entryPoint; Instruction[] methodBody = null; while (currentAddr < this.virtualMachine.ProgramEnd) { //Read the data int instructionData = this.virtualMachine.ReadWordFromMemory(currentAddr); //Read the opcode int opCode = instructionData & 0x3F; if (opCode == OperationCodes.Ret.Code()) { //Decode it RFormatInstruction instruction = RFormatInstruction.Decode(instructionData); if (instruction.OpxCode == OperationXCodes.Ret) { //We have found a RET instruction uint size = currentAddr - entryPoint; //Convert the data in mem to instructions methodBody = new Instruction[(size / 4) + 1]; for (int i = 0; i < methodBody.Length; i++) { methodBody[i] = new Instruction( this.virtualMachine.ReadWordFromMemory(entryPoint + (uint)i * 4)); } break; } } currentAddr += 4; } this.JitMethod(entryPoint, methodBody); } }
public void TestInstructions() { //Test the I-format this.virtualMachine.SetRegisterValue(Registers.R8, 17); IFormatInstruction addiInst = new IFormatInstruction( OperationCodes.Addi.Code(), Registers.R8.Number(), Registers.R9.Number(), 278); this.virtualMachine.ExecuteInstruction(addiInst.Encode()); Assert.AreEqual(278 + 17, this.virtualMachine.GetRegisterValue(Registers.R9)); this.virtualMachine.SetRegisterValue(Registers.R8, 17); addiInst = new IFormatInstruction( OperationCodes.Addi.Code(), Registers.R8.Number(), Registers.R9.Number(), -234); this.virtualMachine.ExecuteInstruction(addiInst.Encode()); Assert.AreEqual(-234 + 17, this.virtualMachine.GetRegisterValue(Registers.R9)); //Test the R-format this.virtualMachine.SetRegisterValue(Registers.R8, 17); this.virtualMachine.SetRegisterValue(Registers.R9, 4717); RFormatInstruction addInst = new RFormatInstruction( OperationCodes.Add.Code(), OperationXCodes.Add, Registers.R8.Number(), Registers.R9.Number(), Registers.R10.Number()); this.virtualMachine.ExecuteInstruction(addInst.Encode()); Assert.AreEqual(4717 + 17, this.virtualMachine.GetRegisterValue(Registers.R10)); //Tests memory instructions this.virtualMachine.SetRegisterValue(Registers.R8, 1024); this.virtualMachine.SetRegisterValue(Registers.R9, 4711); IFormatInstruction storeInst = new IFormatInstruction( OperationCodes.Stw.Code(), Registers.R8.Number(), Registers.R9.Number(), 0); this.virtualMachine.ExecuteInstruction(storeInst.Encode()); int value = this.virtualMachine.ReadWordFromMemory(1024); Assert.AreEqual(4711, value); IFormatInstruction loadInst = new IFormatInstruction( OperationCodes.Ldw.Code(), Registers.R8.Number(), Registers.R10.Number(), 0); this.virtualMachine.ExecuteInstruction(loadInst.Encode()); Assert.AreEqual(4711, this.virtualMachine.GetRegisterValue(Registers.R10)); //Tests branch instructions IFormatInstruction branchInst = new IFormatInstruction( OperationCodes.Br.Code(), 0, 0, 4 * 4); this.virtualMachine.ExecuteInstruction(branchInst.Encode()); Assert.AreEqual((uint)(4 * 4), this.virtualMachine.ProgramCounter); }