Beispiel #1
0
        // 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);
        }
Beispiel #2
0
        public static ASMProcessEquivalencesResult ProcessEquivalences(string[] lines)
        {
            ASMProcessEquivalencesResult result = new ASMProcessEquivalencesResult();

            result.ErrorCode = 0;

            StringBuilder errorTextBuilder = new StringBuilder();

            Dictionary <string, string> eqvDict = new Dictionary <string, string>();

            ASMFindEquivalencesResult findEquivalencesResult = FindEquivalences(eqvDict, lines);

            if (findEquivalencesResult != null)
            {
                if (findEquivalencesResult.ErrorCode > 0)
                {
                    result.ErrorCode = 1;
                    errorTextBuilder.Append(findEquivalencesResult.ErrorMessage);
                }
            }

            List <string> newLines = new List <string>();

            foreach (string line in lines)
            {
                string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line);
                processLine = ASMStringHelper.RemoveLeadingSpaces(processLine);
                processLine = ASMStringHelper.RemoveComment(processLine).ToLower();
                string[] parts         = ASMStringHelper.SplitLine(processLine);
                bool     isEquivalence = ((!string.IsNullOrEmpty(parts[0])) && (parts[0].ToLower().Trim() == ".eqv"));

                string newLine = (string)line.Clone();

                if (!isEquivalence)
                {
                    foreach (KeyValuePair <string, string> eqv in eqvDict)
                    {
                        newLine = newLine.Replace(eqv.Key, eqv.Value);
                    }
                }

                newLines.Add(newLine);
            }

            result.ErrorMessage = errorTextBuilder.ToString();
            result.Lines        = newLines.ToArray();

            return(result);
        }
Beispiel #3
0
        public static string[] RemoveLabel(string[] parts)
        {
            // Remove label portion, if it exists
            if (!string.IsNullOrEmpty(parts[0]))
            {
                if (parts[0].EndsWith(":"))
                {
                    if (!string.IsNullOrEmpty(parts[1]))
                    {
                        string curLine = ASMStringHelper.RemoveLeadingSpaces(parts[1]);
                        curLine = ASMStringHelper.RemoveComment(curLine);
                        parts   = ASMStringHelper.SplitLine(curLine);
                    }
                }
            }

            return(parts);
        }
Beispiel #4
0
        public static uint ProcessStartPC(string asm, uint pc)
        {
            // If the ASM starts with a .org statement, use that address as the PC
            string[] lines = asm.Split('\n');
            lines = ASMStringHelper.RemoveFromLines(lines, "\r");

            foreach (string line in lines)
            {
                if (!string.IsNullOrEmpty(line))
                {
                    string             processLine     = ASMStringHelper.RemoveComment(line).ToLower();
                    string[]           parts           = ASMStringHelper.SplitLine(processLine);
                    ASMProcessPCResult processPCResult = ASMPCHelper.ProcessOrg(pc, parts);
                    pc = processPCResult.PC;
                    break;
                }
            }

            return(pc);
        }
Beispiel #5
0
        private static ASMFindEquivalencesResult FindEquivalences(Dictionary <string, string> eqvDict, string[] lines)
        {
            ASMFindEquivalencesResult result = new ASMFindEquivalencesResult();

            result.ErrorCode = 0;

            StringBuilder errorTextBuilder = new StringBuilder();

            ClearEquivalenceDict(eqvDict);

            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);

                ASMAddEquivalenceResult processEquivalenceResult = ProcessEquivalenceStatement(eqvDict, parts);
                if (processEquivalenceResult != null)
                {
                    if (processEquivalenceResult.ErrorCode > 0)
                    {
                        result.ErrorCode = 1;
                        errorTextBuilder.Append(processEquivalenceResult.ErrorMessage);
                    }
                }
            }

            result.ErrorMessage = errorTextBuilder.ToString();
            return(result);
        }
        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);
        }
Beispiel #7
0
        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()));
        }
Beispiel #8
0
        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
            });
        }
Beispiel #9
0
        // 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);
        }
        public static ASMProcessEquivalencesResult ProcessEquivalences(string[] lines)
        {
            ASMProcessEquivalencesResult result = new ASMProcessEquivalencesResult();

            result.ErrorCode = 0;

            StringBuilder errorTextBuilder = new StringBuilder();

            Dictionary <string, string> eqvMap = new Dictionary <string, string>();

            ASMFindEquivalencesResult findEquivalencesResult = FindEquivalences(eqvMap, lines);

            if (findEquivalencesResult != null)
            {
                if (findEquivalencesResult.ErrorCode > 0)
                {
                    result.ErrorCode = 1;
                    errorTextBuilder.Append(findEquivalencesResult.ErrorMessage);
                }
            }

            List <string> eqvKeys = new List <string>(eqvMap.Keys);

            eqvKeys.Sort((a, b) => a.Length.CompareTo(b.Length));
            eqvKeys.Reverse();

            List <string> newLines = new List <string>();

            foreach (string line in lines)
            {
                string processLine = ASMStringHelper.RemoveLeadingBracketBlock(line);
                processLine = ASMStringHelper.RemoveLeadingSpaces(processLine);
                processLine = ASMStringHelper.RemoveComment(processLine).ToLower();
                string[] parts         = ASMStringHelper.SplitLine(processLine);
                bool     isEquivalence = ((!string.IsNullOrEmpty(parts[0])) && (parts[0].ToLower().Trim() == ".eqv"));

                string newLine = (string)line.Clone();

                if (!isEquivalence)
                {
                    /*
                     * foreach (KeyValuePair<string, string> eqv in eqvDict)
                     * {
                     *  //newLine = newLine.Replace(eqv.Key, eqv.Value);
                     *  newLine = System.Text.RegularExpressions.Regex.Replace(newLine, System.Text.RegularExpressions.Regex.Escape(eqv.Key), eqv.Value.Replace("$", "$$"),
                     *      System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                     * }
                     */

                    foreach (string eqvKey in eqvKeys)
                    {
                        newLine = System.Text.RegularExpressions.Regex.Replace(newLine, System.Text.RegularExpressions.Regex.Escape(eqvKey), eqvMap[eqvKey].Replace("$", "$$"),
                                                                               System.Text.RegularExpressions.RegexOptions.IgnoreCase);
                    }
                }

                newLines.Add(newLine);
            }

            result.ErrorMessage = errorTextBuilder.ToString();
            result.Lines        = newLines.ToArray();

            return(result);
        }