예제 #1
0
        // Static Functions ///////////////////////////////////////////////////

        /// <summary>
        ///     Register RR,RI,RI(C) formats of the AND/NAND/OR/NOR/XOR/XNOR/ADD/SUB instructions.
        /// </summary>
        private static void RegisterALUInstructions([NotNull] InstructionRegistry registry)
        {
            const Int32 ALU_RR_OPCODE  = 0;
            const Int32 ALU_RI_OPCODE  = 1;
            const Int32 ALU_RIC_OPCODE = 2;

            Tuple <string, Int32>[] alu_instructions =
            {
                /* (Mnemonic, Function) */
                new Tuple <string, Int32>("and",  0),
                new Tuple <string, Int32>("nand", 1),
                new Tuple <string, Int32>("or",   2),
                new Tuple <string, Int32>("nor",  3),
                new Tuple <string, Int32>("xor",  4),
                new Tuple <string, Int32>("xnor", 5),
                new Tuple <string, Int32>("add",  6),
                new Tuple <string, Int32>("sub",  7),
            };

            // Add RR, RI, and RI(C) formats for each instruction.
            foreach (var pair in alu_instructions)
            {
                registry.Register(InstructionDefinitionFactory.CreateRRInstruction(
                                      pair.Item1, ALU_RR_OPCODE, pair.Item2));        ///////// ADD $t0, $t1     :=: $t0 += $t1
                registry.Register(InstructionDefinitionFactory.CreateRIStandardInstruction(
                                      pair.Item1, ALU_RI_OPCODE, pair.Item2));        ///////// ADD $t0, $t1, 8  :=: $t0 = $t1 + 8
                registry.Register(InstructionDefinitionFactory.CreateRIImplicitDestinationInstruction(
                                      pair.Item1, ALU_RI_OPCODE, pair.Item2));        ///////// ADD $t0, 8       :=: $t0 += 8
                registry.Register(InstructionDefinitionFactory.CreateRIStandardInstruction(
                                      pair.Item1 + 'c', ALU_RIC_OPCODE, pair.Item2)); // ADDC $t0, $t1, 8 :=: if(c) $t0 = $t1 + 8
                registry.Register(InstructionDefinitionFactory.CreateRIImplicitDestinationInstruction(
                                      pair.Item1 + 'c', ALU_RIC_OPCODE, pair.Item2)); // ADDC $t0, 8      :=: if(c) $t0 += 8
            }
        }
예제 #2
0
        /// <summary>
        ///     Register RR and RI formats of the SLL/SRL/SRA/ROL/ROR instructions.
        /// </summary>
        private static void RegisterShifterInstructions([NotNull] InstructionRegistry registry)
        {
            const Int32 SHIFTER_RR_OPCODE = 3;
            const Int32 SHIFTER_RI_OPCODE = 4;

            Tuple <string, Int32>[] shifter_instructions =
            {
                /* (Mnemonic, Function) */
                new Tuple <string, Int32>("sll", 0),
                new Tuple <string, Int32>("srl", 1),
                new Tuple <string, Int32>("sra", 2),
                new Tuple <string, Int32>("rol", 3),
                new Tuple <string, Int32>("ror", 4),
            };

            // Add RR and RI formats for each instruction.
            foreach (var pair in shifter_instructions)
            {
                registry.Register(InstructionDefinitionFactory.CreateRRInstruction(
                                      pair.Item1, SHIFTER_RR_OPCODE, pair.Item2)); // SLL $t0, $t1    :=: $t0 << $t1
                registry.Register(InstructionDefinitionFactory.CreateRIStandardInstruction(
                                      pair.Item1, SHIFTER_RI_OPCODE, pair.Item2)); // SLL $t0, $t1, 8 :=: $t0 = $t1 << 8
                registry.Register(InstructionDefinitionFactory.CreateRIImplicitDestinationInstruction(
                                      pair.Item1, SHIFTER_RI_OPCODE, pair.Item2)); // SLL $t0, 8      :=: $t0 <<= 8
            }
        }
예제 #3
0
        /// <summary>
        ///     Register RR and RI formats of the CEQ/CNEQ/CLT/CLTE/CLTU/CLTEU/CGT/CGTU instructions.
        /// </summary>
        private static void RegisterComparisonInstructions([NotNull] InstructionRegistry registry)
        {
            const Int32 COMPARATOR_RR_OPCODE = 5;
            const Int32 COMPARATOR_RI_OPCODE = 6;

            Tuple <string, Int32>[] comparison_instructions =
            {
                /* (Mnemonic, Function) */
                new Tuple <string, Int32>("ceq",   0),
                new Tuple <string, Int32>("cneq",  1),
                new Tuple <string, Int32>("clt",   2),
                new Tuple <string, Int32>("clte",  3),
                new Tuple <string, Int32>("cltu",  4),
                new Tuple <string, Int32>("clteu", 5),
                new Tuple <string, Int32>("cgt",   6),
                new Tuple <string, Int32>("cgtu",  7),
            };

            // Add RR and RI formats for each instruction.
            foreach (var pair in comparison_instructions)
            {
                registry.Register(InstructionDefinitionFactory.CreateRRInstruction(
                                      pair.Item1, COMPARATOR_RR_OPCODE, pair.Item2)); // CEQ $t0, $t1 :=: c = ($t0 == $t1)
                registry.Register(InstructionDefinitionFactory.CreateRIDestinationRegisterUnusedInstruction(
                                      pair.Item1, COMPARATOR_RI_OPCODE, pair.Item2)); // CEQ $t0, 8   :=: c = ($t0 == 8)
            }
        }
