/// <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 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); } }