public IInstructionDefinition TryFind([NotNull] InstructionFormat format)
        {
            IInstructionDefinition instruction_definition;

            registry.TryGetValue(format, out instruction_definition);
            return(instruction_definition);
        }
Ejemplo n.º 2
0
 public InstructionMetadata(InstructionMnemonic instructionMnemonic,
                            int opcode, int function,
                            InstructionFormat format)
 {
     Instruction = instructionMnemonic;
     Format      = format;
     OpCode      = opcode;
     Function    = function;
 }
Ejemplo n.º 3
0
        public InstructionMetadata(InstructionMnemonic instructionMnemonic, 
                                    int opcode, int function, 
									InstructionFormat format)
        {
            Instruction = instructionMnemonic;
            Format = format;
            OpCode = opcode;
            Function = function;
        }
        public IInstructionDefinition Find([NotNull] InstructionFormat format)
        {
            IInstructionDefinition instruction_definition;

            registry.TryGetValue(format, out instruction_definition);
            if (instruction_definition != null)
            {
                return(instruction_definition);
            }
            else
            {
                throw new InvalidOperationException("An instruction defintion of the given format has not been registered.");
            }
        }
Ejemplo n.º 5
0
 public static MsilInstruction GetInstruction(string Format)
 {
     foreach (MsilInstruction istn in Instructions)
     {
         string text = istn.Format;
         if (istn.Format.IndexOf(' ') != -1)
         {
             text = InstructionFormat.Match(istn.Format).Value;
         }
         if (string.Compare(text, Format.Replace('_', '.'), true) == 0)
         {
             return(istn);
         }
     }
     return(null);
 }
 /// <summary>
 ///     Check if an instruction_definition of the given format has been registered.
 /// </summary>
 public bool IsRegistered([NotNull] InstructionFormat format)
 => registry.ContainsKey(format);
Ejemplo n.º 7
0
        private void SetInstruction(Instruction inst, InstructionFormat format, string line)
        {
            string[] split       = line.Substring(format.Key.Length).Replace('(', ',').Replace(")", "").Replace('\t', ' ').Split(',');
            int      formatIndex = 0;

            inst.Format = format;
            for (int i = 0; i < split.Length; ++i)
            {
                if (formatIndex >= format.Inputs.Length)
                {
                    return;
                }
                string str = split[i].Trim();
                if (format.Inputs[formatIndex][0] == 'r')
                {
                    if (str == "$ra")
                    {
                        str = "$31";
                    }
                    inst.Register.Add(Int32.Parse(str.Substring(1)));
                }
                else if (format.Inputs[formatIndex][0] == 'i')
                {
                    if (Char.IsDigit(str[0]) || str[0] == '-')
                    {
                        bool neg = false;
                        if (str[0] == '-')
                        {
                            neg = true;
                            str = str.Substring(1);
                        }

                        if (str.IndexOf("0x") == 0)
                        {
                            string num = str.Substring(2);
                            inst.Immediate = 0;
                            for (int j = 0; j < num.Length; ++j)
                            {
                                inst.Immediate *= 16;
                                if (Char.IsDigit(num[j]) || num[j] == '-')
                                {
                                    inst.Immediate += num[j] - '0';
                                }
                                else
                                {
                                    inst.Immediate += num[j] - 'a' + 10;
                                }
                            }
                        }
                        else
                        {
                            inst.Immediate = Int32.Parse(str);
                        }

                        if (neg)
                        {
                            inst.Immediate = -inst.Immediate;
                        }

                        inst.ImmediateLabel = null;
                    }
                    else
                    {
                        inst.ImmediateLabel = str;
                    }
                }
                ++formatIndex;
            }
        }
Ejemplo n.º 8
0
 /// <summary>
 ///     Construct directly from instruction format and mappings.
 /// </summary>
 public NativeInstructionDefinition([NotNull] InstructionFormat format,
                                    [NotNull] InstructionFieldMappingBuilder.InstructionFieldMapping mapping)
 {
     Format        = format;
     field_mapping = mapping;
 }
Ejemplo n.º 9
0
        // Constructors ///////////////////////////////////////////////////////

        /// <summary>
        ///     Construct from mnemonic, operand formats, and mappings.
        /// </summary>
        public NativeInstructionDefinition([NotNull] string mnemonic, [NotNull] OperandFormat operand_format,
                                           [NotNull] InstructionFieldMappingBuilder.InstructionFieldMapping mapping)
        {
            Format        = new InstructionFormat(mnemonic, operand_format);
            field_mapping = mapping;
        }
