private string DecodeDecrementedImmediate(int immedValue, int length) { //uint value = ASMValueHelper.BinaryToUnsigned(immedBinary) + 1; uint value = (uint)immedValue + 1; return("0x" + ASMValueHelper.UnsignedToHex_WithLength(value, length)); }
public ASMDecoderResult DecodeASM(IEnumerable <uint> uLines, uint pc, string spacePadding, bool includeAddress, bool useRegAliases, bool clearErrorText) { if (clearErrorText) { ClearErrorText(); } StringBuilder sb = new StringBuilder(); foreach (uint uLine in uLines) { string strAddress = "[0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8) + "] "; string strPrefix = (includeAddress ? strAddress : "") + spacePadding; try { string decodedLine = TryDecodeSingle(uLine, pc, useRegAliases); sb.Append(strPrefix); sb.Append(decodedLine); sb.Append("\r\n"); pc += 4; } catch (Exception ex) { _errorTextBuilder.AppendLine("FAILED TO DECODE LINE: " + uLine.ToString("{0:X8}") + " (" + ex.Message + ")"); } } return(new ASMDecoderResult(sb.ToString(), _errorTextBuilder.ToString())); }
public int DecodeASMToFile(string inputFilename, string outputFilename, bool littleEndian, bool useRegAliases, uint pc) { ClearErrorText(); BinaryReader reader = null; StreamWriter writer = null; try { reader = new BinaryReader(File.Open(inputFilename, FileMode.Open)); writer = new StreamWriter(outputFilename, false, Encoding.ASCII); } catch (Exception) { return(ASMFileDecoderResult.FileOpenError); } long length = reader.BaseStream.Length; int result = ASMFileDecoderResult.Success; try { int charPos = 0; while (charPos < length) { charPos += 4; uint line = reader.ReadUInt32(); if (!littleEndian) { line = ASMValueHelper.ReverseBytes(line); } string displayHex = ASMValueHelper.UnsignedToHex_WithLength(line, 8); string instruction = DecodeASMSingle(line, pc, useRegAliases); StringBuilder sb = new StringBuilder(); sb.Append(ASMValueHelper.UnsignedToHex_WithLength(pc, 8).ToLower()); sb.Append(": "); sb.Append(displayHex); sb.Append(" "); sb.Append(instruction); writer.WriteLine(sb.ToString()); pc += 4; } } catch { result = ASMFileDecoderResult.ASMDecodeError; } finally { reader.Close(); writer.Close(); } return(result); }
private string DecodeJumpImmediate(int immedValue, uint pc) { /* * string tempBinary = ASMValueHelper.UnsignedToBinary_WithLength(pc, 32).Substring(0,4); * string fullBinary = tempBinary + immedBinary + "00"; * string strValue = ASMValueHelper.BinaryToHex_WithLength(fullBinary, 8).ToLower(); * return "0x" + strValue; */ uint uValue = (uint)((pc & 0xF0000000) + (immedValue << 2)); return("0x" + ASMValueHelper.UnsignedToHex_WithLength(uValue, 8).ToLower()); }
public string ReplaceLabelsInHex(string hex, bool littleEndian) { string result = hex.ToUpper(); foreach (string label in LabelDict.Keys) { uint labelValue = LabelToUnsigned(label); labelValue = littleEndian ? ASMValueHelper.ReverseBytes(labelValue) : labelValue; string labelHex = ASMValueHelper.UnsignedToHex_WithLength(labelValue, 8).ToUpper(); result = result.Replace(label, labelHex); } return(result); }
private string DecodeSignedImmediate(int immedValue, int length) { //short immed = ASMValueHelper.BinaryToSignedShort(immedBinary); //short immed = (short)immedValue; //short immed = Convert.ToInt16((UInt16)immedValue); //short immed = BitConverter.ToInt16(BitConverter.GetBytes((ushort)immedValue), 0); ushort usValue = (ushort)immedValue; short immed = ASMValueHelper.UnsignedShortToSignedShort(usValue); uint uImmed = (uint)((immed < 0) ? (immed * -1) : immed); return(((immed < 0) ? "-0x" : "0x") + ASMValueHelper.UnsignedToHex_WithLength(uImmed, length).ToLower()); }
private string DecodeBranchImmediate(int immedValue, uint pc) { //short difference = ASMValueHelper.BinaryToSignedShort(immedBinary); //short difference = (short)immedValue; //short difference = Convert.ToInt16((UInt16)immedValue); ushort usValue = (ushort)immedValue; short difference = ASMValueHelper.UnsignedShortToSignedShort(usValue); //short difference = BitConverter.ToInt16(BitConverter.GetBytes(usValue), 0); uint immed = (uint)(difference * 4 + pc + 4); string strValue = ASMValueHelper.UnsignedToHex_WithLength(immed, 8).ToLower(); return("0x" + strValue); }
public ASMDecoderResult DecodeASM(string hex, uint pc, string spacePadding, bool littleEndian, bool includeAddress, bool useRegAliases, bool clearErrorText) { if (clearErrorText) { ClearErrorText(); } //string[] lines = hex.Split('\n'); //lines = ASMStringHelper.RemoveFromLines(lines, "\r"); string[] lines = ASMValueHelper.GetHexLines(hex); StringBuilder sb = new StringBuilder(); foreach (string line in lines) { if (string.IsNullOrEmpty(line)) { continue; } string strAddress = "[0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8) + "] "; string strPrefix = (includeAddress ? strAddress : "") + spacePadding; string modLine = line.Replace(" ", "").Replace("\t", ""); try { uint uLine = Convert.ToUInt32(modLine, 16); if (littleEndian) { uLine = ASMValueHelper.ReverseBytes(uLine); } string decodedLine = TryDecodeSingle(uLine, pc, useRegAliases); sb.Append(strPrefix); sb.Append(decodedLine); sb.Append("\r\n"); pc += 4; } catch (Exception ex) { _errorTextBuilder.AppendLine("FAILED TO DECODE LINE: " + line + " (" + ex.Message + ")"); } } return(new ASMDecoderResult(sb.ToString(), _errorTextBuilder.ToString())); }
public string ReplaceLabelsInHex(string hex, bool littleEndian, bool replaceAll = false) { string result = hex.ToUpper(); List <string> labels = new List <string>(LabelDict.Keys); labels.Sort((a, b) => a.Length.CompareTo(b.Length)); labels.Reverse(); foreach (string label in labels) { uint labelValue = LabelToUnsigned(label); labelValue = littleEndian ? ASMValueHelper.ReverseBytes(labelValue) : labelValue; string labelHex = ASMValueHelper.UnsignedToHex_WithLength(labelValue, 8).ToUpper(); result = result.Replace(label, labelHex); } if (replaceAll) { int persistentLabelIndex = result.IndexOf(PersistentLabelPrefix); HashSet <char> endChars = new HashSet <char>() { ' ', '\t', '\r', '\n' }; while (persistentLabelIndex != -1) { int endIndex = persistentLabelIndex; for (; endIndex < result.Length; endIndex++) { if (endChars.Contains(result[endIndex])) { break; } } string label = (endIndex < result.Length) ? result.Substring(persistentLabelIndex, endIndex - persistentLabelIndex) : result.Substring(persistentLabelIndex); result = result.Replace(label, "00000000"); persistentLabelIndex = result.IndexOf(PersistentLabelPrefix); } } return(result); }
// Immediate binary in the form (previous + current - 1) converted to current: (previous + current - 1) - previous + 1 = current private string DecodeModifiedImmediate(int immedValue, int prevImmedValue, int length) { //int result = (int)ASMValueHelper.BinaryToUnsigned(immedBinary) - (int)ASMValueHelper.BinaryToUnsigned(prevBinaryValue) + 1; int result = immedValue - prevImmedValue + 1; if (result < 0) { //_errorTextBuilder.Append("Negative modified immediate " + result.ToString() + " is invalid; Resulting hex is 0x" + hex); _illegalFlag = true; _illegalMessage = "Expected unsigned result for calculated value; negative result " + result.ToString() + " is invalid."; return("0"); } uint uResult = (uint)result; string hex = ASMValueHelper.UnsignedToHex_WithLength(uResult, length); return("0x" + hex); //return "0x" + ASMValueHelper.UnsignedToHex_WithLength(result, 4); }
public string ReplaceLabelsInHex(string hex, bool littleEndian) { string result = hex.ToUpper(); List <string> labels = new List <string>(LabelDict.Keys); labels.Sort((a, b) => a.Length.CompareTo(b.Length)); labels.Reverse(); foreach (string label in labels) { uint labelValue = LabelToUnsigned(label); labelValue = littleEndian ? ASMValueHelper.ReverseBytes(labelValue) : labelValue; string labelHex = ASMValueHelper.UnsignedToHex_WithLength(labelValue, 8).ToUpper(); result = result.Replace(label, labelHex); } return(result); }
public string LabelToHex(string label, int reqLength) { return(ASMValueHelper.UnsignedToHex_WithLength(LabelToUnsigned(label), reqLength)); }
public ASMCheckResult CheckASM(string[] lines, uint pc, bool littleEndian, bool useRegAliases, ICollection <ASMCheckCondition> conditions = null) { if (conditions == null) { conditions = standardCheckConditions; } bool isASM = (_errorTextBuilder.Length == 0); uint startPC = pc; string gprLoad = ""; int hiLoCountdown = 0; string hiLoCommand = ""; bool isLastCommandBranch = false; uint lastBranchAddress = 0; bool isLastCommandUnconditionalJump = false; bool isLastCommandUnconditionalJumpDelaySlot = false; foreach (string line in lines) { string[] parts = ASMStringHelper.SplitLine(line); if (parts.Length < 1) { continue; } string command = parts[0]; if (string.IsNullOrEmpty(command)) { continue; } string commandLower = command.ToLower().Trim(); bool isLoad = IsLoadCommand(command); bool isBranch = IsBranchCommand(command); bool isUnconditionalJump = IsUnconditionalJump(command); string strPC = "0x" + ASMValueHelper.UnsignedToHex_WithLength(pc, 8); string strArgs = parts[1]; if (!string.IsNullOrEmpty(strArgs)) { string[] args = strArgs.Split(','); if (conditions.Contains(ASMCheckCondition.LoadDelay)) { if (!isLastCommandUnconditionalJumpDelaySlot) { CheckLoadDelay(command, args, gprLoad, strPC); } } if (conditions.Contains(ASMCheckCondition.UnalignedOffset)) { int alignmentMultiple = GetAlignmentMultiple(command); if (alignmentMultiple > 1) { string strOffset = args[1].Substring(0, args[1].IndexOf("(")); uint offset = Encoder.ValueHelper.GetAnyUnsignedValue(strOffset); if ((offset % alignmentMultiple) != 0) { _errorTextBuilder.AppendLine("WARNING: Unaligned offset at address " + strPC); } } } if (conditions.Contains(ASMCheckCondition.MultCountdown)) { bool isMultiplication = ((commandLower == "mult") || (commandLower == "multu")); bool isDivision = ((commandLower == "div") || (commandLower == "divu")); if ((hiLoCountdown > 0) && ((isMultiplication) || (isDivision))) { string operation = isMultiplication ? "Multiplication" : "Division"; _errorTextBuilder.AppendLine("WARNING: " + operation + " within 2 commands of " + hiLoCommand + " at address " + strPC); } } if (isLoad) { gprLoad = args[0].Trim(); if (isLastCommandBranch) { if (conditions.Contains(ASMCheckCondition.LoadInBranchDelaySlot)) { _errorTextBuilder.AppendLine("WARNING: Load command in branch delay slot at address " + strPC); } // If there is a load in the branch delay slot, check if the branch target address tries to use the loaded value if (conditions.Contains(ASMCheckCondition.LoadDelay)) { uint endPC = startPC + ((uint)(lines.Length - 1) * 4); uint branchPC = lastBranchAddress; string strBranchPC = "0x" + ASMValueHelper.UnsignedToHex_WithLength(branchPC, 8); if ((startPC <= branchPC) && (branchPC <= endPC)) { int index = (int)((branchPC - startPC) / 4); string branchLine = lines[index]; string[] branchParts = ASMStringHelper.SplitLine(branchLine); if (branchParts.Length > 1) { string strBranchArgs = branchParts[1]; if (!string.IsNullOrEmpty(strBranchArgs)) { string[] branchArgs = strBranchArgs.Split(','); CheckLoadDelay(branchParts[0], branchArgs, gprLoad, strBranchPC); } } } } } } if (conditions.Contains(ASMCheckCondition.StackPointerOffset)) { if (IsAddImmediateCommand(command)) { string stackPointerRegName = Encoder.RegHelper.GetGPRegisterName(29, useRegAliases).ToLower().Trim(); if ((args[0].ToLower().Trim() == stackPointerRegName) && (args[1].ToLower().Trim() == stackPointerRegName)) { uint immed = Encoder.ValueHelper.GetAnyUnsignedValue(args[2].ToLower().Trim()); if (immed % 8 != 0) { _errorTextBuilder.AppendLine("WARNING: Stack pointer offset not a multiple of 8 at address " + strPC); } } } } if (isBranch) { lastBranchAddress = FindBranchTargetAddress(args); } } // Check if we're jumping into a hazard if (isLastCommandBranch) { uint endPC = startPC + ((uint)(lines.Length - 1) * 4); uint branchPC = lastBranchAddress; string strBranchPC = "0x" + ASMValueHelper.UnsignedToHex_WithLength(branchPC, 8); if ((startPC <= branchPC) && (branchPC <= endPC)) { int index = (int)((branchPC - startPC) / 4); string branchLine = lines[index]; string[] branchParts = ASMStringHelper.SplitLine(branchLine); if (branchParts.Length > 1) { string strCommand = branchParts[0]; string strBranchArgs = branchParts[1]; if (!string.IsNullOrEmpty(strBranchArgs)) { string[] branchArgs = strBranchArgs.Split(','); if (conditions.Contains(ASMCheckCondition.LoadDelay)) { if ((IsLoadCommand(strCommand)) && ((branchPC + 4) <= endPC)) { string secondBranchLine = lines[index + 1]; string[] secondBranchParts = ASMStringHelper.SplitLine(secondBranchLine); if (secondBranchParts.Length > 1) { string strSecondBranchArgs = secondBranchParts[1]; if (!string.IsNullOrEmpty(strSecondBranchArgs)) { string[] secondBranchArgs = strSecondBranchArgs.Split(','); string strSecondBranchPC = "0x" + ASMValueHelper.UnsignedToHex_WithLength(branchPC + 4, 8); string branchGprLoad = branchArgs[0].Trim(); CheckLoadDelay(secondBranchParts[0], secondBranchArgs, branchGprLoad, strSecondBranchPC); } } } } if (conditions.Contains(ASMCheckCondition.MultCountdown)) { string strCommandLower = strCommand.ToLower(); if ((strCommandLower == "mfhi") || (strCommandLower == "mflo")) { if (((branchPC + 4) <= endPC)) { string nextBranchLine = lines[index + 1]; string[] nextBranchParts = ASMStringHelper.SplitLine(nextBranchLine); if (nextBranchParts.Length > 0) { string nextBranchCommand = nextBranchParts[0].ToLower(); bool isMultiplication = ((nextBranchCommand == "mult") || (nextBranchCommand == "multu")); bool isDivision = ((nextBranchCommand == "div") || (nextBranchCommand == "divu")); if ((isMultiplication) || (isDivision)) { string operation = isMultiplication ? "Multiplication" : "Division"; string strNextPC = "0x" + ASMValueHelper.UnsignedToHex_WithLength(branchPC + 4, 8); _errorTextBuilder.AppendLine("WARNING: " + operation + " within 2 commands of " + strCommandLower + " at address " + strNextPC); } } } if (((branchPC + 8) <= endPC)) { string nextBranchLine = lines[index + 2]; string[] nextBranchParts = ASMStringHelper.SplitLine(nextBranchLine); if (nextBranchParts.Length > 0) { string nextBranchCommand = nextBranchParts[0].ToLower(); bool isMultiplication = ((nextBranchCommand == "mult") || (nextBranchCommand == "multu")); bool isDivision = ((nextBranchCommand == "div") || (nextBranchCommand == "divu")); if ((isMultiplication) || (isDivision)) { string operation = isMultiplication ? "Multiplication" : "Division"; string strNextPC = "0x" + ASMValueHelper.UnsignedToHex_WithLength(branchPC + 8, 8); _errorTextBuilder.AppendLine("WARNING: " + operation + " within 2 commands of " + strCommandLower + " at address " + strNextPC); } } } } } } } } } if (conditions.Contains(ASMCheckCondition.BranchInBranchDelaySlot)) { if (isBranch && isLastCommandBranch) { _errorTextBuilder.AppendLine("WARNING: Branch command in branch delay slot at address " + strPC); } } if (!isLoad) { gprLoad = ""; } if (isLastCommandUnconditionalJump) { hiLoCountdown = 0; } else if ((commandLower == "mfhi") || (commandLower == "mflo")) { hiLoCountdown = 2; hiLoCommand = commandLower; } else if (hiLoCountdown > 0) { hiLoCountdown--; } isLastCommandBranch = isBranch; isLastCommandUnconditionalJumpDelaySlot = isLastCommandUnconditionalJump; isLastCommandUnconditionalJump = isUnconditionalJump; pc += 4; } return(new ASMCheckResult { ErrorText = _errorTextBuilder.ToString(), IsASM = isASM }); }
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())); }
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)); }
private string DecodeUnsignedImmediate(int immedValue, int length) { uint uValue = (uint)immedValue; return("0x" + ASMValueHelper.UnsignedToHex_WithLength(uValue, length).ToLower()); }
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 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); }