/// <summary>
        /// Parses an instruction and generates the binary code for it.
        /// </summary>
        /// <param name="address">The address of the instruction being parsed in the .text segment.</param>
        /// <param name="args">An array containing the arguments of the instruction.</param>
        /// <returns>One or more 32-bit integers representing this instruction. If this interface is implemented
        /// for a pseudo-instruction, this may return more than one instruction value.</returns>
        public override IEnumerable <int> GenerateCodeForInstruction(int nextTextAddress, string[] args)
        {
            if (args.Length != 2)
            {
                throw new ArgumentException("Invalid number of arguments provided. Expected 2, received " + args.Length + '.');
            }

            int rs2 = RegisterMap.GetNumericFloatingPointRegisterValue(args[0]);

            var retList = new List <int>();
            ParameterizedInstructionArg arg = ParameterizedInstructionArg.ParameterizeArgument(args[1]);
            int instruction = 0;
            int upperOffset = (arg.Offset & 0xFE0);
            int lowerOffset = (arg.Offset & 0x1F);

            instruction |= (upperOffset << 25);
            instruction |= (rs2 << 20);
            instruction |= (arg.Register << 15);

            const int FUNC_CODE = 2;

            instruction |= (FUNC_CODE << 12);

            instruction |= (lowerOffset << 7);
            instruction |= 0x27;
            retList.Add(instruction);

            return(retList);
        }
Beispiel #2
0
            /// <summary>
            /// Takes an argument (e.g. 4(x9)) and parameterizes it into the offset component
            /// and its numeric register ID.
            /// </summary>
            /// <param name="trimmedArgToken">The token to parameterize, with whitespace trimmed on both left/right sides.</param>
            /// <returns>A parameterized register/offset structure.</returns>
            public static ParameterizedInstructionArg ParameterizeArgument(string trimmedArgToken)
            {
                string[] parameterizedArgs = trimmedArgToken.Split(new[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries).Apply((str) => str.Trim()).ToArray();

                // we should expect one or two arguments.
                if (parameterizedArgs.Length != 1 && parameterizedArgs.Length != 2)
                {
                    throw new ArgumentException(trimmedArgToken + " was not in a valid format.");
                }

                ParameterizedInstructionArg retVal = default(ParameterizedInstructionArg);

                // if we have one argument, assume its the register name, and that the offset is 0.
                if (parameterizedArgs.Length == 1)
                {
                    int registerId = RegisterMap.GetNumericRegisterValue(parameterizedArgs[0]);
                    retVal = new ParameterizedInstructionArg(0, registerId);
                }
                else
                {
                    bool isValidOffset = IntExtensions.TryParseEx(parameterizedArgs[0], out short offsetVal) && ((offsetVal & 0xF000) == 0);
                    if (!isValidOffset)
                    {
                        throw new ArgumentException(parameterizedArgs[0] + " is not a valid 12-bit offset.");
                    }

                    int registerId = RegisterMap.GetNumericRegisterValue(parameterizedArgs[1]);
                    retVal = new ParameterizedInstructionArg(offsetVal, registerId);
                }

                return(retVal);
            }
        /// <summary>
        /// Parses an instruction and generates the binary code for it.
        /// </summary>
        /// <param name="address">The address of the instruction being parsed in the .text segment.</param>
        /// <param name="args">An array containing the arguments of the instruction.</param>
        /// <returns>One or more 32-bit integers representing this instruction. If this interface is implemented
        /// for a pseudo-instruction, this may return more than one instruction value.</returns>
        public override IEnumerable <int> GenerateCodeForInstruction(int address, string[] args)
        {
            if (args.Length != 2)
            {
                throw new ArgumentException("Invalid number of arguments provided. Expected 2, received " + args.Length + '.');
            }

            int rdReg = RegisterMap.GetNumericFloatingPointRegisterValue(args[0]);

            var retList = new List <int>();

            const int FUNC_CODE = 0x2;

            if (IsParameterizedToken(args[1]))
            {
                ParameterizedInstructionArg arg = ParameterizedInstructionArg.ParameterizeArgument(args[1]);
                int instruction = 0;
                instruction |= ((arg.Offset & 0xFFF) << 20);
                instruction |= (arg.Register << 15);
                instruction |= (FUNC_CODE << 12);
                instruction |= (rdReg << 7);
                instruction |= 0x7;
                retList.Add(instruction);
            }
            else
            {
                Symbol sym            = SymbolTable.GetSymbol(args[1]);
                int    shiftedAddress = sym.Address >> 12;
                retList.AddRange(new LuiProcessor().GenerateCodeForInstruction(address, new[] { args[0], shiftedAddress.ToString() }));
                int numericOffset = sym.Address & 0xFFF;
                int instruction   = 0;
                instruction |= (numericOffset << 20);
                instruction |= (rdReg << 15);
                instruction |= (FUNC_CODE << 12);
                instruction |= (rdReg << 7);
                instruction |= 0x7;
                retList.Add(instruction);
            }

            return(retList);
        }