예제 #4
0
        public void GivenRegisteredNativeInstruction_Register_Throws()
        {
            var registry = new InstructionRegistry();

            registry.Register(GenerateNativeInstruction());
            registry.Register(GenerateNativeInstruction());
        }
예제 #5
0
        /// <summary>
        ///     Register the LI/LIC/LA/LAC/MOV/MOVC pseudo instructions.
        /// </summary>
        private static void RegisterDataTransferPseudoInstructions([NotNull] InstructionRegistry registry)
        {
            // LI $t0, 8 :=: $t0 = 8
            registry.Register(
                InstructionDefinitionFactory.CreateRISourceRegisterUnusedInstruction(
                    "li", 1, 2)); // OR $t0, $zero, 8

            // LIC $t0, 8 :=: if(c) $t0 = 8
            registry.Register(
                InstructionDefinitionFactory.CreateRISourceRegisterUnusedInstruction(
                    "lic", 2, 2)); // ORC $t0, $zero, 8

            // LA $t0, 8 :=: $t0 = 8
            registry.Register(
                InstructionDefinitionFactory.CreateRISourceRegisterUnusedInstruction(
                    "la", 1, 2)); // OR $t0, $zero, 8

            // LAC $t0, 8 :=: if(c) $t0 = 8
            registry.Register(
                InstructionDefinitionFactory.CreateRISourceRegisterUnusedInstruction(
                    "lac", 2, 2)); // ORC $t0, $zero, 8

            // MOV $t0, $t1 :=: $t0 = $t1
            registry.Register(
                InstructionDefinitionFactory.CreateRRInstruction(
                    "la", 1, 2)); // OR $t0, $t1, 0

            // MOVC $t0, $t1 :=: if(c) $t0 = $t1
            registry.Register(
                InstructionDefinitionFactory.CreateRRInstruction(
                    "lac", 2, 2)); // ORC $t0, $t1, 0
        }
예제 #6
0
        public void GivenValueEqualRegisteredInstructionFormat_IsRegistered_ReturnsTrue()
        {
            var registry    = new InstructionRegistry();
            var instruction = GenerateNativeInstruction();

            registry.Register(instruction);

            // Different format object from original instruction.
            Assert.IsTrue(registry.IsRegistered(GenerateInstructionFormat()));
        }
예제 #7
0
 public IdRef(InstructionWithId instruction)
 {
     _id = instruction.IdResult;
     if (_id == 0)
     {
         throw new ArgumentException("Instruction IdResult should not be zeo.");
     }
     _instruction = instruction;
     _registry    = null;
 }
예제 #8
0
        public void GivenReferenceEqualRegisteredInstructionFormat_Find_ReturnsOriginalRegisteredInstruction()
        {
            var registry    = new InstructionRegistry();
            var instruction = GenerateNativeInstruction();

            registry.Register(instruction);

            // Same format object as original instruction.
            Assert.IsNotNull(registry.Find(instruction.Format));
        }
예제 #9
0
파일: Repl.cs 프로젝트: joshpeterson/mos
 public Repl(ProgrammingModel model, Memory memory)
 {
     registry = new InstructionRegistry();
       this.model = model;
       this.memory = memory;
       assembler = new Assembler(registry.All);
       fetcher = new Fetcher(model, memory);
       decoder = new Decoder(registry.All);
       executor = new Executor(registry.All, model, memory);
       coreLoop = new CoreLoop(fetcher, decoder, executor);
 }
