/// <summary>
        /// Searches for J, JAL, and HI16/LO16 pairs. When it finds these and their values will be zeroed out.
        /// This is to facilitate searching of function signatures. <para/>
        /// This method buffers its input.
        /// </summary>
        /// <param name="insns"></param>
        /// <returns></returns>
        public static IReadOnlyList <InstructionWithPc> ZeroRelocatedValues(this IEnumerable <InstructionWithPc> insns)
        {
            var analyzer = new Analyzer();
            var lastInsn = new Dictionary <int, Instruction>();

            var input     = insns.ToArray();
            var haveHi16  = new bool[32];
            var hi16Index = new int[32];

            Action pendingAction = null;


            for (var i = 0; i < input.Length; i++)
            {
                var insn     = input[i].Instruction;
                var action   = pendingAction;
                var insnId   = insn.Id;
                var analysis = analyzer.Analyze(insn);

                var processedId = insn.IsLoadStore ? MipsInstruction.ADDIU : insnId;

                switch (processedId)
                {
                case MipsInstruction.JAL:
                    //pendingAction = reset;
                    goto J;

                // Fallthrough
                case MipsInstruction.J:
J:
                    insn.Target = 0;
                    break;

                case MipsInstruction.LUI:
                    haveHi16[insn.GprRt]  = true;
                    hi16Index[insn.GprRt] = i;
                    break;

                // Case for LO16 relos, ADDIU and load/store ops
                case MipsInstruction.ADDIU:
                    if (haveHi16[insn.GprRs])
                    {
                        var tmp = input[hi16Index[insn.GprRs]].Instruction;
                        tmp.Immediate = 0;
                        input[hi16Index[insn.GprRs]] = new InstructionWithPc(input[hi16Index[insn.GprRs]].Pc, tmp);
                        insn.Immediate = 0;
                    }

                    haveHi16[insn.GprRs]  = false;
                    hi16Index[insn.GprRs] = 0;

                    break;

                default:
                    if (analysis != null && analysis.DestinationGpr.HasValue)
                    {
                        haveHi16[analysis.DestinationGpr.Value] = false;
                    }

                    break;
                }

                input[i] = new InstructionWithPc(input[i].Pc, insn);

                action?.Invoke();
            }

            return(input);
        }
 void IDiscoveredFunction.AddInstruction(InstructionWithPc iwp) =>
 _instructions.Add(iwp);