Ejemplo n.º 10
0
        // Constructors ///////////////////////////////////////////////////////

        /// <summary>
        ///     Construct from an instruction format and assembler delegate.
        /// </summary>
        /// <param name="format"> The format of this pseudo-instruction. </param>
        /// <param name="assembler_delegate">
        ///     A function that will assemble machine code based on a list of operands.
        ///     Must not return null.
        /// </param>
        public CustomInstructionDefinition([NotNull] InstructionFormat format,
                                           [NotNull] Func <OperandList, MachineCode> assembler_delegate)
        {
            Format = format;
            this.assembler_delegate = assembler_delegate;
        }
Ejemplo n.º 11
0
        } // End constructor.

        /// <summary>
        /// Parses the given string into an operation.
        /// </summary>
        /// <param name="tokens">An array containing a mnemonic as well as any operands the instruction may have. The mnemonic may be have a prefix: * means SIC; + means Format 4.</param>
        /// <param name="result">If the parse was successful, an instruction with operations uninitialized. Otherwise, null.</param>
        /// <returns>A Boolean value indicating whether the parse succeeded.</returns>
        public static bool TryParse(string[] tokens, out Instruction result)
        {
            if (tokens.Length == 0 || tokens[0].Length == 0)
            {
                result = null;
                return(false);
            }
            string            mnemonic     = tokens[0];
            bool              removePrefix = false;
            bool              sic          = false;
            InstructionFormat fmt          = InstructionFormat.NotSet;

            switch (mnemonic[0])
            {
            case '*':
                // This is a SIC instruction.
                // Means all flags are low. (Right?)
                sic          = true;
                removePrefix = true;
                break;

            case '+':
                fmt          = InstructionFormat.Format4;
                removePrefix = true;
                break;
            }
            if (removePrefix)
            {
                mnemonic = mnemonic.Substring(1);
            }
            if (mnemonic.Length < 1)
            {
                result = null;
                return(false);
            }

            Mnemonic m;

            if (char.IsDigit(mnemonic[0]) || !Enum.TryParse(mnemonic, true, out m)) // true to ignore case.
            {
                result = null;
                return(false);
            }

            var ret = new Instruction(m);

            //if (m == Mnemonic.CLEAR)
            //    Debugger.Break();

            if (sic)
            {
                ret.Flags = 0;
            }

            if (ret.Format == InstructionFormat.NotSet || (ret.Format == InstructionFormat.Format3Or4 && fmt == InstructionFormat.Format4))
            {
                ret.Format = fmt;
            }
            else
            {
                if (fmt != InstructionFormat.NotSet)
                {
                    // Instruction already knows its format but we planned to set it to something!
                    Console.Error.WriteLine($"Instruction {m} must be format {(int)ret.Format} (prefix indicated format {(int)fmt})!");
                    result = null;
                    return(false);
                }
            }

            // If format 4 has not been indicated by this point, assume 3/4 instructions are 3.
            if (ret.Format == InstructionFormat.Format3Or4)
            {
                ret.Format = InstructionFormat.Format3;
            }

            Debug.Assert(ret.Format != InstructionFormat.NotSet, "Instruction's format should be set by this point.");

            bool isIndexed = false;

            if (tokens.Length >= 2)
            {
                var args     = tokens[1];
                int commaIdx = args.IndexOf(',');
                if (commaIdx >= 0)
                {
                    var afterComma = args.Substring(commaIdx + 1);
                    if (ret.Format == InstructionFormat.Format2)
                    {
                        if (ret.Operands.Count == 2)
                        {
                            var splitOnComma = new string[tokens.Length + 1];
                            splitOnComma[0] = tokens[0];
                            splitOnComma[1] = args.Substring(0, commaIdx);
                            splitOnComma[2] = args.Substring(commaIdx + 1);
                            Array.Copy(tokens, 2, splitOnComma, 3, tokens.Length - 2);
                            tokens = splitOnComma;
                        }
                        isIndexed = false;
                    }
                    else
                    {
                        if (afterComma != "x" && afterComma != "X")
                        {
                            Console.Error.WriteLine($"Unexpected ',' in {string.Join(" ", tokens)}");
                            result = null;
                            return(false);
                        }
                        isIndexed = true;
                    }
                }
            }

            // Copy in all the operands by parsing as many tokens as we need.
            // Extra tokens are usually just comments. In this method, we simply ignore them, or leave operands as null if there aren't enough.
            int tokenIdx;
            int operandCount = ret.Operands.Count;

            for (tokenIdx = 1; tokenIdx < tokens.Length && tokenIdx <= operandCount; ++tokenIdx)
            {
                var operand = ret.Operands[tokenIdx - 1];
                var token   = tokens[tokenIdx];

                // Parse the operand as the type we expect.
                switch (operand.Type)
                {
                //case OperandType.Device:
                case OperandType.Address:
                    // Acceptable formats:
                    //  Number.
                    //  Number with either @ or # prefix.
                    //  Symbol (most any string?)
                    //  Literal (=C followed by any string surrounded by ', or =X followed by any even-length hex string surrounded by ').
                    switch (token[0])
                    {
                    case '@':
                        operand.AddressingMode = AddressingMode.Indirect;
                        token = token.Substring(1);
                        break;

                    case '#':
                        operand.AddressingMode = AddressingMode.Immediate;
                        token = token.Substring(1);
                        break;
                    }

                    // Interpret the remainder of the token as an address, if possible, or else a symbol.
                    int addr;
                    if (int.TryParse(token, out addr))
                    {
                        if (ret.Operation == Mnemonic.SHIFTL || ret.Operation == Mnemonic.SHIFTR)
                        {
                            if (addr == 0)
                            {
                                Console.Error.WriteLine("Shift by zero is not allowed.");
                                result = null;
                                return(false);
                            }
                            // The book says to subtract one.
                            // Osprey's sicasm does it too.
                            operand.Value = addr - 1;
                        }
                        else
                        {
                            operand.Value = addr;
                        }
                    }
                    else
                    {
                        // todo: check that token is valid for a symbol name and return false if it isn't.
                        operand.SymbolName = token;
                    }
                    if (isIndexed)
                    {
                        operand.AddressingMode |= AddressingMode.Indexed;
                    }
                    break;

                case OperandType.Register:
                    Register reg;
                    if (Enum.TryParse(token, true, out reg))
                    {
                        operand.Value = (int)reg;     // Casting Register to int.
                    }
                    else
                    {
                        Console.Error.WriteLine($"Could not parse {token} as a register.");
                        result = null;
                        return(false);
                    }
                    break;
                }

                Debug.WriteLine($"Parsed {token} as {operand.Type.ToString()}.");
            } // for each operand.

            ret.Comment = string.Join(" ", tokens, tokenIdx, tokens.Length - tokenIdx);

            result = ret;
            return(true);
        }
