Example #1
0
        /// <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;
                    }
                }
            }
        }
Example #2
0
        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));
        }
Example #3
0
        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));
        }
Example #4
0
        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);
            }
        }
Example #6
0
        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);
        }