private EncodingFormat FindFormatDetails(EncodingFormat encoding) { List <char> registerTypes = new List <char>(); List <char> immediateTypes = new List <char>(); string syntax = encoding.Syntax; int numRegs = 0; int numImmeds = 0; foreach (char c in syntax) { if (char.IsLetter(c)) { int metaType = FindElementMetaType(c); if (metaType == ASMElementMetaType.Register) { numRegs++; registerTypes.Add(c); } else if (metaType == ASMElementMetaType.Immediate) { numImmeds++; immediateTypes.Add(c); } } } encoding.RegisterTypes = registerTypes; encoding.ImmediateTypes = immediateTypes; encoding.NumRegs = numRegs; encoding.NumImmeds = numImmeds; return(encoding); }
private ASMAddLabelResult AddLabel(uint pc, string[] parts) { ASMAddLabelResult result = new ASMAddLabelResult(); if (ASMStringHelper.RemoveSpaces(parts[0]).EndsWith(":")) { string preLabel = ASMStringHelper.RemoveSpaces(parts[0]).ToUpper(); string label = preLabel.Substring(0, preLabel.Length - 1); result = AddLabelGeneric(pc, label); // Is there an ASM command on this line? If so, advance the PC if (!string.IsNullOrEmpty(parts[1])) { parts = ASMStringHelper.RemoveLabel(parts); // If this is an ASM command, advance the PC EncodingFormat curEncodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (curEncodingOrNull != null) { pc += 4; } } } //result.ErrorCode = 0; result.PC = pc; return(result); }
// Regs use uppercase letters, immediates use lowercase letters: [r1] becomes AAAAA, [i1] becomes aaa if length = 3, etc. public static string ExpandFormat(EncodingFormat format) { int numRegs = format.NumRegs; int numImmeds = format.NumImmeds; string newFormatBinary = format.Binary; for (int i = 0; i < numRegs; i++) { char elementTypeChar = format.RegisterTypes[i]; string strElementTypeChar = elementTypeChar.ToString(); int iPlusOne = i + 1; string strIPlusOne = iPlusOne.ToString(); newFormatBinary = newFormatBinary.Replace("[" + strElementTypeChar + strIPlusOne + "]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateUpperLetterChar(i), ASMRegisterHelper.GetEncodingBitLength(elementTypeChar))); if (format.PartialRegisterSizes != null) { newFormatBinary = newFormatBinary.Replace("[" + strElementTypeChar + strIPlusOne + "-1]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateUpperLetterChar(i), format.PartialRegisterSizes[0])); newFormatBinary = newFormatBinary.Replace("[" + strElementTypeChar + strIPlusOne + "-2]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateUpperLetterChar(i), format.PartialRegisterSizes[1])); } } for (int i = 0; i < numImmeds; i++) { newFormatBinary = newFormatBinary.Replace("[" + format.ImmediateTypes[i] + (i + 1) + "]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateLowerLetterChar(i), format.ImmediateLengths[i])); } return(newFormatBinary); }
// Find whether or not this is a valid command (and has an entry in our encoding list). If it // does, return it; otherwise, return null. public EncodingFormat FindFormatByCommand(string command) { EncodingFormat format = null; EncodeDict.TryGetValue(command, out format); return(format); }
public void AddToOpcodeFunctionList(int opcode, int function, EncodingFormat encoding) { List <EncodingFormat>[] decodeList = null; if (DecodeOpcodeFunctionList[opcode] != null) { decodeList = DecodeOpcodeFunctionList[opcode]; } else { decodeList = new List <EncodingFormat> [Opcodes.NumPossibleFunctions]; } List <EncodingFormat> encFormatList = null; if (decodeList[function] != null) { encFormatList = decodeList[function]; encFormatList.Add(encoding); decodeList[function] = encFormatList; } else { encFormatList = new List <EncodingFormat>(); encFormatList.Add(encoding); decodeList[function] = encFormatList; } DecodeOpcodeFunctionList[opcode] = decodeList; }
// Translates pseudoinstructions public ASMTranslatePseudoResult TranslatePseudo(string[] lines, uint startPC, bool skipLabelAssertion = false) { _errorTextBuilder.Length = 0; ASMTranslatePseudoResult result = new ASMTranslatePseudoResult(); List <EncodeLine> resultLines = new List <EncodeLine>(); int index = 0; uint pc = startPC; foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { continue; } string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line); processLine = ASMStringHelper.RemoveLeadingSpaces(processLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); processLine = ASMStringHelper.ConvertBracketBlocks(processLine); string[] parts = ASMStringHelper.SplitLine(processLine); parts = ASMStringHelper.RemoveLabel(parts); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts, false); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); // If this is an ASM command, pass off line to translating routine EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { // DEBUG 1/16 try { EncodingFormat encoding = encodingOrNull; EncodeLine[] encodeLines = TranslatePseudoSingle(encoding, parts, index, pc, skipLabelAssertion); foreach (EncodeLine encodeLine in encodeLines) { resultLines.Add(encodeLine); pc += 4; } } catch (Exception ex) { //result.errorMessage = "Error translating pseudoinstruction: " + line; _errorTextBuilder.Append("Error translating pseudoinstruction: " + line + " (" + ex.Message + ")\r\n"); //result.lines = null; //return result; } index++; } } result.lines = resultLines.ToArray(); result.errorMessage = _errorTextBuilder.ToString(); return(result); }
public void AddToDecodeLists(string expFormat, EncodingFormat encoding) { AddToOpcodeList(encoding.Opcode, encoding); if (Opcodes.IsSpecialOpcode(encoding.Opcode)) { AddToOpcodeFunctionList(encoding.Opcode, encoding.Function, encoding); } }
private EncodingFormat FindFormatBaseValues(EncodingFormat encoding) { uint[] baseValues = FindBaseValues(encoding.ExpandedFormat); encoding.BaseEncoding = baseValues[0]; encoding.BitMask = baseValues[1]; encoding.Opcode = (int)baseValues[2]; encoding.Function = (int)baseValues[3]; return(encoding); }
public void AddToOpcodeList(int opcode, EncodingFormat encoding) { List <EncodingFormat> decodeList = null; if (DecodeOpcodeList[opcode] != null) { decodeList = DecodeOpcodeList[opcode]; decodeList.Add(encoding); DecodeOpcodeList[opcode] = decodeList; } else { decodeList = new List <EncodingFormat>(); decodeList.Add(encoding); DecodeOpcodeList[opcode] = decodeList; } }
private ASMSingleEncodeResult TryEncodeSingle(string[] parts, EncodingFormat encoding, uint pc, string processLine, bool littleEndian) { try { return(EncodeASMSingle(parts, encoding, pc, littleEndian)); } catch (Exception ex) { _errorTextBuilder.Append("FAILED TO ENCODE LINE : "); _errorTextBuilder.Append(processLine); _errorTextBuilder.Append(" ("); _errorTextBuilder.Append(ex.Message); _errorTextBuilder.Append(")"); _errorTextBuilder.Append("\r\n"); return(new ASMSingleEncodeResult("", new List <byte>().ToArray())); } }
private string DecodePartialVFPURegister(EncodingFormat encFormat, uint line, int regIndex, char lookupChar) { string formatBinary = encFormat.Binary; string newFormat = encFormat.ExpandedFormat; /* * int[] binaryIndex = new int[2]; * * int part1Index = formatBinary.IndexOf("[p" + (regIndex + 1).ToString() + "-1"); * int part2Index = formatBinary.IndexOf("[p" + (regIndex + 1).ToString() + "-2"); * * int firstIndex = newFormat.IndexOf(lookupChar); * int searchPartIndex = firstIndex; * for (; newFormat[searchPartIndex] == lookupChar; searchPartIndex++) ; * int secondIndex = newFormat.IndexOf(lookupChar, searchPartIndex); * * if (part1Index > part2Index) * { * binaryIndex[0] = secondIndex; * binaryIndex[1] = firstIndex; * } * else * { * binaryIndex[0] = firstIndex; * binaryIndex[1] = secondIndex; * } */ //string firstValue = binaryLine.Substring(binaryIndex[0], encFormat.PartialRegisterSizes[0]); //string secondValue = binaryLine.Substring(binaryIndex[1], encFormat.PartialRegisterSizes[1]); //int firstValue = FindNumericArgValue(line, encFormat.PartialRegisterPositions[regIndex][0], ASMValueHelper.GetIncludeMask(encFormat.PartialRegisterSizes[0])); //int secondValue = FindNumericArgValue(line, encFormat.PartialRegisterPositions[regIndex][1], ASMValueHelper.GetIncludeMask(encFormat.PartialRegisterSizes[1])); int firstValue = FindNumericArgValue(line, encFormat.PartialRegisterPositions[regIndex][0], encFormat.PartialRegisterIncludeMasks[regIndex][0]); int secondValue = FindNumericArgValue(line, encFormat.PartialRegisterPositions[regIndex][1], encFormat.PartialRegisterIncludeMasks[regIndex][1]); //string binaryValue = firstValue + secondValue; int totalValue = (firstValue << encFormat.PartialRegisterSizes[1]) + secondValue; string argValue = DecodeRegister(totalValue, ASMElementTypeCharacter.PartialVFPURegister, false, encFormat.VFPURegisterTypes[regIndex]); return(argValue); }
// For reading encoding files public void ReadEncodeList(string filepath) { StreamReader reader = new StreamReader(filepath); try { while(reader.Peek() != -1) { string line = reader.ReadLine(); if (!string.IsNullOrEmpty(line)) { line = ASMStringHelper.RemoveSpaces(line); string[] lineArray = line.Split(':'); EncodingFormat encoding = new EncodingFormat(); encoding.Command = lineArray[0].ToLower(); encoding.Binary = lineArray[1]; encoding.Syntax = lineArray[2]; if (lineArray.Length > 3) encoding.ImmediateLengths = ASMStringHelper.CreateIntList(lineArray[3]); if (lineArray.Length > 4) encoding.VFPURegisterTypes = ASMStringHelper.CreateIntList(lineArray[4]); if (lineArray.Length > 5) encoding.PartialRegisterSizes = ASMStringHelper.CreateIntList(lineArray[5]); if (lineArray.Length > 6) encoding.ShiftedImmediateAmounts = ASMStringHelper.CreateIntList(lineArray[6]); if (lineArray.Length > 7) encoding.VFPUPrefixType = int.Parse(lineArray[7]); encoding = FindFormatDetails(encoding); string expFormat = ExpandFormat(encoding); encoding.ExpandedFormat = expFormat; encoding = FindFormatBaseValues(encoding); encoding = FindParameterIndexes(encoding); EncodeList.Add(encoding); EncodeDict.Add(encoding.Command, encoding); AddToDecodeLists(expFormat, encoding); } } } catch (Exception ex) { } finally { reader.Close(); } }
public void AddToOpcodeList(int opcode, EncodingFormat encoding) { List<EncodingFormat> decodeList = null; if (DecodeOpcodeList[opcode] != null) { decodeList = DecodeOpcodeList[opcode]; decodeList.Add(encoding); DecodeOpcodeList[opcode] = decodeList; } else { decodeList = new List<EncodingFormat>(); decodeList.Add(encoding); DecodeOpcodeList[opcode] = decodeList; } }
public static EncodingFormat FindParameterIndexes(EncodingFormat format) { List <int> regPositions = new List <int>(); List <int[]> partialRegPositions = new List <int[]>(); List <int> immedPositions = new List <int>(); List <int> regIncludeMasks = new List <int>(); List <int[]> partialRegIncludeMasks = new List <int[]>(); List <int> immedIncludeMasks = new List <int>(); string expFormat = format.ExpandedFormat; string formatBinary = format.Binary; char currentChar = (char)ASMStringHelper.CharOffsets.UpperLetter; for (int i = 0; i < format.NumRegs; i++) { if (format.RegisterTypes[i] == ASMElementTypeCharacter.PartialVFPURegister) { int[] partialPositions = new int[2]; int[] partialIncludeMasks = new int[2]; int part1Index = formatBinary.IndexOf("[p" + (i + 1).ToString() + "-1"); int part2Index = formatBinary.IndexOf("[p" + (i + 1).ToString() + "-2"); int firstIndex = expFormat.IndexOf(currentChar); int searchPartIndex = firstIndex; for (; expFormat[searchPartIndex] == currentChar; searchPartIndex++) { ; } int secondIndex = expFormat.IndexOf(currentChar, searchPartIndex); if (part1Index > part2Index) { partialPositions[0] = secondIndex; partialPositions[1] = firstIndex; } else { partialPositions[0] = firstIndex; partialPositions[1] = secondIndex; } partialPositions[0] = InstructionBitLength - partialPositions[0] - format.PartialRegisterSizes[0]; partialPositions[1] = InstructionBitLength - partialPositions[1] - format.PartialRegisterSizes[1]; partialIncludeMasks[0] = ASMValueHelper.GetIncludeMask(format.PartialRegisterSizes[0]); partialIncludeMasks[1] = ASMValueHelper.GetIncludeMask(format.PartialRegisterSizes[1]); partialRegPositions.Add(partialPositions); partialRegIncludeMasks.Add(partialIncludeMasks); regPositions.Add(0); regIncludeMasks.Add(0); } else { regPositions.Add(InstructionBitLength - expFormat.IndexOf(currentChar) - ASMRegisterHelper.GetEncodingBitLength(format.RegisterTypes[i])); regIncludeMasks.Add(ASMRegisterHelper.GetRegisterIncludeMask(format.RegisterTypes[i])); partialRegPositions.Add(null); partialRegIncludeMasks.Add(null); } currentChar++; } currentChar = (char)ASMStringHelper.CharOffsets.LowerLetter; for (int i = 0; i < format.NumImmeds; i++) { immedPositions.Add(InstructionBitLength - expFormat.IndexOf(currentChar) - format.ImmediateLengths[i]); immedIncludeMasks.Add(ASMValueHelper.GetIncludeMask(format.ImmediateLengths[i])); currentChar++; } format.RegisterPositions = regPositions; format.PartialRegisterPositions = partialRegPositions; format.ImmediatePositions = immedPositions; format.RegisterIncludeMasks = regIncludeMasks; format.PartialRegisterIncludeMasks = partialRegIncludeMasks; format.ImmediateIncludeMasks = immedIncludeMasks; return(format); }
private EncodingFormat FindFormatBaseValues(EncodingFormat encoding) { uint[] baseValues = FindBaseValues(encoding.ExpandedFormat); encoding.BaseEncoding = baseValues[0]; encoding.BitMask = baseValues[1]; encoding.Opcode = (int)baseValues[2]; encoding.Function = (int)baseValues[3]; return encoding; }
private string DecodeASMSingle(uint line, uint pc, bool useRegAliases) { _illegalFlag = false; // Find the binary line and format //string binaryLine = ASMValueHelper.HexToBinary_WithLength(line, 32); //uint uBinaryLine = ASMValueHelper.BinaryToUnsigned(binaryLine); EncodingFormat encFormat = FormatHelper.FindFormatByBinary(line); // If we couldn't find the command, it's some kind of mystery! Either not included in // the encoding file, or an illegal instruction. if (encFormat == null) { _errorTextBuilder.AppendLine("WARNING: Unknown command: " + ASMValueHelper.UnsignedToHex_WithLength(line, 8).ToUpper()); return("unknown"); } string newFormat = encFormat.ExpandedFormat; string syntax = encFormat.Syntax; string formatBinary = encFormat.Binary; string newSyntax = syntax; // Loop through syntax field and replace appropriate values int regIndex = 0; int immedIndex = 0; string argValue = ""; //string binaryValue = ""; //string prevBinaryValue = ""; int numericValue = 0; int prevNumericValue = 0; int syntaxLength = syntax.Length; int newIndex = 0; for (int i = 0; i < syntaxLength; i++) { char c = syntax[i]; // If this is a register or immediate, find value to replace in the syntax for the decoding if (char.IsLetter(c)) { int metaType = ASMFormatHelper.FindElementMetaType(c); if (metaType == ASMElementMetaType.Register) { char lookupChar = ASMStringHelper.CreateRegisterChar(regIndex); //int vfpuRegMode = (c == ASMElementTypeCharacter.VFPURegister ? encFormat.VFPURegisterTypes[regIndex] : 0); switch (c) { case ASMElementTypeCharacter.PartialVFPURegister: argValue = DecodePartialVFPURegister(encFormat, line, regIndex, lookupChar); break; case ASMElementTypeCharacter.InvertedSingleBitVFPURegister: numericValue = FindNumericArgValue(line, encFormat.RegisterPositions[regIndex], encFormat.RegisterIncludeMasks[regIndex]); argValue = DecodeInvertedSingleBitVFPURegister(numericValue, encFormat.VFPURegisterTypes[regIndex]); break; case ASMElementTypeCharacter.VFPURegister: numericValue = FindNumericArgValue(line, encFormat.RegisterPositions[regIndex], encFormat.RegisterIncludeMasks[regIndex]); argValue = DecodeRegister(numericValue, c, useRegAliases, encFormat.VFPURegisterTypes[regIndex]); break; default: //int binaryIndex = newFormat.IndexOf(lookupChar); //binaryValue = binaryLine.Substring(binaryIndex, ASMRegisterHelper.GetEncodingBitLength(c)); numericValue = FindNumericArgValue(line, encFormat.RegisterPositions[regIndex], encFormat.RegisterIncludeMasks[regIndex]); argValue = DecodeRegister(numericValue, c, useRegAliases, 0); break; } regIndex++; } else if (metaType == ASMElementMetaType.Immediate) { char lookupChar = ASMStringHelper.CreateImmediateChar(immedIndex); int binaryIndex = newFormat.IndexOf(lookupChar); //prevBinaryValue = binaryValue; prevNumericValue = numericValue; int immedLength = encFormat.ImmediateLengths[immedIndex]; int hexLength = (immedLength + 3) / 4; //binaryValue = binaryLine.Substring(binaryIndex, immedLength); //numericValue = FindNumericArgValue(line, encFormat.ImmediatePositions[immedIndex], ASMValueHelper.GetIncludeMask(encFormat.ImmediateLengths[immedIndex])); numericValue = FindNumericArgValue(line, encFormat.ImmediatePositions[immedIndex], encFormat.ImmediateIncludeMasks[immedIndex]); switch (c) { case ASMElementTypeCharacter.SignedImmediate: argValue = DecodeSignedImmediate(numericValue, hexLength); break; case ASMElementTypeCharacter.UnsignedImmediate: argValue = DecodeUnsignedImmediate(numericValue, hexLength); break; case ASMElementTypeCharacter.BranchImmediate: argValue = DecodeBranchImmediate(numericValue, pc); break; case ASMElementTypeCharacter.JumpImmediate: argValue = DecodeJumpImmediate(numericValue, pc); break; case ASMElementTypeCharacter.DecrementedImmediate: argValue = DecodeDecrementedImmediate(numericValue, hexLength); break; case ASMElementTypeCharacter.ModifiedImmediate: argValue = DecodeModifiedImmediate(numericValue, prevNumericValue, hexLength); break; case ASMElementTypeCharacter.ShiftedImmediate: argValue = DecodeShiftedImmediate(numericValue, encFormat.ShiftedImmediateAmounts[immedIndex], hexLength); break; case ASMElementTypeCharacter.VFPUPrefixImmediate: argValue = DecodeVFPUPrefixImmediate(numericValue, encFormat.VFPUPrefixType); break; default: break; } immedIndex++; } // Replace character in syntax with correct value newSyntax = ASMStringHelper.ReplaceCharAtIndex(newSyntax, newIndex, argValue); newIndex += argValue.Length - 1; } newIndex++; } string spacing = string.IsNullOrEmpty(newSyntax) ? "" : " "; string decoding = encFormat.Command + spacing + newSyntax; if (_illegalFlag) { decoding = "illegal"; _errorTextBuilder.AppendLine(ASMStringHelper.Concat("Illegal instruction: ", line.ToString("x"), ": ", encFormat.Command.ToUpper(), " (", _illegalMessage, ")")); } return(decoding); }
// Translates a single pseudoinstruction public EncodeLine[] TranslatePseudoSingle(EncodingFormat encoding, string[] parts, int index, uint pc, bool skipLabelAssertion = false) { List<EncodeLine> result = new List<EncodeLine>(); int startParenIndex = 0; int endParenIndex = 0; string strImmed = ""; string[] newParts; uint ivalue = 0; //long lvalue = 0; ushort ushortval = 0; //short shortval = 0; bool useNegativeOffset = false; string regS = ""; int argIndex0 = 0; int argIndex1 = 0; bool doesBranchIfEqual = false; bool isStore = false; bool useAT = false; // Find args string strArgs = ""; string[] args = null; if (!string.IsNullOrEmpty(parts[1])) { strArgs = ASMStringHelper.RemoveSpaces(parts[1]); args = strArgs.Split(','); } switch (encoding.Command) { case "jalr": if (args.Length == 1) { parts[1] = args[0] + ",ra"; } result.Add(new EncodeLine(parts,index)); break; case "mul": case "div": case "rem": case "mod": if ((encoding.Command == "div") && (args.Length < 3)) { result.Add(new EncodeLine(parts,index)); break; } newParts = new string[2]; newParts[0] = (encoding.Command == "mul") ? "mult" : "div"; newParts[1] = args[1] + "," + args[2]; result.Add(new EncodeLine(newParts,index)); parts[0] = ((encoding.Command == "mul") || (encoding.Command == "div")) ? "mflo" : "mfhi"; parts[1] = args[0]; result.Add(new EncodeLine(parts,index)); break; case "bgt": case "blt": case "bge": case "ble": argIndex0 = ((encoding.Command == "bgt") || (encoding.Command == "ble")) ? 1 : 0; argIndex1 = (argIndex0 > 0) ? 0 : 1; doesBranchIfEqual = ((encoding.Command == "bge") || (encoding.Command == "ble")); newParts = new string[2]; newParts[0] = "slt"; newParts[1] = "at," + args[argIndex0] + "," + args[argIndex1]; result.Add(new EncodeLine(newParts,index)); parts[0] = doesBranchIfEqual ? "beq" : "bne"; parts[1] = "at,zero," + args[2]; result.Add(new EncodeLine(parts,index)); break; case "lbu": case "lb": case "lhu": case "lh": case "lw": case "sb": case "sh": case "sw": bool isHiLo = ((args[1].ToLower().StartsWith("%hi")) || (args[1].ToLower().StartsWith("%lo"))); startParenIndex = args[1].IndexOf('(', (isHiLo ? 4 : 0)); // check -1 endParenIndex = args[1].IndexOf(')', (startParenIndex >= 0) ? startParenIndex : 0); isStore = encoding.Command.ToLower().StartsWith("s"); useAT = ((startParenIndex >= 0) || (isStore)); if (startParenIndex >= 0) { regS = args[1].Substring(startParenIndex+1, endParenIndex-startParenIndex-1); strImmed = args[1].Substring(0,startParenIndex); } else strImmed = args[1]; ivalue = ValueHelper.GetAnyUnsignedValue(strImmed, skipLabelAssertion); bool isLabel = !( ((strImmed.StartsWith("0x")) || (strImmed.StartsWith("-0x"))) || (ASMStringHelper.StringIsNumeric(strImmed)) || ((strImmed.StartsWith("-")) && (strImmed.Length > 1)) || (isHiLo) ); if (((ivalue > 0x7fff) && (strImmed[0] != '-') && (!isHiLo)) || isLabel) { ushortval = (ushort)(ivalue & 0xffff); if (ushortval >= 0x8000) { useNegativeOffset = true; ushortval = (ushort)(0x10000 - ushortval); } newParts = new string[2]; newParts[0] = "lui"; newParts[1] = (useAT ? "at" : args[0]) + "," + ((ivalue >> 16) + (useNegativeOffset ? 1 : 0)); result.Add(new EncodeLine(newParts,index)); if (startParenIndex >= 0) { newParts = new string[2]; newParts[0] = "addu"; newParts[1] = "at,at," + regS; result.Add(new EncodeLine(newParts,index)); } parts[1] = args[0] + "," + (useNegativeOffset ? "-" : "") + ushortval + "(" + (useAT ? "at" : args[0]) + ")"; result.Add(new EncodeLine(parts,index)); } else result.Add(new EncodeLine(parts,index)); break; // "la" always translates to two instructions, while "li" can translate to one. case "la": case "li": //ivalue = ValueHelper.GetAnyUnsignedValue(args[1]); /* try { ivalue = ValueHelper.GetAnyUnsignedValue(args[1]); //ivalue = ValueHelper.FindUnsignedValue(args[1]); } catch { ivalue = 0; } */ ivalue = ValueHelper.GetAnyUnsignedValue(args[1], skipLabelAssertion); bool isLA = encoding.Command.Equals("la"); if (ivalue >= 0xffff8000) { parts[0] = "addiu"; parts[1] = args[0] + ",zero," + ((ushort)(ivalue & 0xffff)); result.Add(new EncodeLine(parts,index)); } else if ((ivalue > 0xffff) || isLA) { newParts = new string[2]; newParts[0] = "lui"; newParts[1] = args[0] + "," + (ivalue >> 16); result.Add(new EncodeLine(newParts,index)); ushortval = (ushort)(ivalue & 0xffff); if ((ushortval > 0) || (isLA)) { parts[0] = "ori"; parts[1] = args[0] + "," + args[0] + "," + ushortval; result.Add(new EncodeLine(parts,index)); } } else { if (!((args[1].StartsWith("0x") || ASMStringHelper.StringIsNumeric(args[1])))) parts[1] = args[0] + "," + ValueHelper.LabelHelper.LabelToUnsigned(args[1], skipLabelAssertion); result.Add(new EncodeLine(parts,index)); } break; default: result.Add(new EncodeLine(parts,index)); break; } return result.ToArray(); }
private EncodingFormat FindFormatDetails(EncodingFormat encoding) { List<char> registerTypes = new List<char>(); List<char> immediateTypes = new List<char>(); string syntax = encoding.Syntax; int numRegs = 0; int numImmeds = 0; foreach (char c in syntax) { if (char.IsLetter(c)) { int metaType = FindElementMetaType(c); if (metaType == ASMElementMetaType.Register) { numRegs++; registerTypes.Add(c); } else if (metaType == ASMElementMetaType.Immediate) { numImmeds++; immediateTypes.Add(c); } } } encoding.RegisterTypes = registerTypes; encoding.ImmediateTypes = immediateTypes; encoding.NumRegs = numRegs; encoding.NumImmeds = numImmeds; return encoding; }
public byte[] UpdateBlockReferences(byte[] bytes, uint pc, bool littleEndian, IEnumerable <BlockMove> blockMoves) { int byteCount = bytes.Length; if (byteCount < 4) { return(bytes); } byte[] resultBytes = new byte[byteCount]; int startIndex = 0; byte[] asmBytes = bytes; if (byteCount > 4) { uint offsetBytes = pc % 4; if (offsetBytes != 0) { uint skipBytes = 4 - offsetBytes; pc = pc + skipBytes; startIndex += (int)skipBytes; int length = (int)(bytes.Length - skipBytes); byte[] newBytes = new byte[length]; Array.Copy(bytes, skipBytes, newBytes, 0, length); Array.Copy(bytes, 0, resultBytes, 0, startIndex); asmBytes = newBytes; } } uint[] instructions = ASMValueHelper.GetUintArrayFromBytes(asmBytes, littleEndian); int numInstructions = instructions.Length; uint[] newInstructions = new uint[numInstructions]; uint[] regLuiValues = new uint[32]; int[] regLuiIndexes = new int[32]; for (int regNum = 0; regNum < 32; regNum++) { regLuiIndexes[regNum] = -1; } for (int index = 0; index < numInstructions; index++) { uint uBinaryLine = instructions[index]; uint opcode = (uBinaryLine >> 26); uint newInstruction = uBinaryLine; // Is unconditional jump literal command J or JAL if ((opcode & 0x3E) == 0x02) // ((opcode & 0b111110) == 0b000010) { uint jumpAddress = (((uBinaryLine & 0x03FFFFFFU) << 2) | (pc & 0xF0000000U)); foreach (BlockMove blockMove in blockMoves) { if ((jumpAddress >= blockMove.Location) && (jumpAddress < blockMove.EndLocation)) { uint newJumpAddress = (uint)(jumpAddress + blockMove.Offset); newInstruction = (opcode << 26) | ((newJumpAddress >> 2) & 0x03FFFFFFU); } } } // Is Load Upper Immediate (LUI) EncodingFormat encFormat = Decoder.FormatHelper.FindFormatByBinary(uBinaryLine); if (encFormat.Command == "lui") { int regNum = (int)(uBinaryLine >> encFormat.RegisterPositions[0] & encFormat.RegisterIncludeMasks[0]); uint immediate = (uint)(uBinaryLine >> encFormat.ImmediatePositions[0] & encFormat.ImmediateIncludeMasks[0]); regLuiValues[regNum] = immediate; regLuiIndexes[regNum] = index; } // Is Load or Store command, or ADDI, ADDIU, or ORI if (IsLoadCommand(encFormat.Command) || IsStoreCommand(encFormat.Command) || ((encFormat.Command == "addi") || (encFormat.Command == "addiu") || (encFormat.Command == "ori"))) { int regNum = (int)(uBinaryLine >> encFormat.RegisterPositions[1] & encFormat.RegisterIncludeMasks[1]); if (regLuiIndexes[regNum] >= 0) { short offset = ASMValueHelper.UnsignedShortToSignedShort((ushort)(uBinaryLine & 0xffff)); uint targetAddress = (uint)((regLuiValues[regNum] << 16) + offset) | (0x80000000U); foreach (BlockMove blockMove in blockMoves) { if ((targetAddress >= blockMove.Location) && (targetAddress < blockMove.EndLocation)) { uint newTargetAddress = (uint)(targetAddress + blockMove.Offset); uint newLuiValue = (ushort)(newTargetAddress >> 16); ushort newOffset = (ushort)(newTargetAddress & 0xffff); if (encFormat.Command != "ori") { newLuiValue += (uint)((newOffset >= 0x8000) ? 1 : 0); } newInstruction = ((uBinaryLine & 0xFFFF0000U) | newOffset); // Modify the LUI if necessary if (newLuiValue != regLuiValues[regNum]) { uint newLuiInstruction = (newInstructions[regLuiIndexes[regNum]] & 0xFFFF0000U) | newLuiValue; newInstructions[regLuiIndexes[regNum]] = newLuiInstruction; byte[] newLuiInstructionBytes = ASMValueHelper.ConvertUIntToBytes(newLuiInstruction, littleEndian); Array.Copy(newLuiInstructionBytes, 0, resultBytes, (regLuiIndexes[regNum] * 4) + startIndex, 4); } } } } } newInstructions[index] = newInstruction; byte[] newBytes = ASMValueHelper.ConvertUIntToBytes(newInstruction, littleEndian); Array.Copy(newBytes, 0, resultBytes, (index * 4) + startIndex, 4); } for (int index = (numInstructions * 4) + startIndex; index < byteCount; index++) { resultBytes[index] = bytes[index]; } return(resultBytes); }
public ASMEncoderResult EncodeASM(string asm, uint pc, string spacePadding, bool includeAddress, bool littleEndian, bool clearErrorText) { if (clearErrorText) { ClearErrorText(); } string[] lines = asm.Split('\n'); lines = ASMStringHelper.RemoveFromLines(lines, "\r"); string[] processLines = AddLabelLines(lines); string oldErrorText = _errorTextBuilder.ToString(); EncodeLine[] encodeLines = PreprocessLines(processLines, pc); int encodeLineIndex = 0; int lineIndex = 0; StringBuilder newTextASMBuilder = new StringBuilder(); StringBuilder newTextASMLineBuilder = new StringBuilder(); StringBuilder encodedASMBuilder = new StringBuilder(); List <byte> byteList = new List <byte>(); if (oldErrorText != _errorTextBuilder.ToString()) { return(new ASMEncoderResult(encodedASMBuilder.ToString(), byteList.ToArray(), asm, _errorTextBuilder.ToString())); } foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { newTextASMBuilder.AppendLine(); continue; } newTextASMLineBuilder.Length = 0; string modLine = ASMStringHelper.RemoveLeadingBracketBlock(line); string processLine = ASMStringHelper.RemoveLeadingSpaces(modLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); string[] parts = ASMStringHelper.SplitLine(processLine); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); parts = ASMStringHelper.RemoveLabel(parts); // If this is an ASM command, pass off line to encoding routine EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { if (includeAddress) { newTextASMLineBuilder.Append("[0x"); newTextASMLineBuilder.Append(ASMValueHelper.UnsignedToHex_WithLength(pc, 8)); newTextASMLineBuilder.Append("] "); } newTextASMLineBuilder.AppendLine(modLine); EncodeLine eLine = new EncodeLine(); if (encodeLines.Length > 0) { eLine = encodeLines[encodeLineIndex]; } while ((eLine.LineIndex == lineIndex) && (encodeLineIndex < encodeLines.Length)) { encodingOrNull = FormatHelper.FindFormatByCommand(eLine.LineParts[0]); EncodingFormat encoding = encodingOrNull; ASMSingleEncodeResult singleEncodeResult = TryEncodeSingle(eLine.LineParts, encoding, pc, modLine, littleEndian); encodedASMBuilder.Append(spacePadding); encodedASMBuilder.Append(singleEncodeResult.ASMText); encodedASMBuilder.AppendLine(); //encodedASMBuilder.Append("\r\n"); byteList.AddRange(singleEncodeResult.Bytes); encodeLineIndex++; pc += 4; if (encodeLineIndex < encodeLines.Length) { eLine = encodeLines[encodeLineIndex]; } } lineIndex++; } else { if (!string.IsNullOrEmpty(parts[0])) { if ((parts[0] != ".org") && (parts[0] != ".label") && (parts[0] != ".eqv") && (!parts[0].EndsWith(":"))) { _errorTextBuilder.AppendLine("WARNING: Ignoring unknown command \"" + parts[0] + "\"."); } } } if (string.IsNullOrEmpty(newTextASMLineBuilder.ToString())) { newTextASMLineBuilder.AppendLine(modLine); } newTextASMBuilder.Append(newTextASMLineBuilder.ToString()); } string newTextASM = newTextASMBuilder.ToString(); if (newTextASM.EndsWith("\r\n")) { newTextASMBuilder.Length -= 2; } else if (newTextASM.EndsWith("\n")) { newTextASMBuilder.Length -= 1; } newTextASM = newTextASMBuilder.ToString(); return(new ASMEncoderResult(encodedASMBuilder.ToString(), byteList.ToArray(), newTextASM, _errorTextBuilder.ToString())); }
// Translates pseudoinstructions public ASMTranslatePseudoResult TranslatePseudo(string[] lines, uint startPC, bool skipLabelAssertion = false) { _errorTextBuilder.Length = 0; bool reportErrors = !skipLabelAssertion; ASMTranslatePseudoResult result = new ASMTranslatePseudoResult(); List <EncodeLine> resultLines = new List <EncodeLine>(); int index = 0; uint pc = startPC; List <bool> isSkippingLine = new List <bool>() { false }; int ifNestLevel = 0; foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { continue; } string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line); processLine = ASMStringHelper.RemoveLeadingSpaces(processLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); processLine = ASMStringHelper.ConvertBracketBlocks(processLine); string[] parts = ASMStringHelper.SplitLine(processLine); parts = ASMStringHelper.RemoveLabel(parts); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts, false); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); string firstPart = parts[0].ToLower().Trim(); if (firstPart == ".endif") { if (ifNestLevel == 0) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: No matching .if statement for .endif statement at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8)); } } else { isSkippingLine.RemoveAt(isSkippingLine.Count - 1); ifNestLevel--; } } else if (firstPart == ".else") { if (ifNestLevel == 0) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: No matching .if statement for .else statement at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8)); } } else if (!isSkippingLine[ifNestLevel - 1]) { isSkippingLine[ifNestLevel] = !isSkippingLine[ifNestLevel]; } } else if (firstPart == ".if") { try { string[] innerParts = parts[1].Split(','); if (!parts[1].Contains(",")) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: Unreachable code at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8) + " inside .if statement with bad argument list (no commas): \"" + parts[1] + "\""); } isSkippingLine.Add(true); ifNestLevel++; } else if (innerParts.Length < 2) { if (reportErrors) { _errorTextBuilder.AppendLine("WARNING: Unreachable code at address 0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8) + " inside .if statement with bad argument list (less than 2 arguments): \"" + parts[1] + "\""); } isSkippingLine.Add(true); ifNestLevel++; } else if (isSkippingLine[ifNestLevel]) { isSkippingLine.Add(true); ifNestLevel++; } else { string operation = string.Empty; string eqvKey, eqvValue; if (innerParts.Length >= 3) { operation = ASMStringHelper.RemoveSpaces(innerParts[0]); eqvKey = ASMStringHelper.RemoveSpaces(innerParts[1]); eqvValue = ASMStringHelper.RemoveSpaces(innerParts[2]); } else { operation = "="; eqvKey = ASMStringHelper.RemoveSpaces(innerParts[0]); eqvValue = ASMStringHelper.RemoveSpaces(innerParts[1]); } int intKey = 0; int intValue = 0; bool isKeyInt = int.TryParse(eqvKey, out intKey); bool isValueInt = int.TryParse(eqvValue, out intValue); bool isIntCompare = isKeyInt && isValueInt; bool isPass = false; switch (operation) { case "=": case "==": isPass = eqvKey.Equals(eqvValue); break; case "!=": case "<>": isPass = !eqvKey.Equals(eqvValue); break; case "<": isPass = isIntCompare && (intKey < intValue); break; case ">": isPass = isIntCompare && (intKey > intValue); break; case "<=": isPass = isIntCompare && (intKey <= intValue); break; case ">=": isPass = isIntCompare && (intKey >= intValue); break; default: break; } isSkippingLine.Add(!isPass); ifNestLevel++; } } catch (Exception ex) { if (reportErrors) { _errorTextBuilder.AppendLine("Error on .if statement: " + ex.Message + "\r\n"); } } } else { // If this is an ASM command, pass off line to translating routine EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { try { if (!isSkippingLine[ifNestLevel]) { EncodingFormat encoding = encodingOrNull; EncodeLine[] encodeLines = TranslatePseudoSingle(encoding, parts, index, pc, skipLabelAssertion); foreach (EncodeLine encodeLine in encodeLines) { resultLines.Add(encodeLine); pc += 4; } //index++; } } catch (Exception ex) { if (reportErrors) { //result.errorMessage = "Error translating pseudoinstruction: " + line; _errorTextBuilder.Append("Error translating pseudoinstruction: " + line + " (" + ex.Message + ")\r\n"); } //result.lines = null; //return result; //index++; } index++; } } } result.lines = resultLines.ToArray(); result.errorMessage = _errorTextBuilder.ToString(); return(result); }
private ASMSingleEncodeResult EncodeASMSingle(string[] parts, EncodingFormat encoding, uint pc, bool littleEndian) { // Initialize variables //string binary = ""; //string hex = ""; string strArgs = ""; string[] args = null; /* * if (!string.IsNullOrEmpty(parts[1])) * { * strArgs = ASMStringHelper.RemoveSpaces(parts[1]).Replace('(',',').Replace(")",""); * args = strArgs.Split(','); * } */ // Find encoding format and syntax string command = parts[0].ToLower(); EncodingFormat encodingFormat = FormatHelper.FindFormatByCommand(command); string formatBinary = encodingFormat.Binary; string syntax = encodingFormat.Syntax; string newFormat = formatBinary; if (!string.IsNullOrEmpty(parts[1])) { List <string> argsList = new List <string>(); strArgs = ASMStringHelper.RemoveSpaces(parts[1]); bool foundArg = false; int strArgCharIndex = 0; foreach (char currentChar in syntax) { if (Char.IsLetter(currentChar)) { foundArg = true; } else if (foundArg) { foundArg = false; bool isHiLo = ((strArgs.IndexOf("%hi(", strArgCharIndex) == strArgCharIndex) || (strArgs.IndexOf("%lo(", strArgCharIndex) == strArgCharIndex)); int separatorIndex = strArgs.IndexOf(currentChar, strArgCharIndex + (isHiLo ? 4 : 0)); argsList.Add(strArgs.Substring(strArgCharIndex, separatorIndex - strArgCharIndex)); strArgCharIndex = separatorIndex + 1; } } if (foundArg) { argsList.Add(strArgs.Substring(strArgCharIndex, strArgs.Length - strArgCharIndex)); } args = argsList.ToArray(); } // Create array for registers and immediates Nullable <uint>[] regValue = new Nullable <uint> [26]; Nullable <uint>[][] partialRegValue = new Nullable <uint> [26][]; uint[] immedValue = new uint[26]; int argsIndex = 0; int regIndex = 0; int immedIndex = 0; // Fill arrays based on order of arguments (syntax) foreach (char elementTypeChar in syntax) { bool incrementArgsIndex = true; switch (elementTypeChar) { case ASMElementTypeCharacter.GPRegister: regValue[regIndex++] = EncodeGPRegister(args[argsIndex]); break; case ASMElementTypeCharacter.GenericRegister: regValue[regIndex++] = EncodeGenericRegister(args[argsIndex]); break; case ASMElementTypeCharacter.FloatRegister: regValue[regIndex++] = EncodeFloatRegister(args[argsIndex]); break; case ASMElementTypeCharacter.VFPURegister: regValue[regIndex] = EncodeVFPURegister(args[argsIndex], encodingFormat.VFPURegisterTypes[regIndex]); regIndex++; break; case ASMElementTypeCharacter.PartialVFPURegister: partialRegValue[regIndex] = EncodePartialVFPURegister(args[argsIndex], encodingFormat.VFPURegisterTypes[regIndex], encodingFormat.PartialRegisterSizes, encodingFormat.PartialRegisterIncludeMasks[regIndex]); regIndex++; break; case ASMElementTypeCharacter.InvertedSingleBitVFPURegister: regValue[regIndex] = EncodeInvertedSingleBitVFPURegister(args[argsIndex], encodingFormat.VFPURegisterTypes[regIndex]); regIndex++; break; case ASMElementTypeCharacter.Cop0Register: regValue[regIndex] = EncodeCop0Register(args[argsIndex]); regIndex++; break; case ASMElementTypeCharacter.GTEControlRegister: regValue[regIndex] = EncodeGTEControlRegister(args[argsIndex]); regIndex++; break; case ASMElementTypeCharacter.GTEDataRegister: regValue[regIndex] = EncodeGTEDataRegister(args[argsIndex]); regIndex++; break; case ASMElementTypeCharacter.SignedImmediate: case ASMElementTypeCharacter.UnsignedImmediate: immedValue[immedIndex] = EncodeImmediate(args[argsIndex], encodingFormat.ImmediateLengths[immedIndex], (uint)encodingFormat.ImmediateIncludeMasks[immedIndex]); immedIndex++; break; case ASMElementTypeCharacter.BranchImmediate: immedValue[immedIndex] = EncodeBranchImmediate(args[argsIndex], pc, (uint)encodingFormat.ImmediateIncludeMasks[immedIndex]); immedIndex++; break; case ASMElementTypeCharacter.JumpImmediate: immedValue[immedIndex] = EncodeJumpImmediate(args[argsIndex], 26, pc); immedIndex++; break; case ASMElementTypeCharacter.DecrementedImmediate: immedValue[immedIndex] = EncodeDecrementedImmediate(args[argsIndex], encodingFormat.ImmediateLengths[immedIndex], (uint)encodingFormat.ImmediateIncludeMasks[immedIndex]); immedIndex++; break; case ASMElementTypeCharacter.ModifiedImmediate: immedValue[immedIndex] = EncodeModifiedImmediate(args[argsIndex], args[argsIndex - 1], encodingFormat.ImmediateLengths[immedIndex], (uint)encodingFormat.ImmediateIncludeMasks[immedIndex]); immedIndex++; break; case ASMElementTypeCharacter.ShiftedImmediate: immedValue[immedIndex] = EncodeShiftedImmediate(args[argsIndex], encodingFormat.ImmediateLengths[immedIndex], encodingFormat.ShiftedImmediateAmounts[immedIndex], (uint)encodingFormat.ImmediateIncludeMasks[immedIndex]); immedIndex++; break; case ASMElementTypeCharacter.VFPUPrefixImmediate: immedValue[immedIndex] = EncodeVFPUPrefixImmediate(args[argsIndex], encodingFormat.VFPUPrefixType, encodingFormat.ImmediateLengths[immedIndex]); immedIndex++; break; default: incrementArgsIndex = false; break; } if (incrementArgsIndex) { argsIndex++; } } /* * // Replace bracket blocks in format with appropriate values * for (int i = 0; i < regIndex; i++) * { * newFormat = newFormat.Replace("[" + encodingFormat.RegisterTypes[i] + (i + 1) + "]", regBinary[i]); * * if (partialRegBinary[i] != null) * { * newFormat = newFormat.Replace("[" + encodingFormat.RegisterTypes[i] + (i + 1) + "-1]", partialRegBinary[i][0]); * newFormat = newFormat.Replace("[" + encodingFormat.RegisterTypes[i] + (i + 1) + "-2]", partialRegBinary[i][1]); * } * } * for (int i = 0; i < immedIndex; i++) * { * newFormat = newFormat.Replace("[" + encodingFormat.ImmediateTypes[i] + (i + 1) + "]", immedBinary[i]); * } * * binary = newFormat; */ uint uEncodingValue = encodingFormat.BaseEncoding; for (int i = 0; i < regIndex; i++) { if (regValue[i] != null) { uEncodingValue |= (((uint)regValue[i]) << encodingFormat.RegisterPositions[i]); } else if (partialRegValue[i] != null) { uEncodingValue |= (((uint)partialRegValue[i][0]) << encodingFormat.PartialRegisterPositions[i][0]); uEncodingValue |= (((uint)partialRegValue[i][1]) << encodingFormat.PartialRegisterPositions[i][1]); } } for (int i = 0; i < immedIndex; i++) { uEncodingValue |= (immedValue[i] << encodingFormat.ImmediatePositions[i]); } //byte[] bytes = BitConverter.GetBytes(uEncodingValue); byte[] bytes = ASMValueHelper.ConvertUIntToBytes(uEncodingValue, littleEndian); if (littleEndian) { uEncodingValue = ASMValueHelper.ReverseBytes(uEncodingValue); } //else //{ // Array.Reverse(bytes); //} string hex = ASMValueHelper.UnsignedToHex_WithLength(uEncodingValue, 8).ToUpper(); return(new ASMSingleEncodeResult(hex, bytes)); }
// Regs use uppercase letters, immediates use lowercase letters: [r1] becomes AAAAA, [i1] becomes aaa if length = 3, etc. public static string ExpandFormat(EncodingFormat format) { int numRegs = format.NumRegs; int numImmeds = format.NumImmeds; string newFormatBinary = format.Binary; for (int i = 0; i < numRegs; i++) { char elementTypeChar = format.RegisterTypes[i]; string strElementTypeChar = elementTypeChar.ToString(); int iPlusOne = i + 1; string strIPlusOne = iPlusOne.ToString(); newFormatBinary = newFormatBinary.Replace("[" + strElementTypeChar + strIPlusOne + "]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateUpperLetterChar(i), ASMRegisterHelper.GetEncodingBitLength(elementTypeChar))); if (format.PartialRegisterSizes != null) { newFormatBinary = newFormatBinary.Replace("[" + strElementTypeChar + strIPlusOne + "-1]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateUpperLetterChar(i), format.PartialRegisterSizes[0])); newFormatBinary = newFormatBinary.Replace("[" + strElementTypeChar + strIPlusOne + "-2]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateUpperLetterChar(i), format.PartialRegisterSizes[1])); } } for (int i = 0; i < numImmeds; i++) { newFormatBinary = newFormatBinary.Replace("[" + format.ImmediateTypes[i] + (i + 1) + "]", ASMStringHelper.CreateCharacterString(ASMStringHelper.CreateLowerLetterChar(i), format.ImmediateLengths[i])); } return newFormatBinary; }
// Translates a single pseudoinstruction public EncodeLine[] TranslatePseudoSingle(EncodingFormat encoding, string[] parts, int index, uint pc, bool skipLabelAssertion = false) { List <EncodeLine> result = new List <EncodeLine>(); int startParenIndex = 0; int endParenIndex = 0; string strImmed = ""; string[] newParts; uint ivalue = 0; //long lvalue = 0; ushort ushortval = 0; //short shortval = 0; bool useNegativeOffset = false; string regS = ""; int argIndex0 = 0; int argIndex1 = 0; bool doesBranchIfEqual = false; bool isStore = false; bool useAT = false; // Find args string strArgs = ""; string[] args = null; if (!string.IsNullOrEmpty(parts[1])) { strArgs = ASMStringHelper.RemoveSpaces(parts[1]); args = strArgs.Split(','); } switch (encoding.Command) { case "jalr": if (args.Length == 1) { //parts[1] = args[0] + ",ra"; parts[1] = "ra," + args[0]; } result.Add(new EncodeLine(parts, index)); break; case "mul": case "div": case "rem": case "mod": if ((encoding.Command == "div") && (args.Length < 3)) { result.Add(new EncodeLine(parts, index)); break; } newParts = new string[2]; newParts[0] = (encoding.Command == "mul") ? "mult" : "div"; newParts[1] = args[1] + "," + args[2]; result.Add(new EncodeLine(newParts, index)); parts[0] = ((encoding.Command == "mul") || (encoding.Command == "div")) ? "mflo" : "mfhi"; parts[1] = args[0]; result.Add(new EncodeLine(parts, index)); break; case "add": case "addu": case "and": case "min": case "max": case "nor": case "or": case "rotrv": case "sllv": case "slt": case "sltu": case "srav": case "srlv": case "sub": case "subu": case "xor": if (args.Length == 2) { parts[1] = args[0] + "," + parts[1]; } result.Add(new EncodeLine(parts, index)); break; case "addi": case "addiu": case "andi": case "ori": case "rotr": case "sll": case "slti": case "sltiu": case "sra": case "srl": case "xori": if (args.Length == 2) { parts[1] = args[0] + "," + parts[1]; } result.Add(new EncodeLine(parts, index)); break; case "bgt": case "blt": case "bge": case "ble": argIndex0 = ((encoding.Command == "bgt") || (encoding.Command == "ble")) ? 1 : 0; argIndex1 = (argIndex0 > 0) ? 0 : 1; doesBranchIfEqual = ((encoding.Command == "bge") || (encoding.Command == "ble")); newParts = new string[2]; newParts[0] = "slt"; newParts[1] = "at," + args[argIndex0] + "," + args[argIndex1]; result.Add(new EncodeLine(newParts, index)); parts[0] = doesBranchIfEqual ? "beq" : "bne"; parts[1] = "at,zero," + args[2]; result.Add(new EncodeLine(parts, index)); break; case "lbu": case "lb": case "lhu": case "lh": case "lw": case "sb": case "sh": case "sw": bool isHiLo = ((args[1].ToLower().StartsWith("%hi")) || (args[1].ToLower().StartsWith("%lo"))); startParenIndex = args[1].IndexOf('(', (isHiLo ? 4 : 0)); // check -1 endParenIndex = args[1].IndexOf(')', (startParenIndex >= 0) ? startParenIndex : 0); isStore = encoding.Command.ToLower().StartsWith("s"); useAT = ((startParenIndex >= 0) || (isStore)); if (startParenIndex >= 0) { regS = args[1].Substring(startParenIndex + 1, endParenIndex - startParenIndex - 1); strImmed = args[1].Substring(0, startParenIndex); } else { strImmed = args[1]; } ivalue = ValueHelper.GetAnyUnsignedValue(strImmed, skipLabelAssertion); bool isLabel = !( ((strImmed.StartsWith("0x")) || (strImmed.StartsWith("-0x"))) || (ASMStringHelper.StringIsNumeric(strImmed)) || ((strImmed.StartsWith("-")) && (strImmed.Length > 1)) || (isHiLo) ); if (((ivalue > 0x7fff) && (strImmed[0] != '-') && (!isHiLo)) || isLabel) { ushortval = (ushort)(ivalue & 0xffff); if (ushortval >= 0x8000) { useNegativeOffset = true; ushortval = (ushort)(0x10000 - ushortval); } newParts = new string[2]; newParts[0] = "lui"; newParts[1] = (useAT ? "at" : args[0]) + "," + ((ivalue >> 16) + (useNegativeOffset ? 1 : 0)); result.Add(new EncodeLine(newParts, index)); if (startParenIndex >= 0) { newParts = new string[2]; newParts[0] = "addu"; newParts[1] = "at,at," + regS; result.Add(new EncodeLine(newParts, index)); } parts[1] = args[0] + "," + (useNegativeOffset ? "-" : "") + ushortval + "(" + (useAT ? "at" : args[0]) + ")"; result.Add(new EncodeLine(parts, index)); } else { result.Add(new EncodeLine(parts, index)); } break; // "la" always translates to two instructions, while "li" can translate to one. case "la": case "li": //ivalue = ValueHelper.GetAnyUnsignedValue(args[1]); /* * try * { * ivalue = ValueHelper.GetAnyUnsignedValue(args[1]); * //ivalue = ValueHelper.FindUnsignedValue(args[1]); * } * catch * { * ivalue = 0; * } */ ivalue = ValueHelper.GetAnyUnsignedValue(args[1], skipLabelAssertion); bool isLA = encoding.Command.Equals("la"); if (ivalue >= 0xffff8000) { parts[0] = "addiu"; parts[1] = args[0] + ",zero," + ((ushort)(ivalue & 0xffff)); result.Add(new EncodeLine(parts, index)); } else if ((ivalue > 0xffff) || isLA) { newParts = new string[2]; newParts[0] = "lui"; newParts[1] = args[0] + "," + (ivalue >> 16); result.Add(new EncodeLine(newParts, index)); ushortval = (ushort)(ivalue & 0xffff); if ((ushortval > 0) || (isLA)) { parts[0] = "ori"; parts[1] = args[0] + "," + args[0] + "," + ushortval; result.Add(new EncodeLine(parts, index)); } } else { if (!((args[1].StartsWith("0x") || ASMStringHelper.StringIsNumeric(args[1])))) { parts[1] = args[0] + "," + ValueHelper.LabelHelper.LabelToUnsigned(args[1], skipLabelAssertion); } result.Add(new EncodeLine(parts, index)); } break; default: result.Add(new EncodeLine(parts, index)); break; } return(result.ToArray()); }
public static EncodingFormat FindParameterIndexes(EncodingFormat format) { List<int> regPositions = new List<int>(); List<int[]> partialRegPositions = new List<int[]>(); List<int> immedPositions = new List<int>(); List<int> regIncludeMasks = new List<int>(); List<int[]> partialRegIncludeMasks = new List<int[]>(); List<int> immedIncludeMasks = new List<int>(); string expFormat = format.ExpandedFormat; string formatBinary = format.Binary; char currentChar = (char)ASMStringHelper.CharOffsets.UpperLetter; for (int i = 0; i < format.NumRegs; i++) { if (format.RegisterTypes[i] == ASMElementTypeCharacter.PartialVFPURegister) { int[] partialPositions = new int[2]; int[] partialIncludeMasks = new int[2]; int part1Index = formatBinary.IndexOf("[p" + (i + 1).ToString() + "-1"); int part2Index = formatBinary.IndexOf("[p" + (i + 1).ToString() + "-2"); int firstIndex = expFormat.IndexOf(currentChar); int searchPartIndex = firstIndex; for (; expFormat[searchPartIndex] == currentChar; searchPartIndex++) ; int secondIndex = expFormat.IndexOf(currentChar, searchPartIndex); if (part1Index > part2Index) { partialPositions[0] = secondIndex; partialPositions[1] = firstIndex; } else { partialPositions[0] = firstIndex; partialPositions[1] = secondIndex; } partialPositions[0] = InstructionBitLength - partialPositions[0] - format.PartialRegisterSizes[0]; partialPositions[1] = InstructionBitLength - partialPositions[1] - format.PartialRegisterSizes[1]; partialIncludeMasks[0] = ASMValueHelper.GetIncludeMask(format.PartialRegisterSizes[0]); partialIncludeMasks[1] = ASMValueHelper.GetIncludeMask(format.PartialRegisterSizes[1]); partialRegPositions.Add(partialPositions); partialRegIncludeMasks.Add(partialIncludeMasks); regPositions.Add(0); regIncludeMasks.Add(0); } else { regPositions.Add(InstructionBitLength - expFormat.IndexOf(currentChar) - ASMRegisterHelper.GetEncodingBitLength(format.RegisterTypes[i])); regIncludeMasks.Add(ASMRegisterHelper.GetRegisterIncludeMask(format.RegisterTypes[i])); partialRegPositions.Add(null); partialRegIncludeMasks.Add(null); } currentChar++; } currentChar = (char)ASMStringHelper.CharOffsets.LowerLetter; for (int i = 0; i < format.NumImmeds; i++) { immedPositions.Add(InstructionBitLength - expFormat.IndexOf(currentChar) - format.ImmediateLengths[i]); immedIncludeMasks.Add(ASMValueHelper.GetIncludeMask(format.ImmediateLengths[i])); currentChar++; } format.RegisterPositions = regPositions; format.PartialRegisterPositions = partialRegPositions; format.ImmediatePositions = immedPositions; format.RegisterIncludeMasks = regIncludeMasks; format.PartialRegisterIncludeMasks = partialRegIncludeMasks; format.ImmediateIncludeMasks = immedIncludeMasks; return format; }
public void AddToDecodeLists(string expFormat, EncodingFormat encoding) { AddToOpcodeList(encoding.Opcode, encoding); if (Opcodes.IsSpecialOpcode(encoding.Opcode)) { AddToOpcodeFunctionList(encoding.Opcode, encoding.Function, encoding); } }
public void AddToOpcodeFunctionList(int opcode, int function, EncodingFormat encoding) { List<EncodingFormat>[] decodeList = null; if (DecodeOpcodeFunctionList[opcode] != null) { decodeList = DecodeOpcodeFunctionList[opcode]; } else { decodeList = new List<EncodingFormat>[Opcodes.NumPossibleFunctions]; } List<EncodingFormat> encFormatList = null; if (decodeList[function] != null) { encFormatList = decodeList[function]; encFormatList.Add(encoding); decodeList[function] = encFormatList; } else { encFormatList = new List<EncodingFormat>(); encFormatList.Add(encoding); decodeList[function] = encFormatList; } DecodeOpcodeFunctionList[opcode] = decodeList; }
public ASMFindLabelsResult FindLabels(string[] lines, EncodeLine[] encodeLines, uint pc) { ASMFindLabelsResult result = new ASMFindLabelsResult(); result.ErrorCode = 0; _errorTextBuilder.Length = 0; //LabelDict.Clear(); ClearLabelDict(); //int pc = ProcessPC(0, txt_StartPC.Text); int lineIndex = 0; int encodeLineIndex = 0; foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { continue; } string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line); processLine = ASMStringHelper.RemoveLeadingSpaces(processLine); processLine = ASMStringHelper.RemoveComment(processLine).ToLower(); string[] parts = ASMStringHelper.SplitLine(processLine); //pc = ASMPCHelper.ProcessOrg(pc, parts); ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts, false); pc = processPCResult.PC; _errorTextBuilder.Append(processPCResult.ErrorMessage); ASMAddLabelResult processLabelResult = ProcessLabelStatement(parts); if (processLabelResult != null) { if (processLabelResult.ErrorCode > 0) { result.ErrorCode = 1; _errorTextBuilder.Append(processLabelResult.ErrorMessage); } } EncodingFormat encodingOrNull = FormatHelper.FindFormatByCommand(parts[0]); if (encodingOrNull != null) { EncodeLine eLine = new EncodeLine(); if ((encodeLines.Length > 0) && (encodeLineIndex < encodeLines.Length)) { eLine = encodeLines[encodeLineIndex]; } while ((eLine.LineIndex == lineIndex) && (encodeLineIndex < encodeLines.Length)) { pc += 4; encodeLineIndex++; if (encodeLineIndex < encodeLines.Length) { eLine = encodeLines[encodeLineIndex]; } } lineIndex++; } else { ASMAddLabelResult addLabelResult = AddLabel(pc, parts); if (addLabelResult.ErrorCode == 0) { pc = addLabelResult.PC; } else { _errorTextBuilder.Append(addLabelResult.ErrorMessage); result.ErrorCode = 1; } } } result.ErrorMessage = _errorTextBuilder.ToString(); return(result); }
// For reading encoding files public void ReadEncodeList(string filepath) { StreamReader reader = new StreamReader(filepath); try { while (reader.Peek() != -1) { string line = reader.ReadLine(); if (!string.IsNullOrEmpty(line)) { line = ASMStringHelper.RemoveSpaces(line); string[] lineArray = line.Split(':'); EncodingFormat encoding = new EncodingFormat(); encoding.Command = lineArray[0].ToLower(); encoding.Binary = lineArray[1]; encoding.Syntax = lineArray[2]; if (lineArray.Length > 3) { encoding.ImmediateLengths = ASMStringHelper.CreateIntList(lineArray[3]); } if (lineArray.Length > 4) { encoding.VFPURegisterTypes = ASMStringHelper.CreateIntList(lineArray[4]); } if (lineArray.Length > 5) { encoding.PartialRegisterSizes = ASMStringHelper.CreateIntList(lineArray[5]); } if (lineArray.Length > 6) { encoding.ShiftedImmediateAmounts = ASMStringHelper.CreateIntList(lineArray[6]); } if (lineArray.Length > 7) { encoding.VFPUPrefixType = int.Parse(lineArray[7]); } encoding = FindFormatDetails(encoding); string expFormat = ExpandFormat(encoding); encoding.ExpandedFormat = expFormat; encoding = FindFormatBaseValues(encoding); encoding = FindParameterIndexes(encoding); EncodeList.Add(encoding); EncodeDict.Add(encoding.Command, encoding); AddToDecodeLists(expFormat, encoding); } } } catch (Exception ex) { } finally { reader.Close(); } }