示例#1
0
 public uint match;			/* what to match after masking */
 public opcode_handler_struct(opcode opcode_handler, uint bits, uint mask, uint match)
 {
     this.opcode_handler = opcode_handler;
     this.bits = bits;
     this.mask = mask;
     this.match = match;
 }
示例#2
0
 private static void ConsoleHelpText()
 {
     Console.WriteLine("Assemble folder or disassemble file for Smash 4 AI. Usage:");
     Console.WriteLine("\t>no args: open the GUI");
     foreach (int opValue in Enum.GetValues(typeof(opcode)))
     {
         opcode op = (opcode)opValue;
         Console.Write("\t>");
         Console.ForegroundColor = ConsoleColor.Green;
         Console.Write(Enum.GetName(typeof(opcode), opValue));
         Console.ResetColor();
         Console.WriteLine(": " + descriptions[op]);
     }
 }
示例#3
0
 foreach (var(opcode, a, b, c) in program)
示例#4
0
 public s_opcode(uint cycles, opcode function) { this.cycles = cycles; this.function = function; }
示例#5
0
文件: CPU.cs 项目: saulohdc89/CPU-SIm
        public bool Step()
        {
            opcode currentInstruction = Decode(read(_PC));

            _PC = (byte)(_PC + 1);

            instructionCount += 1;


            switch (currentInstruction)
            {
            case opcode.NOP:
                break;

            case opcode.STA:
                write(read(_PC), _AC);
                _PC = (byte)(_PC + 1);
                break;

            case opcode.LDA:
                _AC = read(read(_PC));
                _PC = (byte)(_PC + 1);
                break;

            case opcode.ADD:
                //       byte[] conv = new byte[2];
                //    conv[0] = _AC;
                //    conv[1] = read(read(_PC));
                // short data = BitConverter.ToInt16(conv,0);

                //byte g =_AC;
                //sbyte q =(read(read(_PC));
                //sbyte t = (sbyte)(g + q);
                // if (t < 0)
                int resultADD = _AC + read(read(_PC));
                _AC = (byte)(resultADD & 0xFF);
                _PC = (byte)(_PC + 1);
                updateFLAGS();
                break;

            case opcode.OR:
                int resultOR = (_AC | read(read(_PC)));
                _AC = (byte)resultOR;
                _PC = (byte)(_PC + 1);
                updateFLAGS();
                break;

            case opcode.AND:
                int resultAND = (_AC & read(read(_PC)));
                _AC = (byte)resultAND;
                _PC = (byte)(_PC + 1);
                updateFLAGS();
                break;

            case opcode.NOT:
                int resultNOT = ~(_AC);
                _AC = (byte)resultNOT;
                updateFLAGS();
                break;

            case opcode.JMP:
                _PC = (byte)(read(_PC));
                break;

            case opcode.JN:
                if (_N == true)
                {
                    _PC = read(_PC);
                }
                else
                {
                    read(_PC);
                    _PC = (byte)(_PC + 1);
                }
                break;

            case opcode.JZ:
                if (_Z == true)
                {
                    _PC = read(_PC);
                }
                else
                {
                    read(_PC);
                    _PC = (byte)(_PC + 1);
                }
                break;

            case opcode.HLT:
                return(false);

            case opcode.INVALID:
                break;
            }
            if (_PC >= 255)
            {
                //  _PC = 0;
                return(false);
            }
            return(true);
        }
示例#6
0
 => this.Update(opcode, low, high);
示例#7
0
 set => RegisterInstruction(opcode, value);
     : super(opcode) {
 }
     : super(opcode) {
     this.type = type;
 }
     : super(opcode) {
     this.method = method;
 }
     : super(opcode) {
     this.field = field;
 }
     : super(opcode) {
     this.labelMarker = labelMarker;
 }
     : super(opcode) {
     this.intOperand = intOperand;
 }
     : super(opcode) {
     this.localVariable = localVariable;
 }
