/// <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. Should be empty.</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[] instructionArgs) { // we expect no arguments. if not, throw an ArgumentException if (instructionArgs.Length != 0) { throw new ArgumentException("Invalid number of arguments provided. Expected 0, received " + instructionArgs.Length + '.'); } var delegateParser = new AddiProcessor(); return(delegateParser.GenerateCodeForInstruction(address, new string[] { "x0", "x0", "0" })); }
/// <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) { // we expect three arguments. if not, throw an ArgumentException if (args.Length != 3) { throw new ArgumentException("Invalid number of arguments provided. Expected 3, received " + args.Length + '.'); } IEnumerable <int> returnVal = null; int instruction = 0; int rdReg = RegisterMap.GetNumericRegisterValue(args[0]); int rs1Reg = RegisterMap.GetNumericRegisterValue(args[1]); int rs2Reg = 0; try { rs2Reg = RegisterMap.GetNumericRegisterValue(args[2]); List <int> instructionList = new List <int>(); instruction |= (rs2Reg << 20); instruction |= (rs1Reg << 15); instruction |= (rdReg << 7); instruction |= 0x33; instructionList.Add(instruction); returnVal = instructionList; } catch (ArgumentException) { // try to parse the string as a number; maybe the user meant addi? int immediate = 0; bool isInt = IntExtensions.TryParseEx(args[2], out immediate); if (isInt) { var immediateParser = new AddiProcessor(); returnVal = immediateParser.GenerateCodeForInstruction(address, args); } else { // otherwise, this is garbage; rethrow the value. throw; } } return(returnVal); }
/// <summary> /// Determines how many instructions are generated via a pseudo-instruction. The default implementation assumes /// that only one instruction will be returned. /// </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>An integer representing how many instructions will be generated for a line of assembly.</returns> protected override int GetNumOfInstructionsForSymbolicInstruction(int address, string[] args) { if (args.Length != 2) { throw new ArgumentException("la - expected 2 arguments; received " + args.Length); } int numGeneratedInstructions = 0; const int UNKNOWN_SYMBOL_INST_COUNT = 2; // see if we've seen this symbol before. // if we have and its a text segment symbol, assume worst case (eventually when we add linkage modifiers, // all assumptions about known addresses are going to most likely change). // otherwise, if we don't have this symbol by now, then it is a text segment symbol that we haven't read. // assume worst case. if (SymbolTable.ContainsSymbol(args[1])) { Symbol sym = SymbolTable.GetSymbol(args[1]); if (sym.SegmentType == SegmentType.Data) { var tempProc = new AddiProcessor(); numGeneratedInstructions = tempProc.GenerateCodeForInstruction(address, new string[] { args[0], "x0", sym.Address.ToString() }).Count(); } else { numGeneratedInstructions = UNKNOWN_SYMBOL_INST_COUNT; } } else { numGeneratedInstructions = UNKNOWN_SYMBOL_INST_COUNT; } return(numGeneratedInstructions); }