Ejemplo n.º 12
0
        public Instruction(Mnemonic mnemonic)
        {
            Operation = mnemonic;
            switch (mnemonic)
            {
            case Mnemonic.LDA:
            case Mnemonic.LDX:
            case Mnemonic.LDS:
            case Mnemonic.LDT:
            case Mnemonic.LDB:
            case Mnemonic.LDL:
            case Mnemonic.LDCH:
            case Mnemonic.STCH:
            case Mnemonic.STA:
            case Mnemonic.STX:
            case Mnemonic.STS:
            case Mnemonic.STT:
            case Mnemonic.STB:
            case Mnemonic.STL:
            case Mnemonic.ADD:
            case Mnemonic.SUB:
            case Mnemonic.MUL:
            case Mnemonic.DIV:
            case Mnemonic.AND:
            case Mnemonic.OR:
            case Mnemonic.COMP:
            case Mnemonic.J:
            case Mnemonic.JSUB:
            case Mnemonic.JLT:
            case Mnemonic.JGT:
            case Mnemonic.JEQ:
            case Mnemonic.TIX:
            case Mnemonic.TD:
            case Mnemonic.WD:
            case Mnemonic.RD:
                Operands = new List <Operand>()
                {
                    new Operand(OperandType.Address)
                }.AsReadOnly();
                Format = InstructionFormat.Format3Or4;
                break;

            case Mnemonic.CLEAR:
            case Mnemonic.TIXR:
                Operands = new List <Operand>()
                {
                    new Operand(OperandType.Register)
                }.AsReadOnly();
                Format = InstructionFormat.Format2;
                break;

            case Mnemonic.RMO:
            case Mnemonic.ADDR:
            case Mnemonic.SUBR:
            case Mnemonic.COMPR:
            case Mnemonic.DIVR:
            case Mnemonic.MULR:
                Operands = new List <Operand>()
                {
                    new Operand(OperandType.Register), new Operand(OperandType.Register)
                }.AsReadOnly();
                Format = InstructionFormat.Format2;
                break;

            case Mnemonic.SHIFTL:
            case Mnemonic.SHIFTR:
                // The second operand isn't really an address, but we mark it that way so that it isn't ToStringged as a register.
                // For example, we don't want to print "SHIFTR A,PC" instead of "SHIFTR A,8".
                Operands = new List <Operand>()
                {
                    new Operand(OperandType.Register), new Operand(OperandType.Address)
                }.AsReadOnly();
                Format = InstructionFormat.Format2;
                break;

            case Mnemonic.RSUB:
                Operands = new List <Operand>();
                Format   = InstructionFormat.Format3Or4;
                break;

            case Mnemonic.NOP:
                Operands = new List <Operand>();
                Format   = InstructionFormat.Format1;
                break;

            default:
                throw new NotSupportedException("That operation is not yet supported.");
            }
        } // End constructor.