示例#15
0
        private static void ConsoleMain(string[] args)
        {
            //project handling variables
            AITree tree = null;

            string[] fighters    = new string[0];
            bool     allFighters = true;

            AITree.AIType[] types    = new AITree.AIType[0];
            bool            allTypes = true;

            try
            {
                for (int i = 0; i < args.Length; i++)
                {
                    opcode op           = (opcode)Enum.Parse(typeof(opcode), args[i].TrimStart('-'));
                    string notOpenMsg   = "ERROR: project must be open for opcode " + args[i];
                    string notClosedMsg = "ERROR: project must be closed for opcode " + args[i];
                    switch (op)
                    {
                    case opcode.h:
                        ConsoleHelpText();
                        break;

                    case opcode.wp:
                        if (tree != null)
                        {
                            throw new Exception(notClosedMsg);
                        }
                        util.workDir = args[++i];
                        if (!Directory.Exists(util.workDir))
                        {
                            Directory.CreateDirectory(util.workDir);
                        }
                        break;

                    case opcode.cp:
                        util.compDir = args[++i];
                        if (!Directory.Exists(util.compDir))
                        {
                            Directory.CreateDirectory(util.compDir);
                        }
                        break;

                    case opcode.gp:
                        util.gameFtDir = args[++i];
                        break;

                    case opcode.fl:
                        i++;
                        if (args[i] == "all")
                        {
                            allFighters = true;
                            break;
                        }
                        allFighters = false;
                        fighters    = args[i].Split(',');
                        break;

                    case opcode.tl:
                    {
                        i++;
                        if (args[i] == "all")
                        {
                            allTypes = true;
                            break;
                        }
                        allTypes = false;
                        string[]             strTypes = args[i].Split(',');
                        List <AITree.AIType> typeList = new List <AITree.AIType>();
                        for (int j = 0; j < strTypes.Length; j++)
                        {
                            AITree.AIType newType = AITree.StringToAIType[strTypes[j]];
                            if (!typeList.Contains(newType))
                            {
                                typeList.Add(newType);
                            }
                        }
                        types = typeList.ToArray();
                        break;
                    }

                    case opcode.d:
                        aism.DisassembleFile(args[++i], util.workDir);
                        break;

                    case opcode.a:
                        aism.AssembleFolder(args[++i], util.compDir);
                        break;

                    case opcode.po:
                        if (tree != null)
                        {
                            throw new Exception(notClosedMsg);
                        }
                        tree = new AITree();
                        tree.InitOpenProject();
                        break;

                    case opcode.pn:
                    {
                        if (tree != null)
                        {
                            throw new Exception(notClosedMsg);
                        }
                        tree = new AITree();
                        string[]        loc_fighters = fighters;
                        AITree.AIType[] loc_types    = types;
                        if (allFighters)
                        {
                            List <string> fighterNames = new List <string>();
                            foreach (string dir in Directory.EnumerateDirectories(util.gameFtDir))
                            {
                                fighterNames.Add(util.GetFolderName(dir));
                            }
                            loc_fighters = fighterNames.ToArray();
                        }
                        if (allTypes)
                        {
                            loc_types = new AITree.AIType[]
                            {
                                AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script
                            }
                        }
                        ;
                        tree.InitNewProject(loc_fighters, loc_types);
                        break;
                    }

                    case opcode.pac:
                    {
                        if (tree == null)
                        {
                            throw new Exception(notOpenMsg);
                        }
                        string[]        loc_fighters = fighters;
                        AITree.AIType[] loc_types    = types;
                        if (allFighters)
                        {
                            List <string> fighterNames = new List <string>();
                            foreach (string dir in Directory.EnumerateDirectories(util.compDir))
                            {
                                fighterNames.Add(util.GetFolderName(dir));
                            }
                            loc_fighters = fighterNames.ToArray();
                        }
                        if (allTypes)
                        {
                            loc_types = new AITree.AIType[]
                            {
                                AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script
                            }
                        }
                        ;
                        tree.AddProjectFiles(loc_fighters, loc_types, AITree.AISource.compiled);
                        break;
                    }

                    case opcode.pag:
                    {
                        if (tree == null)
                        {
                            throw new Exception(notOpenMsg);
                        }
                        string[]        loc_fighters = fighters;
                        AITree.AIType[] loc_types    = types;
                        if (allFighters)
                        {
                            List <string> fighterNames = new List <string>();
                            foreach (string dir in Directory.EnumerateDirectories(util.gameFtDir))
                            {
                                fighterNames.Add(util.GetFolderName(dir));
                            }
                            loc_fighters = fighterNames.ToArray();
                        }
                        if (allTypes)
                        {
                            loc_types = new AITree.AIType[]
                            {
                                AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script
                            }
                        }
                        ;
                        tree.AddProjectFiles(loc_fighters, loc_types, AITree.AISource.game_file);
                        break;
                    }

                    case opcode.pcm:
                    {
                        if (tree == null)
                        {
                            throw new Exception(notOpenMsg);
                        }
                        string[]        loc_fighters = fighters;
                        AITree.AIType[] loc_types    = types;
                        if (allFighters)
                        {
                            List <string> fighterNames = new List <string>();
                            foreach (string dir in Directory.EnumerateDirectories(util.workDir))
                            {
                                fighterNames.Add(util.GetFolderName(dir));
                            }
                            loc_fighters = fighterNames.ToArray();
                        }
                        if (allTypes)
                        {
                            loc_types = new AITree.AIType[]
                            {
                                AITree.AIType.attack_data, AITree.AIType.param, AITree.AIType.param_nfp, AITree.AIType.script
                            }
                        }
                        ;

                        foreach (var ft in loc_fighters)
                        {
                            foreach (var type in loc_types)
                            {
                                string pathIn = AITree.GetFolderPath(ft, type, AITree.AISource.work);
                                if (Directory.Exists(pathIn))
                                {
                                    string pathOut = AITree.GetFolderPath(ft, type, AITree.AISource.compiled);
                                    aism.AssembleFolder(pathIn, pathOut);
                                }
                            }
                        }
                        break;
                    }

                    case opcode.pcl:
                        if (tree == null)
                        {
                            throw new Exception(notOpenMsg);
                        }
                        tree = null;
                        break;

                    case opcode.pd:
                        Console.WriteLine("workspace: " + util.workDir);
                        Console.WriteLine("compile: " + util.compDir);
                        Console.WriteLine("game: " + util.gameFtDir);
                        break;

                    case opcode.pt:
                    {
                        if (tree == null)
                        {
                            throw new Exception(notOpenMsg);
                        }
                        foreach (var ft in tree.fighters)
                        {
                            Console.Write(ft.name + ": {");
                            int count = ft.files.Count;
                            for (int j = 0; j < count; j++)
                            {
                                Console.Write(AITree.AITypeToString[ft.files[j].type]);
                                if (j < count - 1)
                                {
                                    Console.Write(", ");
                                }
                            }
                            Console.WriteLine("}");
                        }
                        break;
                    }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(helpReminder);
            }
        }
示例#16
0
 void m68k_set_instr_hook_callback(opcode callback)
 {
     m68k_cpu.instr_hook_callback = callback != null ? callback : default_instr_hook_callback;
 }
示例#17
0
        public override line GetNextLine(ByteProvider bp)
        {
            x86_64_line l  = new x86_64_line();
            List <byte> os = new List <byte>();

            l.offset_start = bp.Offset;

            byte rex           = 0x0;
            bool has_prefix_66 = false;
            bool has_prefix_f2 = false;
            bool has_prefix_f3 = false;
            byte b             = bp.GetNextByte();

            os.Add(b);

            // read any prefixes
            bool         reading_prefixes = true;
            List <ulong> prefixes         = new List <ulong>();

            while (reading_prefixes)
            {
                switch (b)
                {
                case 0xf2:
                case 0x66:
                case 0xf3:
                    if (b == 0xf2)
                    {
                        has_prefix_f2 = true;
                    }
                    if (b == 0xf3)
                    {
                        has_prefix_f3 = true;
                    }
                    if (b == 0x66)
                    {
                        has_prefix_66 = true;
                    }
                    b = bp.GetNextByte();
                    os.Add(b);
                    break;

                case 0xf0:
                case 0x2e:
                case 0x36:
                case 0x3e:
                case 0x26:
                case 0x64:
                case 0x65:
                case 0x67:
                    prefixes.Add(b);
                    b = bp.GetNextByte();
                    os.Add(b);
                    break;

                default:
                    reading_prefixes = false;
                    break;
                }
            }
            l.prefixes = prefixes.ToArray();

            // read any rex prefix
            if ((b >= 0x40) && (b <= 0x4f))
            {
                prefixes.Add(b);
                l.prefixes = prefixes.ToArray();
                rex        = b;
                b          = bp.GetNextByte();
                os.Add(b);
            }

            // read the opcode
            if (b == 0x0f)
            {
                // two byte opcode

                /* read any rex prefix (in multi-byte opcodes, the rex
                 * prefix comes after the 0x0f byte)
                 */
                byte b2 = bp.GetNextByte();
                os.Add(b2);
                if ((b2 >= 0x40) && (b2 <= 0x4f))
                {
                    prefixes.Add(b2);
                    l.prefixes = prefixes.ToArray();
                    rex        = b;
                    b2         = bp.GetNextByte();
                    os.Add(b2);
                }

                if ((b2 == 0x38) || (b2 == 0x3a))
                {
                    byte b3 = bp.GetNextByte();
                    os.Add(b3);
                    l.opcode = (ulong)((b << 16) + (b2 << 8) + b3);
                }
                else if (has_prefix_f2)
                {
                    l.opcode = (ulong)((0xf2 << 16) + (b << 8) + b2);
                }
                else if (has_prefix_f3)
                {
                    l.opcode = (ulong)((0xf3 << 16) + (b << 8) + b2);
                }
                else if (has_prefix_66)
                {
                    l.opcode = (ulong)((0x66 << 16) + (b << 8) + b2);
                }
                else
                {
                    l.opcode = (ulong)((b << 8) + b2);
                }
            }
            else
            {
                if (has_prefix_f2)
                {
                    prefixes.Add(0xf2);
                }
                if (has_prefix_f3)
                {
                    prefixes.Add(0xf3);
                }
                if (has_prefix_66)
                {
                    prefixes.Add(0x66);
                }
                l.opcode = (ulong)b;
            }

            opcode o = null;

            if (opcodes.ContainsKey(l.opcode))
            {
                o = opcodes[l.opcode];
            }

            if (o == null)
            {
                l.offset_end = bp.Offset;
                return(l);
            }
            else
            {
                byte  modrm;
                byte  sib  = 0;
                long  disp = 0;
                ulong imm  = 0;

                if (o.has_rm)
                {
                    // read the rm byte
                    modrm = bp.GetNextByte();
                    os.Add(modrm);

                    byte mod = (byte)(modrm >> 6);
                    byte rm  = (byte)(modrm & 7);
                    byte reg = (byte)((modrm >> 3) & 7);

                    if (o.reinterpret_after_r)
                    {
                        l.opcode = (((ulong)reg) << 24) + l.opcode + 0x10000000;
                        if (opcodes.ContainsKey(l.opcode))
                        {
                            o = opcodes[l.opcode];
                        }
                        else
                        {
                            l.offset_end = bp.Offset;
                            return(l);
                        }
                    }

                    // decide if we need an sib byte
                    if ((mod != 3) && (rm == 4))
                    {
                        sib = bp.GetNextByte();
                        os.Add(sib);
                    }

                    // decide if we need a displacement
                    if (((mod == 0) && (rm == 5)) || (mod == 2))
                    {
                        // 4 byte displacement
                        byte d1 = bp.GetNextByte();
                        os.Add(d1);
                        byte d2 = bp.GetNextByte();
                        os.Add(d2);
                        byte d3 = bp.GetNextByte();
                        os.Add(d3);
                        byte d4 = bp.GetNextByte();
                        os.Add(d4);

                        byte[] dval = new byte[] { d1, d2, d3, d4 };
                        disp = BitConverter.ToInt32(dval, 0);

                        //disp = (ulong)d1 + (((ulong)d2) << 8) + (((ulong)d3) << 16) + (((ulong)d4) << 24);
                    }
                    else if (mod == 1)
                    {
                        // 1 byte displacement
                        byte d1 = bp.GetNextByte();
                        os.Add(d1);

                        byte extend = 0;
                        if ((d1 & 0x80) == 0x80)
                        {
                            extend = 0xff;
                        }

                        byte[] dval = new byte[] { d1, extend, extend, extend };
                        disp = BitConverter.ToInt32(dval, 0);
                    }

                    // load a immediate value if necessary
                    int imm_length = o.immediate_length;
                    if ((imm_length == 4) && (o.immediate_extends_on_rexw) && ((rex & 0x08) == 0x08))
                    {
                        imm_length = 8;
                    }
                    for (int i = 0; i < imm_length; i++)
                    {
                        byte cur_b = bp.GetNextByte();
                        os.Add(cur_b);
                        imm += ((ulong)cur_b) << (i * 8);
                    }

                    // work out the opcodes
                    List <location> args = new List <location>();
                    foreach (opcode.operand_source osrc in o.operand_sources)
                    {
                        switch (osrc.type)
                        {
                        case opcode.operand_source.src_type.Fixed:
                            if (osrc.Fixed_Location.type == location.location_type.Register)
                            {
                                ulong reg_no = osrc.Fixed_Location.reg_no;
                                reg_no = reg_no % 8;

                                if (osrc.extends_on_rexb && ((rex & 0x01) == 0x01))
                                {
                                    reg_no += reg_nos["r8"];
                                }
                                else if ((rex & 0x08) == 0x08)
                                {
                                    reg_no += reg_nos["rax"];
                                }
                                else
                                {
                                    reg_no = osrc.Fixed_Location.reg_no;
                                }
                                args.Add(new location {
                                    type = location.location_type.Register, reg_no = reg_no
                                });
                            }
                            else
                            {
                                args.Add(osrc.Fixed_Location);
                            }
                            break;

                        case opcode.operand_source.src_type.Imm:
                            args.Add(new location {
                                type = location.location_type.Immediate, immediate = imm, is_pc_relative = osrc.is_pc_relative
                            });
                            break;

                        case opcode.operand_source.src_type.ModRM_Reg:
                        {
                            ulong base_reg = 0;
                            switch (osrc.length)
                            {
                            case opcode.operand_source.reg_length.r8:
                                base_reg = reg_nos["al"];
                                break;

                            case opcode.operand_source.reg_length.r16:
                                base_reg = reg_nos["ax"];

                                break;

                            case opcode.operand_source.reg_length.r32:
                                base_reg = reg_nos["eax"];
                                if (has_prefix_66)
                                {
                                    base_reg = reg_nos["ax"];
                                }
                                else
                                {
                                    if (((rex & rex_w) == rex_w) && osrc.extends_on_rexw)
                                    {
                                        base_reg = reg_nos["rax"];
                                    }
                                    if ((rex & 0x4) == 0x4)
                                    {
                                        base_reg = reg_nos["r8"];
                                    }
                                }
                                break;

                            case opcode.operand_source.reg_length.r64:
                                base_reg = reg_nos["rax"];
                                if ((rex & 0x4) == 0x4)
                                {
                                    base_reg = reg_nos["r8"];
                                }
                                break;

                            case opcode.operand_source.reg_length.mm:
                                base_reg = reg_nos["mm0"];
                                break;

                            case opcode.operand_source.reg_length.xmm:
                                base_reg = reg_nos["xmm0"];
                                if ((rex & 0x4) == 0x4)
                                {
                                    base_reg = reg_nos["xmm8"];
                                }
                                break;

                            case opcode.operand_source.reg_length.cr:
                                base_reg = reg_nos["cr0"];
                                break;
                            }

                            args.Add(new location {
                                    type = location.location_type.Register, reg_no = base_reg + (ulong)reg
                                });
                        }
                        break;

                        case opcode.operand_source.src_type.ModRM_RM:
                        {
                            if (mod == 3)
                            {
                                ulong base_reg = 0;

                                switch (osrc.length)
                                {
                                case opcode.operand_source.reg_length.r8:
                                    base_reg = reg_nos["al"];
                                    break;

                                case opcode.operand_source.reg_length.r16:
                                    base_reg = reg_nos["ax"];

                                    break;

                                case opcode.operand_source.reg_length.r32:
                                    base_reg = reg_nos["eax"];
                                    if (has_prefix_66)
                                    {
                                        base_reg = reg_nos["ax"];
                                    }
                                    else
                                    {
                                        if (((rex & rex_w) == rex_w) && osrc.extends_on_rexw)
                                        {
                                            base_reg = reg_nos["rax"];
                                        }
                                        if ((rex & 0x1) == 0x1)
                                        {
                                            base_reg = reg_nos["r8"];
                                        }
                                    }
                                    break;

                                case opcode.operand_source.reg_length.r64:
                                    base_reg = reg_nos["rax"];
                                    if ((rex & 0x1) == 0x1)
                                    {
                                        base_reg = reg_nos["r8"];
                                    }
                                    break;

                                case opcode.operand_source.reg_length.mm:
                                    base_reg = reg_nos["mm0"];
                                    break;

                                case opcode.operand_source.reg_length.xmm:
                                    base_reg = reg_nos["xmm0"];
                                    if ((rex & 0x1) == 0x1)
                                    {
                                        base_reg = reg_nos["xmm8"];
                                    }
                                    break;

                                case opcode.operand_source.reg_length.cr:
                                    base_reg = reg_nos["cr0"];
                                    break;
                                }

                                args.Add(new location {
                                        type = location.location_type.Register, reg_no = base_reg + (ulong)rm
                                    });
                            }
                            else
                            {
                                ulong base_reg = reg_nos["rax"];

                                switch (rm)
                                {
                                case 0:
                                    base_reg = reg_nos["rax"];
                                    break;

                                case 1:
                                    base_reg = reg_nos["rcx"];
                                    break;

                                case 2:
                                    base_reg = reg_nos["rdx"];
                                    break;

                                case 3:
                                    base_reg = reg_nos["rbx"];
                                    break;

                                case 4:
                                {
                                    // interpret sib byte
                                    byte s_scale = (byte)(sib >> 6);
                                    byte s_base  = (byte)(sib & 7);
                                    byte s_index = (byte)((sib >> 3) & 7);

                                    List <location> sib_args  = new List <location>();
                                    bool            need_plus = false;

                                    // the special combination of base = 5, mod = 0, rex_b = 0 means no base
                                    if (!((s_base == 5) && (mod == 0) && ((rex & rex_b) == rex_b)))
                                    {
                                        // otherwise we have a base
                                        ulong s_base_base_reg = reg_nos["rax"];
                                        if ((rex & rex_b) == rex_b)
                                        {
                                            s_base_base_reg = reg_nos["r8"];
                                        }

                                        need_plus = true;
                                        sib_args.Add(new location {
                                                    type = location.location_type.Register, reg_no = s_base_base_reg + s_base
                                                });
                                    }

                                    // if s_index != 4, then we have a index register
                                    if (!((s_index == 4) && ((rex & rex_x) != rex_x)))
                                    {
                                        location.scale_func scale = location.scale_func.None;
                                        if (need_plus)
                                        {
                                            scale = location.scale_func.Plus;
                                        }

                                        ulong s_index_base_reg = reg_nos["rax"];
                                        if ((rex & rex_x) == rex_x)
                                        {
                                            s_index_base_reg = reg_nos["r8"];
                                        }

                                        need_plus = true;
                                        sib_args.Add(new location {
                                                    type = location.location_type.Register, reg_no = s_index_base_reg + s_index, scale = scale
                                                });

                                        if (s_scale == 1)
                                        {
                                            sib_args.Add(new location {
                                                        type = location.location_type.Const, immediate = 2, scale = location.scale_func.Multiply
                                                    });
                                        }
                                        else if (s_scale == 2)
                                        {
                                            sib_args.Add(new location {
                                                        type = location.location_type.Const, immediate = 4, scale = location.scale_func.Multiply
                                                    });
                                        }
                                        else if (s_scale == 3)
                                        {
                                            sib_args.Add(new location {
                                                        type = location.location_type.Const, immediate = 8, scale = location.scale_func.Multiply
                                                    });
                                        }
                                    }

                                    if ((mod == 1) || (mod == 2) || ((mod == 0) && (s_base == 5) && ((rex & rex_b) == rex_b)))
                                    {
                                        // add displacement
                                        location.scale_func scale = location.scale_func.None;
                                        if (need_plus)
                                        {
                                            scale = ((disp >= 0) ? location.scale_func.Plus : location.scale_func.Minus);
                                        }

                                        sib_args.Add(new location {
                                                    type = location.location_type.Immediate, immediate = ((disp >= 0) ? (ulong)disp : (ulong)(-disp)), scale = scale
                                                });
                                    }

                                    args.Add(new location {
                                                type = location.location_type.ContentsOf, args = sib_args.ToArray()
                                            });
                                    continue;
                                }

                                case 5:
                                {
                                    if (mod == 0)
                                    {
                                        args.Add(new location {
                                                    type = location.location_type.ContentsOf, args = new location[] { new location {
                                                                                                                          type = location.location_type.Register, reg_no = reg_nos["rip"]
                                                                                                                      }, new location {
                                                                                                                          type = location.location_type.Immediate, scale = ((disp >= 0) ? location.scale_func.Plus : location.scale_func.Minus), immediate = ((disp >= 0) ? (ulong)disp : (ulong)(-disp))
                                                                                                                      } }
                                                });
                                        continue;
                                    }
                                    else
                                    {
                                        base_reg = reg_nos["rbp"];
                                    }
                                }
                                break;

                                case 6:
                                    base_reg = reg_nos["rsi"];
                                    break;

                                case 7:
                                    base_reg = reg_nos["rdi"];
                                    break;
                                }
                                if ((rex & 0x1) == 0x1)
                                {
                                    base_reg = base_reg - reg_nos["rax"] + reg_nos["r8"];
                                }

                                location loc = new location {
                                    type = location.location_type.ContentsOf, args = new location[] { new location {
                                                                                                          type = location.location_type.Register, reg_no = base_reg
                                                                                                      } }
                                };
                                if ((mod == 1) || (mod == 2))
                                {
                                    loc.args = new location[] { loc.args[0], new location {
                                                                    type = location.location_type.Immediate, scale = ((disp >= 0) ? location.scale_func.Plus : location.scale_func.Minus), immediate = ((disp >= 0) ? (ulong)disp : (ulong)(-disp))
                                                                } }
                                }
                                ;
                                args.Add(loc);
                            }
                        }
                        break;
                        }
                    }
                    l.arguments = args.ToArray();
                }
                else
                {
                    // no mod_rm

                    // load a immediate value if necessary
                    int imm_length = o.immediate_length;
                    if ((imm_length == 4) && (o.immediate_extends_on_rexw) && ((rex & 0x08) == 0x08))
                    {
                        imm_length = 8;
                    }
                    for (int i = 0; i < imm_length; i++)
                    {
                        byte cur_b = bp.GetNextByte();
                        os.Add(cur_b);
                        imm += ((ulong)cur_b) << (i * 8);
                    }

                    List <location> args = new List <location>();

                    foreach (opcode.operand_source osrc in o.operand_sources)
                    {
                        switch (osrc.type)
                        {
                        case opcode.operand_source.src_type.Fixed:
                            if (osrc.Fixed_Location.type == location.location_type.Register)
                            {
                                ulong reg_no = osrc.Fixed_Location.reg_no;
                                reg_no = reg_no % 8;

                                if (osrc.extends_on_rexb && ((rex & 0x01) == 0x01))
                                {
                                    reg_no += reg_nos["r8"];
                                }
                                else if ((rex & 0x08) == 0x08)
                                {
                                    reg_no += reg_nos["rax"];
                                }
                                else
                                {
                                    reg_no = osrc.Fixed_Location.reg_no;
                                }
                                args.Add(new location {
                                    type = location.location_type.Register, reg_no = reg_no
                                });
                            }
                            else
                            {
                                args.Add(osrc.Fixed_Location);
                            }
                            break;

                        case opcode.operand_source.src_type.Imm:
                            args.Add(new location {
                                type = location.location_type.Immediate, immediate = imm, is_pc_relative = osrc.is_pc_relative
                            });
                            break;
                        }
                    }

                    l.arguments = args.ToArray();
                }
            }

            l.o          = o;
            l.opcodes    = os.ToArray();
            l.bp         = bp;
            l.offset_end = bp.Offset;

            return(l);
        }