예제 #10
0
        /// <summary>
        ///     Register Register and Immediate formats of the JMP/BRC instructions.
        /// </summary>
        private static void RegisterControlTransferPseudoInstructions([NotNull] InstructionRegistry registry)
        {
            Tuple <string, Int32>[] jump_instructions =
            {
                /* (Mnemonic, Opcode) */
                new Tuple <string, Int32>("jmp", 1), // ALU RI
                new Tuple <string, Int32>("brc", 2), // ALU RI(C)
            };

            foreach (var pair in jump_instructions)
            {
                // Jump to immediate address.
                // JMP 0x8 :=: goto 0x8
                // BRC 0x8 :=: if(c) goto 0x8
                registry.Register(
                    new NativeInstructionDefinition( // OR/ORC $pc, $zero, 0x8
                        mnemonic: pair.Item1,
                        operand_format: new OperandFormat(typeof(ImmediateOperand)),
                        mapping: new InstructionFieldMappingBuilder()
                        .R1(ops => (int)Registers.RegisterNumber.PC)
                        .R2(ops => (int)Registers.RegisterNumber.ZERO)
                        .Immediate(ops => ((ImmediateOperand)ops[0]).Value)
                        .Opcode(pair.Item2)
                        .Function(2)
                        .Build()
                        ));
                // Jump to register address.
                // JMP $t0 :=: goto $t0
                // BRC $t0 :=: if(c) goto $t0
                registry.Register(
                    new NativeInstructionDefinition( // OR/ORC $pc, $t0, 0
                        mnemonic: pair.Item1,
                        operand_format: new OperandFormat(typeof(RegisterOperand)),
                        mapping: new InstructionFieldMappingBuilder()
                        .R1(ops => (int)Registers.RegisterNumber.PC)
                        .R2(ops => (int)((RegisterOperand)ops[0]).RegisterNumber)
                        .Immediate(0)
                        .Opcode(pair.Item2)
                        .Function(2)
                        .Build()
                        ));
            }
        }
예제 #11
0
        /// <summary>
        ///     Register: Register address, Immediate address, and Base-Offset addressing formats of the SB/SH instructions.
        /// </summary>
        private static void RegisterMemoryStoreInstructions([NotNull] InstructionRegistry registry)
        {
            const Int32 MEMORY_STORE_OPCODE = 8;

            Tuple <string, Int32>[] memory_store_instructions =
            {
                /* (Mnemonic, Function) */
                new Tuple <string, Int32>("sb", 7),
                new Tuple <string, Int32>("sh", 6),
            };

            // Add Register, Immediate, and BaseOffset formats for each instruction.
            foreach (var pair in memory_store_instructions)
            {
                registry.Register(InstructionDefinitionFactory.CreateRRInstruction(
                                      pair.Item1, MEMORY_STORE_OPCODE, pair.Item2)); // SH $t0, $t1       :=: *($t1) = $t0
                registry.Register(InstructionDefinitionFactory.CreateRISourceRegisterUnusedInstruction(
                                      pair.Item1, MEMORY_STORE_OPCODE, pair.Item2)); // SH $t0, 0xFF      :=: *(0xFF) = $t0
                registry.Register(InstructionDefinitionFactory.CreateBaseOffsetInstruction(
                                      pair.Item1, MEMORY_STORE_OPCODE, pair.Item2)); // SH $t0, 0xFF($t1) :=: *($t1 + 0xFF) = $t0
            }
        }
예제 #12
0
        /// <summary>
        ///     Register: Register address, Immediate address, and Base-Offset addressing formats of the LB/LBU/LH instructions.
        /// </summary>
        private static void RegisterMemoryLoadInstructions([NotNull] InstructionRegistry registry)
        {
            const Int32 MEMORY_LOAD_OPCODE = 7;

            Tuple <string, Int32>[] memory_load_instructions =
            {
                /* (Mnemonic, Function) */
                new Tuple <string, Int32>("lb",  3),
                new Tuple <string, Int32>("lbu", 4),
                new Tuple <string, Int32>("lh",  1),
            };

            // Add Register, Immediate, and BaseOffset formats for each instruction.
            foreach (var pair in memory_load_instructions)
            {
                registry.Register(InstructionDefinitionFactory.CreateRRInstruction(
                                      pair.Item1, MEMORY_LOAD_OPCODE, pair.Item2)); // LH $t0, $t1       :=: $t0 = *($t1)
                registry.Register(InstructionDefinitionFactory.CreateRISourceRegisterUnusedInstruction(
                                      pair.Item1, MEMORY_LOAD_OPCODE, pair.Item2)); // LH $t0, 0xFF      :=: $t0 = *(0xFF)
                registry.Register(InstructionDefinitionFactory.CreateBaseOffsetInstruction(
                                      pair.Item1, MEMORY_LOAD_OPCODE, pair.Item2)); // LH $t0, 0xFF($t1) :=: $t0 = *($t1 + 0xFF)
            }
        }
예제 #13
0
 public IdRef(InstructionWithId instruction, InstructionRegistry registry)
 {
     _id          = instruction.IdResult;
     _instruction = instruction;
     _registry    = registry;
 }
예제 #14
0
 public IdRef(T instruction, InstructionRegistry registry) : base(instruction, registry)
 {
 }
예제 #15
0
 public IdRef(uint id, InstructionRegistry registry) : base(id, registry)
 {
 }
예제 #16
0
 public IdRef(uint id, InstructionRegistry registry)
 {
     _id          = id;
     _registry    = registry;
     _instruction = null;
 }
예제 #17
0
 /// <summary>
 ///     Register the following instructions:
 ///     - HALT
 /// </summary>
 private static void RegisterMiscInstructions([NotNull] InstructionRegistry registry)
 {
     registry.Register(
         InstructionDefinitionFactory.CreateOpcodeOnlyInstruction(
             "halt", 31));
 }