--- crash-4.0-8.12/main.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/main.c 2009-09-08 16:20:56.000000000 -0400 @@ -75,7 +75,7 @@ */ opterr = 0; optind = 0; - while((c = getopt_long(argc, argv, "Lkgh::e:i:sSvc:d:tfp:m:", + while((c = getopt_long(argc, argv, "Lkgh::e:i:sSvc:d:tfp:m:x", long_options, &option_index)) != -1) { switch (c) { @@ -321,6 +321,10 @@ optarg); break; + case 'x': + pc->flags |= PRELOAD_EXTENSIONS; + break; + default: error(INFO, "invalid option: %s\n", argv[optind-1]); @@ -578,6 +582,9 @@ pc->flags |= RUNTIME; + if (pc->flags & PRELOAD_EXTENSIONS) + preload_extensions(); + /* * Return here if a non-recoverable error occurs * during command execution. @@ -1128,6 +1135,9 @@ if (pc->flags & CRASHBUILTIN) sprintf(&buf[strlen(buf)], "%sCRASHBUILTIN", others++ ? "|" : ""); + if (pc->flags & PRELOAD_EXTENSIONS) + sprintf(&buf[strlen(buf)], + "%sPRELOAD_EXTENSIONS", others++ ? "|" : ""); if (pc->flags) strcat(buf, ")"); --- crash-4.0-8.12/memory.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/memory.c 2009-08-31 15:20:23.000000000 -0400 @@ -10481,7 +10481,7 @@ if (IS_SPARSEMEM()) { nr_mem_sections = NR_MEM_SECTIONS(); - for (nr = 0; nr <= nr_mem_sections ; nr++) { + for (nr = 0; nr < nr_mem_sections ; nr++) { if ((sec_addr = valid_section_nr(nr))) { coded_mem_map = section_mem_map_addr(sec_addr); mem_map = sparse_decode_mem_map(coded_mem_map, nr); --- crash-4.0-8.12/kernel.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/kernel.c 2009-08-26 10:32:02.000000000 -0400 @@ -81,7 +81,10 @@ kt->init_begin = symbol_value("__init_begin"); kt->init_end = symbol_value("__init_end"); } - kt->end = symbol_value("_end"); + if (symbol_exists("_end")) + kt->end = symbol_value("_end"); + else + kt->end = highest_bss_symbol(); /* * For the traditional (non-pv_ops) Xen architecture, default to writable @@ -2441,6 +2444,7 @@ fprintf(fp, " frameptr: %lx\n", (ulong)bt->frameptr); fprintf(fp, " call_target: %s\n", bt->call_target ? bt->call_target : "none"); + fprintf(fp, " eframe_ip: %lx\n", bt->eframe_ip); fprintf(fp, " debug: %lx\n", bt->debug); } --- crash-4.0-8.12/configure.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/configure.c 2009-09-01 11:52:23.000000000 -0400 @@ -25,10 +25,10 @@ * PROGRAM (for daemon) * create: build_data.c * - * -u clear: TARGET, GDB, GDB_FILES, GDB_OFILES, RELEASE and TARGET_CFLAGS + * -u clear: TARGET, GDB, GDB_FILES, GDB_OFILES, VERSION and TARGET_CFLAGS * undef: WARNING_ERROR, WARNING_OPTIONS * - * -r define: GDB_FILES, RELEASE + * -r define: GDB_FILES, VERSION * verify that no .rpmmacro file exists for the running shell * * -w define: WARNING_OPTIONS @@ -549,8 +549,8 @@ found++; if (strncmp(buf, "GDB_FILES=", strlen("GDB_FILES=")) == 0) fprintf(fp2, "GDB_FILES=${%s}\n", gdb_files); - else if (strncmp(buf, "RELEASE=", strlen("RELEASE=")) == 0) - fprintf(fp2, "RELEASE=%s\n", + else if (strncmp(buf, "VERSION=", strlen("VERSION=")) == 0) + fprintf(fp2, "VERSION=%s\n", target_data.release); else fprintf(fp2, "%s", buf); @@ -797,8 +797,8 @@ fprintf(fp2, "GDB_OFILES=\n"); else if (strncmp(buf, "GDB=", strlen("GDB=")) == 0) fprintf(fp2, "GDB=\n"); - else if (strncmp(buf, "RELEASE=", strlen("RELEASE=")) == 0) - fprintf(fp2, "RELEASE=\n"); + else if (strncmp(buf, "VERSION=", strlen("VERSION=")) == 0) + fprintf(fp2, "VERSION=\n"); else if (strncmp(buf, "WARNING_ERROR=", strlen("WARNING_ERROR=")) == 0) { shift_string_right(buf, 1); @@ -1140,14 +1140,14 @@ Release = strstr(target_data.release, "-"); if (!Release) { + Version = target_data.release; + Release = "0"; + } else { fprintf(stderr, - "\nNOTE: cannot create local spec file: no release number: [%s]\n", + "crash.spec: obsolete src.rpm build manner -- no dashes allowed: %s\n", target_data.release); return; } - *Release = '\0'; - Version = target_data.release; - Release++; printf("#\n"); printf("# crash core analysis suite\n"); @@ -1158,7 +1158,7 @@ printf("Release: %s\n", Release); printf("License: GPLv2\n"); printf("Group: Development/Debuggers\n"); - printf("Source: %%{name}-%%{version}-%%{release}.tar.gz\n"); + printf("Source: %%{name}-%%{version}.tar.gz\n"); printf("URL: http://people.redhat.com/anderson\n"); printf("Distribution: Linux 2.2 or greater\n"); printf("Vendor: Red Hat, Inc.\n"); @@ -1201,12 +1201,13 @@ printf("* snap: Takes a snapshot of live memory and creates a kdump dumpfile\n"); printf("\n"); printf("%%prep\n"); - printf("%%setup -n %%{name}-%%{version}-%%{release}\n"); + printf("%%setup -n %%{name}-%%{version}\n"); printf("# %%patch0 -p1 -b .install (patch example)\n"); printf("\n"); printf("%%build\n"); - printf("make RPMPKG=\"%%{version}-%%{release}\"\n"); - printf("make RPMPKG=\"%%{version}-%%{release}\" extensions\n"); + printf("make RPMPKG=\"%%{version}\"\n"); + printf("# make RPMPKG=\"%%{version}-%%{release}\"\n"); + printf("make extensions\n"); /* printf("make crashd\n"); */ printf("\n"); printf("%%install\n"); --- crash-4.0-8.12/x86_64.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/x86_64.c 2009-09-08 13:52:25.000000000 -0400 @@ -30,6 +30,8 @@ static ulong x86_64_get_task_pgd(ulong); static int x86_64_translate_pte(ulong, void *, ulonglong); static ulong x86_64_processor_speed(void); +static int is_vsyscall_addr(ulong); +struct syment *x86_64_value_to_symbol(ulong, ulong *); static int x86_64_eframe_search(struct bt_info *); static int x86_64_eframe_verify(struct bt_info *, long, long, long, long, long, long); static long x86_64_exception_frame(ulong,ulong,char *,struct bt_info *, FILE *); @@ -90,7 +92,7 @@ static ulong x86_64_get_stackbase_hyper(ulong); static ulong x86_64_get_stacktop_hyper(ulong); static int x86_64_framesize_cache_resize(void); -static int x86_64_framesize_cache_func(int, ulong, int *); +static int x86_64_framesize_cache_func(int, ulong, int *, int); static int x86_64_get_framesize(struct bt_info *, ulong); static void x86_64_framesize_debug(struct bt_info *); static void x86_64_get_active_set(void); @@ -244,13 +246,16 @@ machdep->cmd_mach = x86_64_cmd_mach; machdep->get_smp_cpus = x86_64_get_smp_cpus; machdep->line_number_hooks = x86_64_line_number_hooks; - machdep->value_to_symbol = generic_machdep_value_to_symbol; + machdep->value_to_symbol = x86_64_value_to_symbol; machdep->init_kernel_pgd = x86_64_init_kernel_pgd; machdep->clear_machdep_cache = x86_64_clear_machdep_cache; machdep->xendump_p2m_create = x86_64_xendump_p2m_create; machdep->get_xendump_regs = x86_64_get_xendump_regs; machdep->xen_kdump_p2m_create = x86_64_xen_kdump_p2m_create; machdep->xendump_panic_task = x86_64_xendump_panic_task; + if (symbol_exists("vgettimeofday")) + machdep->machspec->vsyscall_page = + PAGEBASE(symbol_value("vgettimeofday")); x86_64_calc_phys_base(); break; @@ -493,7 +498,7 @@ fprintf(fp, " xendump_panic_task: x86_64_xendump_panic_task()\n"); fprintf(fp, "xen_kdump_p2m_create: x86_64_xen_kdump_p2m_create()\n"); fprintf(fp, " line_number_hooks: x86_64_line_number_hooks\n"); - fprintf(fp, " value_to_symbol: generic_machdep_value_to_symbol()\n"); + fprintf(fp, " value_to_symbol: x86_64_value_to_symbol()\n"); fprintf(fp, " last_pgd_read: %lx\n", machdep->last_pgd_read); fprintf(fp, " last_pmd_read: %lx\n", machdep->last_pmd_read); fprintf(fp, " last_ptbl_read: %lx\n", machdep->last_ptbl_read); @@ -583,6 +588,7 @@ } if (ms->crash_nmi_rsp) fprintf(fp, "\n"); + fprintf(fp, " vsyscall_page: %lx\n", ms->vsyscall_page); fprintf(fp, " stkinfo: esize: %d%sisize: %d\n", ms->stkinfo.esize, @@ -1048,7 +1054,10 @@ static int x86_64_is_kvaddr(ulong addr) { - return (addr >= PAGE_OFFSET); + if (machdep->flags & VM_XEN_RHEL4) + return (addr >= VMALLOC_START); + else + return (addr >= PAGE_OFFSET); } static int @@ -2243,6 +2252,8 @@ char buf[BUFSIZE]; eframe_check = -1; + if (!(bt->flags & BT_SAVE_EFRAME_IP)) + bt->eframe_ip = 0; offset = 0; sp = value_search(text, &offset); if (!sp) @@ -2556,6 +2567,9 @@ bt->stackbuf + (irq_eframe - bt->stackbase), bt, ofp); rsp += SIZE(pt_regs); /* guaranteed kernel mode */ + if (bt->eframe_ip && ((framesize = x86_64_get_framesize(bt, + bt->eframe_ip)) >= 0)) + rsp += framesize; level++; irq_eframe = 0; } @@ -2579,7 +2593,8 @@ i += SIZE(pt_regs)/sizeof(ulong); case BACKTRACE_ENTRY_DISPLAYED: level++; - if ((framesize = x86_64_get_framesize(bt, *up)) >= 0) { + if ((framesize = x86_64_get_framesize(bt, + bt->eframe_ip ? bt->eframe_ip : *up)) >= 0) { rsp += framesize; i += framesize/sizeof(ulong); } @@ -2617,10 +2632,11 @@ * Print the return values from the estack end. */ if (!done) { - bt->flags |= BT_START; - x86_64_print_stack_entry(bt, ofp, level, - 0, bt->instptr); - bt->flags &= ~(BT_START|BT_FRAMESIZE_DISABLE); + bt->flags |= BT_START|BT_SAVE_EFRAME_IP; + x86_64_print_stack_entry(bt, ofp, level, + 0, bt->instptr); + bt->flags &= + ~(BT_START|BT_SAVE_EFRAME_IP|BT_FRAMESIZE_DISABLE); level++; if ((framesize = x86_64_get_framesize(bt, bt->instptr)) >= 0) rsp += framesize; @@ -2669,7 +2685,8 @@ i += SIZE(pt_regs)/sizeof(ulong); case BACKTRACE_ENTRY_DISPLAYED: level++; - if ((framesize = x86_64_get_framesize(bt, *up)) >= 0) { + if ((framesize = x86_64_get_framesize(bt, + bt->eframe_ip ? bt->eframe_ip : *up)) >= 0) { rsp += framesize; i += framesize/sizeof(ulong); } @@ -2779,6 +2796,9 @@ level++; rsp += SIZE(pt_regs); irq_eframe = 0; + if (bt->eframe_ip && ((framesize = x86_64_get_framesize(bt, + bt->eframe_ip)) >= 0)) + rsp += framesize; } level++; } @@ -2856,7 +2876,8 @@ i += SIZE(pt_regs)/sizeof(ulong); case BACKTRACE_ENTRY_DISPLAYED: level++; - if ((framesize = x86_64_get_framesize(bt, *up)) >= 0) { + if ((framesize = x86_64_get_framesize(bt, + bt->eframe_ip ? bt->eframe_ip : *up)) >= 0) { rsp += framesize; i += framesize/sizeof(ulong); } @@ -3449,6 +3470,7 @@ if (offset) fprintf(ofp, (output_radix == 16) ? "+0x%lx" : "+%ld", offset); + bt->eframe_ip = rip; } else fprintf(ofp, "unknown or invalid address"); fprintf(ofp, "]\n"); @@ -3548,6 +3570,33 @@ } /* + * Check whether an RIP is in the FIXMAP vsyscall page. + */ +static int +is_vsyscall_addr(ulong rip) +{ + ulong page; + + if ((page = machdep->machspec->vsyscall_page)) + if ((rip >= page) && (rip < (page+PAGESIZE()))) + return TRUE; + + return FALSE; +} + +struct syment * +x86_64_value_to_symbol(ulong vaddr, ulong *offset) +{ + struct syment *sp; + + if (is_vsyscall_addr(vaddr) && + (sp = value_search_base_kernel(vaddr, offset))) + return sp; + + return generic_machdep_value_to_symbol(vaddr, offset); +} + +/* * Check that the verifiable registers contain reasonable data. */ #define RAZ_MASK 0xffffffffffc08028 /* return-as-zero bits */ @@ -3590,6 +3639,8 @@ if ((cs == 0x33) && (ss == 0x2b)) { if (IS_UVADDR(rip, bt->tc) && IS_UVADDR(rsp, bt->tc)) return TRUE; + if (is_vsyscall_addr(rip) && IS_UVADDR(rsp, bt->tc)) + return TRUE; } if (XEN() && ((cs == 0x33) || (cs == 0xe033)) && @@ -3647,6 +3698,7 @@ ulong ur_rip, ur_rsp; ulong halt_rip, halt_rsp; ulong crash_kexec_rip, crash_kexec_rsp; + ulong call_function_rip, call_function_rsp; bt = &bt_local; BCOPY(bt_in, bt, sizeof(struct bt_info)); @@ -3654,6 +3706,7 @@ ur_rip = ur_rsp = 0; halt_rip = halt_rsp = 0; crash_kexec_rip = crash_kexec_rsp = 0; + call_function_rip = call_function_rsp = 0; stage = 0; estack = -1; @@ -3780,9 +3833,9 @@ if (!panic_task && (stage > 0) && STREQ(sym, "smp_call_function_interrupt")) { - *rip = *up; - *rsp = bt->stackbase + ((char *)(up) - bt->stackbuf); - return; + call_function_rip = *up; + call_function_rsp = bt->stackbase + + ((char *)(up) - bt->stackbuf); } if (!panic_task && STREQ(sym, "crash_nmi_callback")) { @@ -3865,6 +3918,12 @@ return; } + if (call_function_rip && call_function_rsp) { + *rip = call_function_rip; + *rsp = call_function_rsp; + return; + } + if (halt_rip && halt_rsp) { *rip = halt_rip; *rsp = halt_rsp; @@ -5822,6 +5881,7 @@ struct framesize_cache { ulong textaddr; int framesize; + int exception; }; static struct framesize_cache *x86_64_framesize_cache = NULL; @@ -5852,6 +5912,7 @@ fc++, i++) { fc->textaddr = 0; fc->framesize = 0; + fc->exception = 0; } x86_64_framesize_cache = new_fc; @@ -5861,9 +5922,9 @@ } static int -x86_64_framesize_cache_func(int cmd, ulong textaddr, int *framesize) +x86_64_framesize_cache_func(int cmd, ulong textaddr, int *framesize, int exception) { - int i; + int i, n; struct framesize_cache *fc; char buf[BUFSIZE]; @@ -5881,6 +5942,8 @@ fc = &x86_64_framesize_cache[0]; for (i = 0; i < framesize_cache_entries; i++, fc++) { if (fc->textaddr == textaddr) { + if (fc->exception != exception) + return FALSE; *framesize = fc->framesize; return TRUE; } @@ -5893,8 +5956,19 @@ for (i = 0; i < framesize_cache_entries; i++, fc++) { if ((fc->textaddr == 0) || (fc->textaddr == textaddr)) { + if (*framesize == -1) { + fc->textaddr = 0; + fc->framesize = 0; + fc->exception = 0; + for (n = i+1; n < framesize_cache_entries; + i++, n++) + x86_64_framesize_cache[i] = + x86_64_framesize_cache[n]; + return 0; + } fc->textaddr = textaddr; fc->framesize = *framesize; + fc->exception = exception; return fc->framesize; } } @@ -5915,8 +5989,9 @@ break; } - fprintf(fp, "[%3d]: %lx %3d (%s)\n", i, + fprintf(fp, "[%3d]: %lx %3d %s (%s)\n", i, fc->textaddr, fc->framesize, + fc->exception ? "EX" : "CF", value_to_symstr(fc->textaddr, buf, 0)); } break; @@ -5941,6 +6016,8 @@ ulong locking_func, textaddr_save, current; char *p1, *p2; int reterror; + int arg_exists; + int exception; if (!(bt->flags & BT_FRAMESIZE_DEBUG)) { if ((bt->flags & BT_FRAMESIZE_IGNORE_MASK) || @@ -5954,8 +6031,11 @@ return 0; } + exception = bt->eframe_ip == textaddr ? TRUE : FALSE; + if (!(bt->flags & BT_FRAMESIZE_DEBUG) && - x86_64_framesize_cache_func(FRAMESIZE_QUERY, textaddr, &framesize)) { + x86_64_framesize_cache_func(FRAMESIZE_QUERY, textaddr, &framesize, + exception)) { if (framesize == -1) bt->flags |= BT_FRAMESIZE_DISABLE; return framesize; @@ -6014,15 +6094,22 @@ } } - if (c < (arg+1)) + if (c < (instr+1)) continue; + else if (c >= (arg+1)) + arg_exists = TRUE; + else + arg_exists = FALSE; reterror = 0; current = htol(strip_ending_char(arglist[0], ':'), RETURN_ON_ERROR, &reterror); if (reterror) continue; - if (current >= textaddr) + + if (current > textaddr) + break; + else if ((current == textaddr) && !exception) break; if (STRNEQ(arglist[instr], "push")) { @@ -6035,7 +6122,7 @@ if (CRASHDEBUG(2) || (bt->flags & BT_FRAMESIZE_DEBUG)) fprintf(pc->saved_fp, "%s\t[framesize: %d]\n", strip_linefeeds(buf2), framesize); - } else if (STRNEQ(arglist[instr], "add") && + } else if (arg_exists && STRNEQ(arglist[instr], "add") && (p1 = strstr(arglist[arg], ",%rsp"))) { *p1 = NULLCHAR; p2 = arglist[arg]; @@ -6047,7 +6134,7 @@ if (CRASHDEBUG(2) || (bt->flags & BT_FRAMESIZE_DEBUG)) fprintf(pc->saved_fp, "%s\t[framesize: %d]\n", strip_linefeeds(buf2), framesize); - } else if (STRNEQ(arglist[instr], "sub") && + } else if (arg_exists && STRNEQ(arglist[instr], "sub") && (p1 = strstr(arglist[arg], ",%rsp"))) { *p1 = NULLCHAR; p2 = arglist[arg]; @@ -6059,45 +6146,44 @@ if (CRASHDEBUG(2) || (bt->flags & BT_FRAMESIZE_DEBUG)) fprintf(pc->saved_fp, "%s\t[framesize: %d]\n", strip_linefeeds(buf2), framesize); - } else if (STRNEQ(arglist[instr], "retq")) { + } else if (STRNEQ(arglist[instr], "retq_NOT_CHECKED")) { bt->flags |= BT_FRAMESIZE_DISABLE; framesize = -1; if (CRASHDEBUG(2) || (bt->flags & BT_FRAMESIZE_DEBUG)) fprintf(pc->saved_fp, "%s\t[framesize: DISABLED]\n", strip_linefeeds(buf2)); break; - } + } } close_tmpfile2(); if (textaddr_save) textaddr = textaddr_save; - return (x86_64_framesize_cache_func(FRAMESIZE_ENTER, textaddr, &framesize)); + return (x86_64_framesize_cache_func(FRAMESIZE_ENTER, textaddr, + &framesize, exception)); } static void x86_64_framesize_debug(struct bt_info *bt) { int framesize; + int exception; + + exception = (bt->flags & BT_EFRAME_SEARCH); switch (bt->hp->esp) { case 1: /* "dump" */ - if (bt->hp->eip) { - framesize = 1; - x86_64_framesize_cache_func(FRAMESIZE_ENTER, bt->hp->eip, - &framesize); - } else - x86_64_framesize_cache_func(FRAMESIZE_DUMP, 0, NULL); + x86_64_framesize_cache_func(FRAMESIZE_DUMP, 0, NULL, 0); break; case 0: - if (bt->hp->eip) { - framesize = 0; + if (bt->hp->eip) { /* clear one entry */ + framesize = -1; x86_64_framesize_cache_func(FRAMESIZE_ENTER, bt->hp->eip, - &framesize); - } else /* "clear" */ + &framesize, exception); + } else /* clear all entries */ BZERO(&x86_64_framesize_cache[0], sizeof(struct framesize_cache)*framesize_cache_entries); break; @@ -6114,7 +6200,7 @@ framesize = bt->hp->esp; if (bt->hp->eip) x86_64_framesize_cache_func(FRAMESIZE_ENTER, bt->hp->eip, - &framesize); + &framesize, exception); } else error(INFO, "x86_64_framesize_debug: ignoring command\n"); break; --- crash-4.0-8.12/extensions.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/extensions.c 2009-09-03 16:33:18.000000000 -0400 @@ -19,6 +19,7 @@ #include static int in_extensions_library(char *, char *); +static char *get_extensions_directory(char *); #define DUMP_EXTENSIONS (0) #define LOAD_EXTENSION (1) @@ -228,7 +229,7 @@ } else strcpy(ext->filename, lib); - if (!is_elf_file(ext->filename)) { + if (!is_shared_object(ext->filename)) { error(INFO, "%s: not an ELF format object file\n", ext->filename); free(ext); @@ -324,6 +325,80 @@ } /* + * Look for an extensions directory using the proper order. + */ +static char * +get_extensions_directory(char *dirbuf) +{ + char *env; + + if ((env = getenv("CRASH_EXTENSIONS"))) { + if (is_directory(env)) { + strcpy(dirbuf, env); + return dirbuf; + } + } + + if (BITS64()) { + sprintf(dirbuf, "/usr/lib64/crash/extensions"); + if (is_directory(dirbuf)) + return dirbuf; + } + + sprintf(dirbuf, "/usr/lib/crash/extensions"); + if (is_directory(dirbuf)) + return dirbuf; + + sprintf(dirbuf, "./extensions"); + if (is_directory(dirbuf)) + return dirbuf; + + return NULL; +} + + +void +preload_extensions(void) +{ + DIR *dirp; + struct dirent *dp; + char dirbuf[BUFSIZE]; + char filename[BUFSIZE]; + int found; + + if (!get_extensions_directory(dirbuf)) + return; + + dirp = opendir(dirbuf); + if (!dirp) { + error(INFO, "%s: %s\n", dirbuf, strerror(errno)); + return; + } + + for (found = 0, dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + sprintf(filename, "%s%s%s", dirbuf, + LASTCHAR(dirbuf) == '/' ? "" : "/", + dp->d_name); + + if (!is_shared_object(filename)) + continue; + + found++; + + load_extension(dp->d_name); + } + + closedir(dirp); + + if (found) + fprintf(fp, "\n"); + else + error(NOTE, + "%s: no extension modules found in directory\n\n", + dirbuf); +} + +/* * Unload all, or as specified, extension libraries. */ void --- crash-4.0-8.12/symbols.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/symbols.c 2009-09-03 16:07:46.000000000 -0400 @@ -2653,6 +2653,86 @@ return(is_bfd_format(file)); } +int +is_shared_object(char *file) +{ + int fd, swap; + char eheader[BUFSIZE]; + Elf32_Ehdr *elf32; + Elf64_Ehdr *elf64; + + if (is_directory(file)) + return FALSE; + + if ((fd = open(file, O_RDONLY)) < 0) + return FALSE; + + if (read(fd, eheader, BUFSIZE) != BUFSIZE) { + close(fd); + return FALSE; + } + close(fd); + + if (!STRNEQ(eheader, ELFMAG) || eheader[EI_VERSION] != EV_CURRENT) + return FALSE; + + elf32 = (Elf32_Ehdr *)&eheader[0]; + elf64 = (Elf64_Ehdr *)&eheader[0]; + + swap = (((eheader[EI_DATA] == ELFDATA2LSB) && + (__BYTE_ORDER == __BIG_ENDIAN)) || + ((eheader[EI_DATA] == ELFDATA2MSB) && + (__BYTE_ORDER == __LITTLE_ENDIAN))); + + if ((elf32->e_ident[EI_CLASS] == ELFCLASS32) && + (swap16(elf32->e_type, swap) == ET_DYN)) { + switch (swap16(elf32->e_machine, swap)) + { + case EM_386: + if (machine_type("x86")) + return TRUE; + break; + + case EM_S390: + if (machine_type("S390")) + return TRUE; + break; + } + + if (CRASHDEBUG(1)) + error(INFO, "%s: machine type mismatch: %d\n", + file, swap16(elf32->e_machine, swap)); + + return FALSE; + + } else if ((elf64->e_ident[EI_CLASS] == ELFCLASS64) && + (swap16(elf64->e_type, swap) == ET_DYN)) { + switch (swap16(elf64->e_machine, swap)) + { + case EM_IA_64: + if (machine_type("IA64")) + return TRUE; + break; + + case EM_PPC64: + if (machine_type("PPC64")) + return TRUE; + break; + + case EM_X86_64: + if (machine_type("X86_64")) + return TRUE; + break; + } + + if (CRASHDEBUG(1)) + error(INFO, "%s: machine type mismatch: %d\n", + file, swap16(elf32->e_machine, swap)); + } + + return FALSE; +} + /* * Given a choice between two namelists, pick the one for gdb to use. * For now, just check get their stats and check their sizes; the larger @@ -3471,6 +3551,21 @@ return((struct syment *)NULL); } +ulong +highest_bss_symbol(void) +{ + struct syment *sp; + ulong highest = 0; + + for (sp = st->symtable; sp < st->symend; sp++) { + if ((sp->type == 'b') || (sp->type == 'B')) { + if (sp->value > highest) + highest = sp->value; + } + } + return highest; +} + /* * Search for a value only within the base kernel's symbols, * also avoiding the machdep->value_to_symbol() call, which will @@ -8953,7 +9048,7 @@ patch_kernel_symbol(struct gnu_request *req) { int i, c; - struct syment *sp_array[200], *sp; + struct syment *sp_array[1000], *sp; if (req->name == PATCH_KERNEL_SYMBOLS_START) { if (kt->flags & RELOC_FORCE) @@ -8988,7 +9083,7 @@ sp->allocated = TRUE; req->last_sp = (ulong)sp; } else { - switch (c = get_syment_array(req->name, sp_array, 200)) + switch (c = get_syment_array(req->name, sp_array, 1000)) { case 0: req->last_sp = 0; return TRUE; --- crash-4.0-8.12/diskdump.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/diskdump.c 2009-08-19 09:05:28.000000000 -0400 @@ -399,10 +399,10 @@ return FALSE; } -static int +static ulong pfn_to_pos(ulong pfn) { - int desc_pos, j, valid; + ulong desc_pos, j, valid; ulong p1, p2; if (KDUMP_SPLIT()) { @@ -530,7 +530,7 @@ int i, ret; int found; ulong pfn; - int desc_pos; + ulong desc_pos; off_t seek_offset; page_desc_t pd; const int block_size = dd->block_size; --- crash-4.0-8.12/defs.h 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/defs.h 2009-09-08 16:43:24.000000000 -0400 @@ -188,6 +188,8 @@ #define KERNTYPES (0x800000000000000ULL) #define MINIMAL_MODE (0x1000000000000000ULL) #define CRASHBUILTIN (0x2000000000000000ULL) +#define PRELOAD_EXTENSIONS \ + (0x4000000000000000ULL) #define ACTIVE() (pc->flags & LIVE_SYSTEM) #define DUMPFILE() (!(pc->flags & LIVE_SYSTEM)) @@ -710,6 +712,7 @@ char *call_target; void *machdep; ulong debug; + ulong eframe_ip; }; #define STACK_OFFSET_TYPE(OFF) \ @@ -3324,6 +3327,7 @@ struct syment *symbol_search(char *); struct syment *value_search(ulong, ulong *); struct syment *value_search_base_kernel(ulong, ulong *); +ulong highest_bss_symbol(void); int in_ksymbol_range(ulong); int module_symbol(ulong, struct syment **, struct load_module **, char *, ulong); @@ -3362,6 +3366,7 @@ void dump_offset_table(char *, ulong); int is_elf_file(char *); int is_kernel(char *); +int is_shared_object(char *); int file_elf_version(char *); int is_system_map(char *); int select_namelist(char *); @@ -3643,6 +3648,7 @@ void dump_extension_table(int); void load_extension(char *); void unload_extension(char *); +void preload_extensions(void); /* Hooks for sial */ unsigned long get_curtask(void); char *crash_global_cmd(void); @@ -3726,6 +3732,7 @@ #define BT_TEXT_SYMBOLS_ALL (0x4000000000ULL) #define BT_XEN_STOP_THIS_CPU (0x8000000000ULL) #define BT_THREAD_GROUP (0x10000000000ULL) +#define BT_SAVE_EFRAME_IP (0x20000000000ULL) #define BT_REF_HEXVAL (0x1) #define BT_REF_SYMBOL (0x2) @@ -3882,6 +3889,7 @@ struct x86_64_stkinfo stkinfo; ulong *current; ulong *crash_nmi_rsp; + ulong vsyscall_page; }; #define KSYMS_START (0x1) --- crash-4.0-8.12/Makefile 2009-09-09 15:54:21.000000000 -0400 +++ crash-4.0.9/Makefile 2009-09-09 15:54:20.000000000 -0400 @@ -506,14 +506,8 @@ tar cvzf ${PROGRAM}.tar.gz ${TAR_FILES} ${GDB_FILES} ${GDB_PATCH_FILES} @echo; ls -l ${PROGRAM}.tar.gz -# To create a base tar file for Red Hat RPM packaging, pass the base RPM -# version number without the release number, as in: "make release RPMPKG=x.y". -# This will cause the local src.rpm creation to fail below (as it should). -# However, when the package is created by the Red Hat build procedure, its -# spec file will have its own release number, which will in turn get passed -# to the "all" target upon the initial build. - -RELEASE= +VERSION= +RELEASE=0 release: make_configure @if [ "`id --user`" != "0" ]; then \ @@ -530,34 +524,34 @@ @make --no-print-directory do_release do_release: - @echo "RELEASE: ${RELEASE} GDB VERSION: ${GDB}" + @echo "CRASH VERSION: ${VERSION} GDB VERSION: ${GDB}" @if [ ! -f .rh_rpm_package ]; then \ echo "no .rh_rpm_package exists!"; exit 1; fi @chmod 666 .rh_rpm_package - @rm -rf ./RELDIR; mkdir ./RELDIR; mkdir ./RELDIR/${PROGRAM}-${RELEASE} - @rm -f ${PROGRAM}-${RELEASE}.tar.gz - @rm -f ${PROGRAM}-${RELEASE}.src.rpm - @chown root ./RELDIR/${PROGRAM}-${RELEASE} + @rm -rf ./RELDIR; mkdir ./RELDIR; mkdir ./RELDIR/${PROGRAM}-${VERSION} + @rm -f ${PROGRAM}-${VERSION}.tar.gz + @rm -f ${PROGRAM}-${VERSION}-${RELEASE}.src.rpm + @chown root ./RELDIR/${PROGRAM}-${VERSION} @tar cf - ${SOURCE_FILES} Makefile ${GDB_FILES} ${GDB_PATCH_FILES} COPYING \ - .rh_rpm_package crash.8 ${EXTENSION_SOURCE_FILES} | (cd ./RELDIR/${PROGRAM}-${RELEASE}; tar xf -) - @cp ${GDB}.tar.gz ./RELDIR/${PROGRAM}-${RELEASE} - @./${PROGRAM} --no_scroll --no_crashrc -h README > ./RELDIR/${PROGRAM}-${RELEASE}/README + .rh_rpm_package crash.8 ${EXTENSION_SOURCE_FILES} | (cd ./RELDIR/${PROGRAM}-${VERSION}; tar xf -) + @cp ${GDB}.tar.gz ./RELDIR/${PROGRAM}-${VERSION} + @./${PROGRAM} --no_scroll --no_crashrc -h README > ./RELDIR/${PROGRAM}-${VERSION}/README @(cd ./RELDIR; find . -exec chown root {} ";") @(cd ./RELDIR; find . -exec chgrp root {} ";") @(cd ./RELDIR; find . -exec touch {} ";") @(cd ./RELDIR; \ - tar czvf ../${PROGRAM}-${RELEASE}.tar.gz ${PROGRAM}-${RELEASE}) - @chgrp root ${PROGRAM}-${RELEASE}.tar.gz + tar czvf ../${PROGRAM}-${VERSION}.tar.gz ${PROGRAM}-${VERSION}) + @chgrp root ${PROGRAM}-${VERSION}.tar.gz @rm -rf ./RELDIR @echo - @ls -l ${PROGRAM}-${RELEASE}.tar.gz + @ls -l ${PROGRAM}-${VERSION}.tar.gz @./configure -s -u > ${PROGRAM}.spec @if [ -s ${PROGRAM}.spec ]; then \ - cp ${PROGRAM}-${RELEASE}.tar.gz /usr/src/redhat/SOURCES; \ + cp ${PROGRAM}-${VERSION}.tar.gz /usr/src/redhat/SOURCES; \ /usr/bin/rpmbuild -bs ${PROGRAM}.spec > /dev/null; \ - rm -f /usr/src/redhat/SOURCES/${PROGRAM}-${RELEASE}.tar.gz; \ - mv /usr/src/redhat/SRPMS/${PROGRAM}-${RELEASE}.src.rpm . ; \ - ls -l ${PROGRAM}-${RELEASE}.src.rpm; \ + rm -f /usr/src/redhat/SOURCES/${PROGRAM}-${VERSION}.tar.gz; \ + mv /usr/src/redhat/SRPMS/${PROGRAM}-${VERSION}-${RELEASE}.src.rpm . ; \ + ls -l ${PROGRAM}-${VERSION}-${RELEASE}.src.rpm; \ exit 0; fi ref: --- crash-4.0-8.12/gdb-6.1.patch 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/gdb-6.1.patch 2009-08-14 16:11:10.000000000 -0400 @@ -378,3 +378,11377 @@ 2007-12-13 Jim Blandy * dwarf2read.c (attr_form_is_constant): New function. +--- gdb-6.1/opcodes/i386-dis.c.orig ++++ gdb-6.1/opcodes/i386-dis.c +@@ -1,52 +1,47 @@ + /* Print i386 instructions for GDB, the GNU debugger. + Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +- 2001, 2002, 2003 Free Software Foundation, Inc. ++ 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + +-This file is part of GDB. ++ This file is part of the GNU opcodes library. + +-This program is free software; you can redistribute it and/or modify +-it under the terms of the GNU General Public License as published by +-the Free Software Foundation; either version 2 of the License, or +-(at your option) any later version. +- +-This program is distributed in the hope that it will be useful, +-but WITHOUT ANY WARRANTY; without even the implied warranty of +-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-GNU General Public License for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program; if not, write to the Free Software +-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ This library is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3, or (at your option) ++ any later version. ++ ++ It is distributed in the hope that it will be useful, but WITHOUT ++ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY ++ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public ++ License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++ ++/* 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) ++ July 1988 ++ modified by John Hassey (hassey@dg-rtp.dg.com) ++ x86-64 support added by Jan Hubicka (jh@suse.cz) ++ VIA PadLock support by Michal Ludvig (mludvig@suse.cz). */ ++ ++/* The main tables describing the instructions is essentially a copy ++ of the "Opcode Map" chapter (Appendix A) of the Intel 80386 ++ Programmers Manual. Usually, there is a capital letter, followed ++ by a small letter. The capital letter tell the addressing mode, ++ and the small letter tells about the operand size. Refer to ++ the Intel manual for details. */ + +-/* +- * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu) +- * July 1988 +- * modified by John Hassey (hassey@dg-rtp.dg.com) +- * x86-64 support added by Jan Hubicka (jh@suse.cz) +- */ +- +-/* +- * The main tables describing the instructions is essentially a copy +- * of the "Opcode Map" chapter (Appendix A) of the Intel 80386 +- * Programmers Manual. Usually, there is a capital letter, followed +- * by a small letter. The capital letter tell the addressing mode, +- * and the small letter tells about the operand size. Refer to +- * the Intel manual for details. +- */ +- +-#include "dis-asm.h" + #include "sysdep.h" ++#include "dis-asm.h" + #include "opintl.h" +- +-#define MAXLEN 20 ++#include "opcode/i386.h" ++#include "libiberty.h" + + #include + +-#ifndef UNIXWARE_COMPAT +-/* Set non-zero for broken, compatible instructions. Set to zero for +- non-broken opcodes. */ +-#define UNIXWARE_COMPAT 1 +-#endif ++#define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0) + + static int fetch_data (struct disassemble_info *, bfd_byte *); + static void ckprefix (void); +@@ -60,6 +55,8 @@ static void oappend (const char *); + static void append_seg (void); + static void OP_indirE (int, int); + static void print_operand_value (char *, int, bfd_vma); ++static void OP_E_extended (int, int, int); ++static void print_displacement (char *, bfd_vma); + static void OP_E (int, int); + static void OP_G (int, int); + static bfd_vma get64 (void); +@@ -67,6 +64,7 @@ static bfd_signed_vma get32 (void); + static bfd_signed_vma get32s (void); + static int get16 (void); + static void set_op (bfd_vma, int); ++static void OP_Skip_MODRM (int, int); + static void OP_REG (int, int); + static void OP_IMREG (int, int); + static void OP_I (int, int); +@@ -83,34 +81,51 @@ static void OP_DSreg (int, int); + static void OP_C (int, int); + static void OP_D (int, int); + static void OP_T (int, int); +-static void OP_Rd (int, int); ++static void OP_R (int, int); + static void OP_MMX (int, int); + static void OP_XMM (int, int); + static void OP_EM (int, int); + static void OP_EX (int, int); ++static void OP_EMC (int,int); ++static void OP_MXC (int,int); + static void OP_MS (int, int); + static void OP_XS (int, int); ++static void OP_M (int, int); ++static void OP_0f07 (int, int); ++static void OP_Monitor (int, int); ++static void OP_Mwait (int, int); ++static void NOP_Fixup1 (int, int); ++static void NOP_Fixup2 (int, int); + static void OP_3DNowSuffix (int, int); +-static void OP_SIMD_Suffix (int, int); +-static void SIMD_Fixup (int, int); +-static void PNI_Fixup (int, int); ++static void CMP_Fixup (int, int); + static void BadOp (void); ++static void REP_Fixup (int, int); ++static void CMPXCHG8B_Fixup (int, int); ++static void XMM_Fixup (int, int); ++static void CRC32_Fixup (int, int); ++static void print_drex_arg (unsigned int, int, int); ++static void OP_DREX4 (int, int); ++static void OP_DREX3 (int, int); ++static void OP_DREX_ICMP (int, int); ++static void OP_DREX_FCMP (int, int); + + struct dis_private { + /* Points to first byte not fetched. */ + bfd_byte *max_fetched; +- bfd_byte the_buffer[MAXLEN]; ++ bfd_byte the_buffer[MAX_MNEM_SIZE]; + bfd_vma insn_start; + int orig_sizeflag; + jmp_buf bailout; + }; + +-/* The opcode for the fwait instruction, which we treat as a prefix +- when we can. */ +-#define FWAIT_OPCODE (0x9b) ++enum address_mode ++{ ++ mode_16bit, ++ mode_32bit, ++ mode_64bit ++}; + +-/* Set to 1 for 64bit mode disassembly. */ +-static int mode_64bit; ++enum address_mode address_mode; + + /* Flags for the prefixes for the current instruction. See below. */ + static int prefixes; +@@ -119,10 +134,6 @@ static int prefixes; + static int rex; + /* Bits of REX we've already used. */ + static int rex_used; +-#define REX_MODE64 8 +-#define REX_EXTX 4 +-#define REX_EXTY 2 +-#define REX_EXTZ 1 + /* Mark parts used in the REX prefix. When we are testing for + empty prefix (for 8bit register REX extension), just mask it + out. Otherwise test for REX bit is excuse for existence of REX +@@ -130,11 +141,28 @@ static int rex_used; + #define USED_REX(value) \ + { \ + if (value) \ +- rex_used |= (rex & value) ? (value) | 0x40 : 0; \ ++ { \ ++ if ((rex & value)) \ ++ rex_used |= (value) | REX_OPCODE; \ ++ } \ + else \ +- rex_used |= 0x40; \ ++ rex_used |= REX_OPCODE; \ + } + ++/* Special 'registers' for DREX handling */ ++#define DREX_REG_UNKNOWN 1000 /* not initialized */ ++#define DREX_REG_MEMORY 1001 /* use MODRM/SIB/OFFSET memory */ ++ ++/* The DREX byte has the following fields: ++ Bits 7-4 -- DREX.Dest, xmm destination register ++ Bit 3 -- DREX.OC0, operand config bit defines operand order ++ Bit 2 -- DREX.R, equivalent to REX_R bit, to extend ModRM register ++ Bit 1 -- DREX.X, equivalent to REX_X bit, to extend SIB index field ++ Bit 0 -- DREX.W, equivalent to REX_B bit, to extend ModRM r/m field, ++ SIB base field, or opcode reg field. */ ++#define DREX_XMM(drex) ((drex >> 4) & 0xf) ++#define DREX_OC0(drex) ((drex >> 3) & 0x1) ++ + /* Flags for prefixes which we somehow handled when printing the + current instruction. */ + static int used_prefixes; +@@ -167,10 +195,13 @@ fetch_data (struct disassemble_info *inf + struct dis_private *priv = (struct dis_private *) info->private_data; + bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); + +- status = (*info->read_memory_func) (start, +- priv->max_fetched, +- addr - priv->max_fetched, +- info); ++ if (addr <= priv->the_buffer + MAX_MNEM_SIZE) ++ status = (*info->read_memory_func) (start, ++ priv->max_fetched, ++ addr - priv->max_fetched, ++ info); ++ else ++ status = -1; + if (status != 0) + { + /* If we did manage to read at least one byte, then +@@ -186,532 +217,801 @@ fetch_data (struct disassemble_info *inf + return 1; + } + +-#define XX NULL, 0 ++#define XX { NULL, 0 } + +-#define Eb OP_E, b_mode +-#define Ev OP_E, v_mode +-#define Ed OP_E, d_mode +-#define Edq OP_E, dq_mode +-#define indirEb OP_indirE, b_mode +-#define indirEv OP_indirE, v_mode +-#define Ew OP_E, w_mode +-#define Ma OP_E, v_mode +-#define M OP_E, 0 /* lea, lgdt, etc. */ +-#define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */ +-#define Gb OP_G, b_mode +-#define Gv OP_G, v_mode +-#define Gd OP_G, d_mode +-#define Gw OP_G, w_mode +-#define Rd OP_Rd, d_mode +-#define Rm OP_Rd, m_mode +-#define Ib OP_I, b_mode +-#define sIb OP_sI, b_mode /* sign extened byte */ +-#define Iv OP_I, v_mode +-#define Iq OP_I, q_mode +-#define Iv64 OP_I64, v_mode +-#define Iw OP_I, w_mode +-#define Jb OP_J, b_mode +-#define Jv OP_J, v_mode +-#define Cm OP_C, m_mode +-#define Dm OP_D, m_mode +-#define Td OP_T, d_mode +- +-#define RMeAX OP_REG, eAX_reg +-#define RMeBX OP_REG, eBX_reg +-#define RMeCX OP_REG, eCX_reg +-#define RMeDX OP_REG, eDX_reg +-#define RMeSP OP_REG, eSP_reg +-#define RMeBP OP_REG, eBP_reg +-#define RMeSI OP_REG, eSI_reg +-#define RMeDI OP_REG, eDI_reg +-#define RMrAX OP_REG, rAX_reg +-#define RMrBX OP_REG, rBX_reg +-#define RMrCX OP_REG, rCX_reg +-#define RMrDX OP_REG, rDX_reg +-#define RMrSP OP_REG, rSP_reg +-#define RMrBP OP_REG, rBP_reg +-#define RMrSI OP_REG, rSI_reg +-#define RMrDI OP_REG, rDI_reg +-#define RMAL OP_REG, al_reg +-#define RMAL OP_REG, al_reg +-#define RMCL OP_REG, cl_reg +-#define RMDL OP_REG, dl_reg +-#define RMBL OP_REG, bl_reg +-#define RMAH OP_REG, ah_reg +-#define RMCH OP_REG, ch_reg +-#define RMDH OP_REG, dh_reg +-#define RMBH OP_REG, bh_reg +-#define RMAX OP_REG, ax_reg +-#define RMDX OP_REG, dx_reg +- +-#define eAX OP_IMREG, eAX_reg +-#define eBX OP_IMREG, eBX_reg +-#define eCX OP_IMREG, eCX_reg +-#define eDX OP_IMREG, eDX_reg +-#define eSP OP_IMREG, eSP_reg +-#define eBP OP_IMREG, eBP_reg +-#define eSI OP_IMREG, eSI_reg +-#define eDI OP_IMREG, eDI_reg +-#define AL OP_IMREG, al_reg +-#define AL OP_IMREG, al_reg +-#define CL OP_IMREG, cl_reg +-#define DL OP_IMREG, dl_reg +-#define BL OP_IMREG, bl_reg +-#define AH OP_IMREG, ah_reg +-#define CH OP_IMREG, ch_reg +-#define DH OP_IMREG, dh_reg +-#define BH OP_IMREG, bh_reg +-#define AX OP_IMREG, ax_reg +-#define DX OP_IMREG, dx_reg +-#define indirDX OP_IMREG, indir_dx_reg +- +-#define Sw OP_SEG, w_mode +-#define Ap OP_DIR, 0 +-#define Ob OP_OFF, b_mode +-#define Ob64 OP_OFF64, b_mode +-#define Ov OP_OFF, v_mode +-#define Ov64 OP_OFF64, v_mode +-#define Xb OP_DSreg, eSI_reg +-#define Xv OP_DSreg, eSI_reg +-#define Yb OP_ESreg, eDI_reg +-#define Yv OP_ESreg, eDI_reg +-#define DSBX OP_DSreg, eBX_reg +- +-#define es OP_REG, es_reg +-#define ss OP_REG, ss_reg +-#define cs OP_REG, cs_reg +-#define ds OP_REG, ds_reg +-#define fs OP_REG, fs_reg +-#define gs OP_REG, gs_reg +- +-#define MX OP_MMX, 0 +-#define XM OP_XMM, 0 +-#define EM OP_EM, v_mode +-#define EX OP_EX, v_mode +-#define MS OP_MS, v_mode +-#define XS OP_XS, v_mode +-#define None OP_E, 0 +-#define OPSUF OP_3DNowSuffix, 0 +-#define OPSIMD OP_SIMD_Suffix, 0 ++#define Eb { OP_E, b_mode } ++#define Ev { OP_E, v_mode } ++#define Ed { OP_E, d_mode } ++#define Edq { OP_E, dq_mode } ++#define Edqw { OP_E, dqw_mode } ++#define Edqb { OP_E, dqb_mode } ++#define Edqd { OP_E, dqd_mode } ++#define Eq { OP_E, q_mode } ++#define indirEv { OP_indirE, stack_v_mode } ++#define indirEp { OP_indirE, f_mode } ++#define stackEv { OP_E, stack_v_mode } ++#define Em { OP_E, m_mode } ++#define Ew { OP_E, w_mode } ++#define M { OP_M, 0 } /* lea, lgdt, etc. */ ++#define Ma { OP_M, a_mode } ++#define Mb { OP_M, b_mode } ++#define Md { OP_M, d_mode } ++#define Mp { OP_M, f_mode } /* 32 or 48 bit memory operand for LDS, LES etc */ ++#define Mq { OP_M, q_mode } ++#define Mx { OP_M, x_mode } ++#define Gb { OP_G, b_mode } ++#define Gv { OP_G, v_mode } ++#define Gd { OP_G, d_mode } ++#define Gdq { OP_G, dq_mode } ++#define Gm { OP_G, m_mode } ++#define Gw { OP_G, w_mode } ++#define Rd { OP_R, d_mode } ++#define Rm { OP_R, m_mode } ++#define Ib { OP_I, b_mode } ++#define sIb { OP_sI, b_mode } /* sign extened byte */ ++#define Iv { OP_I, v_mode } ++#define Iq { OP_I, q_mode } ++#define Iv64 { OP_I64, v_mode } ++#define Iw { OP_I, w_mode } ++#define I1 { OP_I, const_1_mode } ++#define Jb { OP_J, b_mode } ++#define Jv { OP_J, v_mode } ++#define Cm { OP_C, m_mode } ++#define Dm { OP_D, m_mode } ++#define Td { OP_T, d_mode } ++#define Skip_MODRM { OP_Skip_MODRM, 0 } ++ ++#define RMeAX { OP_REG, eAX_reg } ++#define RMeBX { OP_REG, eBX_reg } ++#define RMeCX { OP_REG, eCX_reg } ++#define RMeDX { OP_REG, eDX_reg } ++#define RMeSP { OP_REG, eSP_reg } ++#define RMeBP { OP_REG, eBP_reg } ++#define RMeSI { OP_REG, eSI_reg } ++#define RMeDI { OP_REG, eDI_reg } ++#define RMrAX { OP_REG, rAX_reg } ++#define RMrBX { OP_REG, rBX_reg } ++#define RMrCX { OP_REG, rCX_reg } ++#define RMrDX { OP_REG, rDX_reg } ++#define RMrSP { OP_REG, rSP_reg } ++#define RMrBP { OP_REG, rBP_reg } ++#define RMrSI { OP_REG, rSI_reg } ++#define RMrDI { OP_REG, rDI_reg } ++#define RMAL { OP_REG, al_reg } ++#define RMAL { OP_REG, al_reg } ++#define RMCL { OP_REG, cl_reg } ++#define RMDL { OP_REG, dl_reg } ++#define RMBL { OP_REG, bl_reg } ++#define RMAH { OP_REG, ah_reg } ++#define RMCH { OP_REG, ch_reg } ++#define RMDH { OP_REG, dh_reg } ++#define RMBH { OP_REG, bh_reg } ++#define RMAX { OP_REG, ax_reg } ++#define RMDX { OP_REG, dx_reg } ++ ++#define eAX { OP_IMREG, eAX_reg } ++#define eBX { OP_IMREG, eBX_reg } ++#define eCX { OP_IMREG, eCX_reg } ++#define eDX { OP_IMREG, eDX_reg } ++#define eSP { OP_IMREG, eSP_reg } ++#define eBP { OP_IMREG, eBP_reg } ++#define eSI { OP_IMREG, eSI_reg } ++#define eDI { OP_IMREG, eDI_reg } ++#define AL { OP_IMREG, al_reg } ++#define CL { OP_IMREG, cl_reg } ++#define DL { OP_IMREG, dl_reg } ++#define BL { OP_IMREG, bl_reg } ++#define AH { OP_IMREG, ah_reg } ++#define CH { OP_IMREG, ch_reg } ++#define DH { OP_IMREG, dh_reg } ++#define BH { OP_IMREG, bh_reg } ++#define AX { OP_IMREG, ax_reg } ++#define DX { OP_IMREG, dx_reg } ++#define zAX { OP_IMREG, z_mode_ax_reg } ++#define indirDX { OP_IMREG, indir_dx_reg } ++ ++#define Sw { OP_SEG, w_mode } ++#define Sv { OP_SEG, v_mode } ++#define Ap { OP_DIR, 0 } ++#define Ob { OP_OFF64, b_mode } ++#define Ov { OP_OFF64, v_mode } ++#define Xb { OP_DSreg, eSI_reg } ++#define Xv { OP_DSreg, eSI_reg } ++#define Xz { OP_DSreg, eSI_reg } ++#define Yb { OP_ESreg, eDI_reg } ++#define Yv { OP_ESreg, eDI_reg } ++#define DSBX { OP_DSreg, eBX_reg } ++ ++#define es { OP_REG, es_reg } ++#define ss { OP_REG, ss_reg } ++#define cs { OP_REG, cs_reg } ++#define ds { OP_REG, ds_reg } ++#define fs { OP_REG, fs_reg } ++#define gs { OP_REG, gs_reg } ++ ++#define MX { OP_MMX, 0 } ++#define XM { OP_XMM, 0 } ++#define EM { OP_EM, v_mode } ++#define EMd { OP_EM, d_mode } ++#define EMx { OP_EM, x_mode } ++#define EXw { OP_EX, w_mode } ++#define EXd { OP_EX, d_mode } ++#define EXq { OP_EX, q_mode } ++#define EXx { OP_EX, x_mode } ++#define MS { OP_MS, v_mode } ++#define XS { OP_XS, v_mode } ++#define EMCq { OP_EMC, q_mode } ++#define MXC { OP_MXC, 0 } ++#define OPSUF { OP_3DNowSuffix, 0 } ++#define CMP { CMP_Fixup, 0 } ++#define XMM0 { XMM_Fixup, 0 } ++ ++/* Used handle "rep" prefix for string instructions. */ ++#define Xbr { REP_Fixup, eSI_reg } ++#define Xvr { REP_Fixup, eSI_reg } ++#define Ybr { REP_Fixup, eDI_reg } ++#define Yvr { REP_Fixup, eDI_reg } ++#define Yzr { REP_Fixup, eDI_reg } ++#define indirDXr { REP_Fixup, indir_dx_reg } ++#define ALr { REP_Fixup, al_reg } ++#define eAXr { REP_Fixup, eAX_reg } + +-#define cond_jump_flag NULL, cond_jump_mode +-#define loop_jcxz_flag NULL, loop_jcxz_mode ++#define cond_jump_flag { NULL, cond_jump_mode } ++#define loop_jcxz_flag { NULL, loop_jcxz_mode } + + /* bits in sizeflag */ + #define SUFFIX_ALWAYS 4 + #define AFLAG 2 + #define DFLAG 1 + +-#define b_mode 1 /* byte operand */ +-#define v_mode 2 /* operand size depends on prefixes */ +-#define w_mode 3 /* word operand */ +-#define d_mode 4 /* double word operand */ +-#define q_mode 5 /* quad word operand */ +-#define x_mode 6 +-#define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */ +-#define cond_jump_mode 8 +-#define loop_jcxz_mode 9 +-#define dq_mode 10 /* operand size depends on REX prefixes. */ +- +-#define es_reg 100 +-#define cs_reg 101 +-#define ss_reg 102 +-#define ds_reg 103 +-#define fs_reg 104 +-#define gs_reg 105 +- +-#define eAX_reg 108 +-#define eCX_reg 109 +-#define eDX_reg 110 +-#define eBX_reg 111 +-#define eSP_reg 112 +-#define eBP_reg 113 +-#define eSI_reg 114 +-#define eDI_reg 115 +- +-#define al_reg 116 +-#define cl_reg 117 +-#define dl_reg 118 +-#define bl_reg 119 +-#define ah_reg 120 +-#define ch_reg 121 +-#define dh_reg 122 +-#define bh_reg 123 +- +-#define ax_reg 124 +-#define cx_reg 125 +-#define dx_reg 126 +-#define bx_reg 127 +-#define sp_reg 128 +-#define bp_reg 129 +-#define si_reg 130 +-#define di_reg 131 +- +-#define rAX_reg 132 +-#define rCX_reg 133 +-#define rDX_reg 134 +-#define rBX_reg 135 +-#define rSP_reg 136 +-#define rBP_reg 137 +-#define rSI_reg 138 +-#define rDI_reg 139 +- +-#define indir_dx_reg 150 +- +-#define FLOATCODE 1 +-#define USE_GROUPS 2 +-#define USE_PREFIX_USER_TABLE 3 +-#define X86_64_SPECIAL 4 +- +-#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0 +- +-#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0 +-#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0 +-#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0 +-#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0 +-#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0 +-#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0 +-#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0 +-#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0 +-#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0 +-#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0 +-#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0 +-#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0 +-#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0 +-#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0 +-#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0 +-#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0 +-#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0 +-#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0 +-#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0 +-#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0 +-#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0 +-#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0 +-#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0 +- +-#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0 +-#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0 +-#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0 +-#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0 +-#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0 +-#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0 +-#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0 +-#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0 +-#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0 +-#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0 +-#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0 +-#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0 +-#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0 +-#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0 +-#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0 +-#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0 +-#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0 +-#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0 +-#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0 +-#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0 +-#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0 +-#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0 +-#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0 +-#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0 +-#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0 +-#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0 +-#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0 +-#define PREGRP27 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 27, NULL, 0 +-#define PREGRP28 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 28, NULL, 0 +-#define PREGRP29 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 29, NULL, 0 +-#define PREGRP30 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 30, NULL, 0 +-#define PREGRP31 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 31, NULL, 0 +-#define PREGRP32 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 32, NULL, 0 ++/* byte operand */ ++#define b_mode 1 ++/* operand size depends on prefixes */ ++#define v_mode (b_mode + 1) ++/* word operand */ ++#define w_mode (v_mode + 1) ++/* double word operand */ ++#define d_mode (w_mode + 1) ++/* quad word operand */ ++#define q_mode (d_mode + 1) ++/* ten-byte operand */ ++#define t_mode (q_mode + 1) ++/* 16-byte XMM operand */ ++#define x_mode (t_mode + 1) ++/* d_mode in 32bit, q_mode in 64bit mode. */ ++#define m_mode (x_mode + 1) ++/* pair of v_mode operands */ ++#define a_mode (m_mode + 1) ++#define cond_jump_mode (a_mode + 1) ++#define loop_jcxz_mode (cond_jump_mode + 1) ++/* operand size depends on REX prefixes. */ ++#define dq_mode (loop_jcxz_mode + 1) ++/* registers like dq_mode, memory like w_mode. */ ++#define dqw_mode (dq_mode + 1) ++/* 4- or 6-byte pointer operand */ ++#define f_mode (dqw_mode + 1) ++#define const_1_mode (f_mode + 1) ++/* v_mode for stack-related opcodes. */ ++#define stack_v_mode (const_1_mode + 1) ++/* non-quad operand size depends on prefixes */ ++#define z_mode (stack_v_mode + 1) ++/* 16-byte operand */ ++#define o_mode (z_mode + 1) ++/* registers like dq_mode, memory like b_mode. */ ++#define dqb_mode (o_mode + 1) ++/* registers like dq_mode, memory like d_mode. */ ++#define dqd_mode (dqb_mode + 1) ++ ++#define es_reg (dqd_mode + 1) ++#define cs_reg (es_reg + 1) ++#define ss_reg (cs_reg + 1) ++#define ds_reg (ss_reg + 1) ++#define fs_reg (ds_reg + 1) ++#define gs_reg (fs_reg + 1) ++ ++#define eAX_reg (gs_reg + 1) ++#define eCX_reg (eAX_reg + 1) ++#define eDX_reg (eCX_reg + 1) ++#define eBX_reg (eDX_reg + 1) ++#define eSP_reg (eBX_reg + 1) ++#define eBP_reg (eSP_reg + 1) ++#define eSI_reg (eBP_reg + 1) ++#define eDI_reg (eSI_reg + 1) ++ ++#define al_reg (eDI_reg + 1) ++#define cl_reg (al_reg + 1) ++#define dl_reg (cl_reg + 1) ++#define bl_reg (dl_reg + 1) ++#define ah_reg (bl_reg + 1) ++#define ch_reg (ah_reg + 1) ++#define dh_reg (ch_reg + 1) ++#define bh_reg (dh_reg + 1) ++ ++#define ax_reg (bh_reg + 1) ++#define cx_reg (ax_reg + 1) ++#define dx_reg (cx_reg + 1) ++#define bx_reg (dx_reg + 1) ++#define sp_reg (bx_reg + 1) ++#define bp_reg (sp_reg + 1) ++#define si_reg (bp_reg + 1) ++#define di_reg (si_reg + 1) ++ ++#define rAX_reg (di_reg + 1) ++#define rCX_reg (rAX_reg + 1) ++#define rDX_reg (rCX_reg + 1) ++#define rBX_reg (rDX_reg + 1) ++#define rSP_reg (rBX_reg + 1) ++#define rBP_reg (rSP_reg + 1) ++#define rSI_reg (rBP_reg + 1) ++#define rDI_reg (rSI_reg + 1) ++ ++#define z_mode_ax_reg (rDI_reg + 1) ++#define indir_dx_reg (z_mode_ax_reg + 1) ++ ++#define MAX_BYTEMODE indir_dx_reg ++ ++/* Flags that are OR'ed into the bytemode field to pass extra ++ information. */ ++#define DREX_OC1 0x10000 /* OC1 bit set */ ++#define DREX_NO_OC0 0x20000 /* OC0 bit not used */ ++#define DREX_MASK 0x40000 /* mask to delete */ ++ ++#if MAX_BYTEMODE >= DREX_OC1 ++#error MAX_BYTEMODE must be less than DREX_OC1 ++#endif + +-#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0 ++#define FLOATCODE 1 ++#define USE_REG_TABLE (FLOATCODE + 1) ++#define USE_MOD_TABLE (USE_REG_TABLE + 1) ++#define USE_RM_TABLE (USE_MOD_TABLE + 1) ++#define USE_PREFIX_TABLE (USE_RM_TABLE + 1) ++#define USE_X86_64_TABLE (USE_PREFIX_TABLE + 1) ++#define USE_3BYTE_TABLE (USE_X86_64_TABLE + 1) ++ ++#define FLOAT NULL, { { NULL, FLOATCODE } } ++ ++#define DIS386(T, I) NULL, { { NULL, (T)}, { NULL, (I) } } ++#define REG_TABLE(I) DIS386 (USE_REG_TABLE, (I)) ++#define MOD_TABLE(I) DIS386 (USE_MOD_TABLE, (I)) ++#define RM_TABLE(I) DIS386 (USE_RM_TABLE, (I)) ++#define PREFIX_TABLE(I) DIS386 (USE_PREFIX_TABLE, (I)) ++#define X86_64_TABLE(I) DIS386 (USE_X86_64_TABLE, (I)) ++#define THREE_BYTE_TABLE(I) DIS386 (USE_3BYTE_TABLE, (I)) ++ ++#define REG_80 0 ++#define REG_81 (REG_80 + 1) ++#define REG_82 (REG_81 + 1) ++#define REG_8F (REG_82 + 1) ++#define REG_C0 (REG_8F + 1) ++#define REG_C1 (REG_C0 + 1) ++#define REG_C6 (REG_C1 + 1) ++#define REG_C7 (REG_C6 + 1) ++#define REG_D0 (REG_C7 + 1) ++#define REG_D1 (REG_D0 + 1) ++#define REG_D2 (REG_D1 + 1) ++#define REG_D3 (REG_D2 + 1) ++#define REG_F6 (REG_D3 + 1) ++#define REG_F7 (REG_F6 + 1) ++#define REG_FE (REG_F7 + 1) ++#define REG_FF (REG_FE + 1) ++#define REG_0F00 (REG_FF + 1) ++#define REG_0F01 (REG_0F00 + 1) ++#define REG_0F0D (REG_0F01 + 1) ++#define REG_0F18 (REG_0F0D + 1) ++#define REG_0F71 (REG_0F18 + 1) ++#define REG_0F72 (REG_0F71 + 1) ++#define REG_0F73 (REG_0F72 + 1) ++#define REG_0FA6 (REG_0F73 + 1) ++#define REG_0FA7 (REG_0FA6 + 1) ++#define REG_0FAE (REG_0FA7 + 1) ++#define REG_0FBA (REG_0FAE + 1) ++#define REG_0FC7 (REG_0FBA + 1) ++ ++#define MOD_8D 0 ++#define MOD_0F01_REG_0 (MOD_8D + 1) ++#define MOD_0F01_REG_1 (MOD_0F01_REG_0 + 1) ++#define MOD_0F01_REG_2 (MOD_0F01_REG_1 + 1) ++#define MOD_0F01_REG_3 (MOD_0F01_REG_2 + 1) ++#define MOD_0F01_REG_7 (MOD_0F01_REG_3 + 1) ++#define MOD_0F12_PREFIX_0 (MOD_0F01_REG_7 + 1) ++#define MOD_0F13 (MOD_0F12_PREFIX_0 + 1) ++#define MOD_0F16_PREFIX_0 (MOD_0F13 + 1) ++#define MOD_0F17 (MOD_0F16_PREFIX_0 + 1) ++#define MOD_0F18_REG_0 (MOD_0F17 + 1) ++#define MOD_0F18_REG_1 (MOD_0F18_REG_0 + 1) ++#define MOD_0F18_REG_2 (MOD_0F18_REG_1 + 1) ++#define MOD_0F18_REG_3 (MOD_0F18_REG_2 + 1) ++#define MOD_0F20 (MOD_0F18_REG_3 + 1) ++#define MOD_0F21 (MOD_0F20 + 1) ++#define MOD_0F22 (MOD_0F21 + 1) ++#define MOD_0F23 (MOD_0F22 + 1) ++#define MOD_0F24 (MOD_0F23 + 1) ++#define MOD_0F26 (MOD_0F24 + 1) ++#define MOD_0F2B_PREFIX_0 (MOD_0F26 + 1) ++#define MOD_0F2B_PREFIX_1 (MOD_0F2B_PREFIX_0 + 1) ++#define MOD_0F2B_PREFIX_2 (MOD_0F2B_PREFIX_1 + 1) ++#define MOD_0F2B_PREFIX_3 (MOD_0F2B_PREFIX_2 + 1) ++#define MOD_0F51 (MOD_0F2B_PREFIX_3 + 1) ++#define MOD_0F71_REG_2 (MOD_0F51 + 1) ++#define MOD_0F71_REG_4 (MOD_0F71_REG_2 + 1) ++#define MOD_0F71_REG_6 (MOD_0F71_REG_4 + 1) ++#define MOD_0F72_REG_2 (MOD_0F71_REG_6 + 1) ++#define MOD_0F72_REG_4 (MOD_0F72_REG_2 + 1) ++#define MOD_0F72_REG_6 (MOD_0F72_REG_4 + 1) ++#define MOD_0F73_REG_2 (MOD_0F72_REG_6 + 1) ++#define MOD_0F73_REG_3 (MOD_0F73_REG_2 + 1) ++#define MOD_0F73_REG_6 (MOD_0F73_REG_3 + 1) ++#define MOD_0F73_REG_7 (MOD_0F73_REG_6 + 1) ++#define MOD_0FAE_REG_0 (MOD_0F73_REG_7 + 1) ++#define MOD_0FAE_REG_1 (MOD_0FAE_REG_0 + 1) ++#define MOD_0FAE_REG_2 (MOD_0FAE_REG_1 + 1) ++#define MOD_0FAE_REG_3 (MOD_0FAE_REG_2 + 1) ++#define MOD_0FAE_REG_4 (MOD_0FAE_REG_3 + 1) ++#define MOD_0FAE_REG_5 (MOD_0FAE_REG_4 + 1) ++#define MOD_0FAE_REG_6 (MOD_0FAE_REG_5 + 1) ++#define MOD_0FAE_REG_7 (MOD_0FAE_REG_6 + 1) ++#define MOD_0FB2 (MOD_0FAE_REG_7 + 1) ++#define MOD_0FB4 (MOD_0FB2 + 1) ++#define MOD_0FB5 (MOD_0FB4 + 1) ++#define MOD_0FC7_REG_6 (MOD_0FB5 + 1) ++#define MOD_0FC7_REG_7 (MOD_0FC7_REG_6 + 1) ++#define MOD_0FD7 (MOD_0FC7_REG_7 + 1) ++#define MOD_0FE7_PREFIX_2 (MOD_0FD7 + 1) ++#define MOD_0FF0_PREFIX_3 (MOD_0FE7_PREFIX_2 + 1) ++#define MOD_0F382A_PREFIX_2 (MOD_0FF0_PREFIX_3 + 1) ++#define MOD_62_32BIT (MOD_0F382A_PREFIX_2 + 1) ++#define MOD_C4_32BIT (MOD_62_32BIT + 1) ++#define MOD_C5_32BIT (MOD_C4_32BIT + 1) ++ ++#define RM_0F01_REG_0 0 ++#define RM_0F01_REG_1 (RM_0F01_REG_0 + 1) ++#define RM_0F01_REG_2 (RM_0F01_REG_1 + 1) ++#define RM_0F01_REG_3 (RM_0F01_REG_2 + 1) ++#define RM_0F01_REG_7 (RM_0F01_REG_3 + 1) ++#define RM_0FAE_REG_5 (RM_0F01_REG_7 + 1) ++#define RM_0FAE_REG_6 (RM_0FAE_REG_5 + 1) ++#define RM_0FAE_REG_7 (RM_0FAE_REG_6 + 1) ++ ++#define PREFIX_90 0 ++#define PREFIX_0F10 (PREFIX_90 + 1) ++#define PREFIX_0F11 (PREFIX_0F10 + 1) ++#define PREFIX_0F12 (PREFIX_0F11 + 1) ++#define PREFIX_0F16 (PREFIX_0F12 + 1) ++#define PREFIX_0F2A (PREFIX_0F16 + 1) ++#define PREFIX_0F2B (PREFIX_0F2A + 1) ++#define PREFIX_0F2C (PREFIX_0F2B + 1) ++#define PREFIX_0F2D (PREFIX_0F2C + 1) ++#define PREFIX_0F2E (PREFIX_0F2D + 1) ++#define PREFIX_0F2F (PREFIX_0F2E + 1) ++#define PREFIX_0F51 (PREFIX_0F2F + 1) ++#define PREFIX_0F52 (PREFIX_0F51 + 1) ++#define PREFIX_0F53 (PREFIX_0F52 + 1) ++#define PREFIX_0F58 (PREFIX_0F53 + 1) ++#define PREFIX_0F59 (PREFIX_0F58 + 1) ++#define PREFIX_0F5A (PREFIX_0F59 + 1) ++#define PREFIX_0F5B (PREFIX_0F5A + 1) ++#define PREFIX_0F5C (PREFIX_0F5B + 1) ++#define PREFIX_0F5D (PREFIX_0F5C + 1) ++#define PREFIX_0F5E (PREFIX_0F5D + 1) ++#define PREFIX_0F5F (PREFIX_0F5E + 1) ++#define PREFIX_0F60 (PREFIX_0F5F + 1) ++#define PREFIX_0F61 (PREFIX_0F60 + 1) ++#define PREFIX_0F62 (PREFIX_0F61 + 1) ++#define PREFIX_0F6C (PREFIX_0F62 + 1) ++#define PREFIX_0F6D (PREFIX_0F6C + 1) ++#define PREFIX_0F6F (PREFIX_0F6D + 1) ++#define PREFIX_0F70 (PREFIX_0F6F + 1) ++#define PREFIX_0F73_REG_3 (PREFIX_0F70 + 1) ++#define PREFIX_0F73_REG_7 (PREFIX_0F73_REG_3 + 1) ++#define PREFIX_0F78 (PREFIX_0F73_REG_7 + 1) ++#define PREFIX_0F79 (PREFIX_0F78 + 1) ++#define PREFIX_0F7C (PREFIX_0F79 + 1) ++#define PREFIX_0F7D (PREFIX_0F7C + 1) ++#define PREFIX_0F7E (PREFIX_0F7D + 1) ++#define PREFIX_0F7F (PREFIX_0F7E + 1) ++#define PREFIX_0FB8 (PREFIX_0F7F + 1) ++#define PREFIX_0FBD (PREFIX_0FB8 + 1) ++#define PREFIX_0FC2 (PREFIX_0FBD + 1) ++#define PREFIX_0FC3 (PREFIX_0FC2 + 1) ++#define PREFIX_0FC7_REG_6 (PREFIX_0FC3 + 1) ++#define PREFIX_0FD0 (PREFIX_0FC7_REG_6 + 1) ++#define PREFIX_0FD6 (PREFIX_0FD0 + 1) ++#define PREFIX_0FE6 (PREFIX_0FD6 + 1) ++#define PREFIX_0FE7 (PREFIX_0FE6 + 1) ++#define PREFIX_0FF0 (PREFIX_0FE7 + 1) ++#define PREFIX_0FF7 (PREFIX_0FF0 + 1) ++#define PREFIX_0F3810 (PREFIX_0FF7 + 1) ++#define PREFIX_0F3814 (PREFIX_0F3810 + 1) ++#define PREFIX_0F3815 (PREFIX_0F3814 + 1) ++#define PREFIX_0F3817 (PREFIX_0F3815 + 1) ++#define PREFIX_0F3820 (PREFIX_0F3817 + 1) ++#define PREFIX_0F3821 (PREFIX_0F3820 + 1) ++#define PREFIX_0F3822 (PREFIX_0F3821 + 1) ++#define PREFIX_0F3823 (PREFIX_0F3822 + 1) ++#define PREFIX_0F3824 (PREFIX_0F3823 + 1) ++#define PREFIX_0F3825 (PREFIX_0F3824 + 1) ++#define PREFIX_0F3828 (PREFIX_0F3825 + 1) ++#define PREFIX_0F3829 (PREFIX_0F3828 + 1) ++#define PREFIX_0F382A (PREFIX_0F3829 + 1) ++#define PREFIX_0F382B (PREFIX_0F382A + 1) ++#define PREFIX_0F3830 (PREFIX_0F382B + 1) ++#define PREFIX_0F3831 (PREFIX_0F3830 + 1) ++#define PREFIX_0F3832 (PREFIX_0F3831 + 1) ++#define PREFIX_0F3833 (PREFIX_0F3832 + 1) ++#define PREFIX_0F3834 (PREFIX_0F3833 + 1) ++#define PREFIX_0F3835 (PREFIX_0F3834 + 1) ++#define PREFIX_0F3837 (PREFIX_0F3835 + 1) ++#define PREFIX_0F3838 (PREFIX_0F3837 + 1) ++#define PREFIX_0F3839 (PREFIX_0F3838 + 1) ++#define PREFIX_0F383A (PREFIX_0F3839 + 1) ++#define PREFIX_0F383B (PREFIX_0F383A + 1) ++#define PREFIX_0F383C (PREFIX_0F383B + 1) ++#define PREFIX_0F383D (PREFIX_0F383C + 1) ++#define PREFIX_0F383E (PREFIX_0F383D + 1) ++#define PREFIX_0F383F (PREFIX_0F383E + 1) ++#define PREFIX_0F3840 (PREFIX_0F383F + 1) ++#define PREFIX_0F3841 (PREFIX_0F3840 + 1) ++#define PREFIX_0F38F0 (PREFIX_0F3841 + 1) ++#define PREFIX_0F38F1 (PREFIX_0F38F0 + 1) ++#define PREFIX_0F3A08 (PREFIX_0F38F1 + 1) ++#define PREFIX_0F3A09 (PREFIX_0F3A08 + 1) ++#define PREFIX_0F3A0A (PREFIX_0F3A09 + 1) ++#define PREFIX_0F3A0B (PREFIX_0F3A0A + 1) ++#define PREFIX_0F3A0C (PREFIX_0F3A0B + 1) ++#define PREFIX_0F3A0D (PREFIX_0F3A0C + 1) ++#define PREFIX_0F3A0E (PREFIX_0F3A0D + 1) ++#define PREFIX_0F3A14 (PREFIX_0F3A0E + 1) ++#define PREFIX_0F3A15 (PREFIX_0F3A14 + 1) ++#define PREFIX_0F3A16 (PREFIX_0F3A15 + 1) ++#define PREFIX_0F3A17 (PREFIX_0F3A16 + 1) ++#define PREFIX_0F3A20 (PREFIX_0F3A17 + 1) ++#define PREFIX_0F3A21 (PREFIX_0F3A20 + 1) ++#define PREFIX_0F3A22 (PREFIX_0F3A21 + 1) ++#define PREFIX_0F3A40 (PREFIX_0F3A22 + 1) ++#define PREFIX_0F3A41 (PREFIX_0F3A40 + 1) ++#define PREFIX_0F3A42 (PREFIX_0F3A41 + 1) ++#define PREFIX_0F3A60 (PREFIX_0F3A42 + 1) ++#define PREFIX_0F3A61 (PREFIX_0F3A60 + 1) ++#define PREFIX_0F3A62 (PREFIX_0F3A61 + 1) ++#define PREFIX_0F3A63 (PREFIX_0F3A62 + 1) ++ ++#define X86_64_06 0 ++#define X86_64_07 (X86_64_06 + 1) ++#define X86_64_0D (X86_64_07 + 1) ++#define X86_64_16 (X86_64_0D + 1) ++#define X86_64_17 (X86_64_16 + 1) ++#define X86_64_1E (X86_64_17 + 1) ++#define X86_64_1F (X86_64_1E + 1) ++#define X86_64_27 (X86_64_1F + 1) ++#define X86_64_2F (X86_64_27 + 1) ++#define X86_64_37 (X86_64_2F + 1) ++#define X86_64_3F (X86_64_37 + 1) ++#define X86_64_60 (X86_64_3F + 1) ++#define X86_64_61 (X86_64_60 + 1) ++#define X86_64_62 (X86_64_61 + 1) ++#define X86_64_63 (X86_64_62 + 1) ++#define X86_64_6D (X86_64_63 + 1) ++#define X86_64_6F (X86_64_6D + 1) ++#define X86_64_9A (X86_64_6F + 1) ++#define X86_64_C4 (X86_64_9A + 1) ++#define X86_64_C5 (X86_64_C4 + 1) ++#define X86_64_CE (X86_64_C5 + 1) ++#define X86_64_D4 (X86_64_CE + 1) ++#define X86_64_D5 (X86_64_D4 + 1) ++#define X86_64_EA (X86_64_D5 + 1) ++#define X86_64_0F01_REG_0 (X86_64_EA + 1) ++#define X86_64_0F01_REG_1 (X86_64_0F01_REG_0 + 1) ++#define X86_64_0F01_REG_2 (X86_64_0F01_REG_1 + 1) ++#define X86_64_0F01_REG_3 (X86_64_0F01_REG_2 + 1) ++ ++#define THREE_BYTE_0F24 0 ++#define THREE_BYTE_0F25 (THREE_BYTE_0F24 + 1) ++#define THREE_BYTE_0F38 (THREE_BYTE_0F25 + 1) ++#define THREE_BYTE_0F3A (THREE_BYTE_0F38 + 1) ++#define THREE_BYTE_0F7A (THREE_BYTE_0F3A + 1) ++#define THREE_BYTE_0F7B (THREE_BYTE_0F7A + 1) + + typedef void (*op_rtn) (int bytemode, int sizeflag); + + struct dis386 { + const char *name; +- op_rtn op1; +- int bytemode1; +- op_rtn op2; +- int bytemode2; +- op_rtn op3; +- int bytemode3; ++ struct ++ { ++ op_rtn rtn; ++ int bytemode; ++ } op[MAX_OPERANDS]; + }; + + /* Upper case letters in the instruction names here are macros. + 'A' => print 'b' if no register operands or suffix_always is true + 'B' => print 'b' if suffix_always is true ++ 'C' => print 's' or 'l' ('w' or 'd' in Intel mode) depending on operand ++ size prefix ++ 'D' => print 'w' if no register operands or 'w', 'l' or 'q', if ++ suffix_always is true + 'E' => print 'e' if 32-bit form of jcxz + 'F' => print 'w' or 'l' depending on address size prefix (loop insns) ++ 'G' => print 'w' or 'l' depending on operand size prefix (i/o insns) + 'H' => print ",pt" or ",pn" branch hint ++ 'I' => honor following macro letter even in Intel mode (implemented only ++ for some of the macro letters) ++ 'J' => print 'l' ++ 'K' => print 'd' or 'q' if rex prefix is present. + 'L' => print 'l' if suffix_always is true ++ 'M' => print 'r' if intel_mnemonic is false. + 'N' => print 'n' if instruction has no wait "prefix" +- 'O' => print 'd', or 'o' ++ 'O' => print 'd' or 'o' (or 'q' in Intel mode) + 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix, +- . or suffix_always is true. print 'q' if rex prefix is present. +- 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always +- . is true +- 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode) ++ or suffix_always is true. print 'q' if rex prefix is present. ++ 'Q' => print 'w', 'l' or 'q' for memory operand or suffix_always ++ is true ++ 'R' => print 'w', 'l' or 'q' ('d' for 'l' and 'e' in Intel mode) + 'S' => print 'w', 'l' or 'q' if suffix_always is true + 'T' => print 'q' in 64bit mode and behave as 'P' otherwise + 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise ++ 'V' => print 'q' in 64bit mode and behave as 'S' otherwise ++ 'W' => print 'b', 'w' or 'l' ('d' in Intel mode) + 'X' => print 's', 'd' depending on data16 prefix (for XMM) +- 'W' => print 'b' or 'w' ("w" or "de" in intel mode) +- 'Y' => 'q' if instruction has an REX 64bit overwrite prefix ++ 'Y' => 'q' if instruction has an REX 64bit overwrite prefix and ++ suffix_always is true. ++ 'Z' => print 'q' in 64bit mode and behave as 'L' otherwise ++ '!' => change condition from true to false or from false to true. ++ '%' => add 1 upper case letter to the macro. ++ ++ 2 upper case letter macros: ++ 'LQ' => print 'l' ('d' in Intel mode) or 'q' for memory operand ++ or suffix_always is true + + Many of the above letters print nothing in Intel mode. See "putop" + for the details. + + Braces '{' and '}', and vertical bars '|', indicate alternative +- mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel +- modes. In cases where there are only two alternatives, the X86_64 +- instruction is reserved, and "(bad)" is printed. +-*/ ++ mnemonic strings for AT&T and Intel. */ + + static const struct dis386 dis386[] = { + /* 00 */ +- { "addB", Eb, Gb, XX }, +- { "addS", Ev, Gv, XX }, +- { "addB", Gb, Eb, XX }, +- { "addS", Gv, Ev, XX }, +- { "addB", AL, Ib, XX }, +- { "addS", eAX, Iv, XX }, +- { "push{T|}", es, XX, XX }, +- { "pop{T|}", es, XX, XX }, ++ { "addB", { Eb, Gb } }, ++ { "addS", { Ev, Gv } }, ++ { "addB", { Gb, Eb } }, ++ { "addS", { Gv, Ev } }, ++ { "addB", { AL, Ib } }, ++ { "addS", { eAX, Iv } }, ++ { X86_64_TABLE (X86_64_06) }, ++ { X86_64_TABLE (X86_64_07) }, + /* 08 */ +- { "orB", Eb, Gb, XX }, +- { "orS", Ev, Gv, XX }, +- { "orB", Gb, Eb, XX }, +- { "orS", Gv, Ev, XX }, +- { "orB", AL, Ib, XX }, +- { "orS", eAX, Iv, XX }, +- { "push{T|}", cs, XX, XX }, +- { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */ ++ { "orB", { Eb, Gb } }, ++ { "orS", { Ev, Gv } }, ++ { "orB", { Gb, Eb } }, ++ { "orS", { Gv, Ev } }, ++ { "orB", { AL, Ib } }, ++ { "orS", { eAX, Iv } }, ++ { X86_64_TABLE (X86_64_0D) }, ++ { "(bad)", { XX } }, /* 0x0f extended opcode escape */ + /* 10 */ +- { "adcB", Eb, Gb, XX }, +- { "adcS", Ev, Gv, XX }, +- { "adcB", Gb, Eb, XX }, +- { "adcS", Gv, Ev, XX }, +- { "adcB", AL, Ib, XX }, +- { "adcS", eAX, Iv, XX }, +- { "push{T|}", ss, XX, XX }, +- { "popT|}", ss, XX, XX }, ++ { "adcB", { Eb, Gb } }, ++ { "adcS", { Ev, Gv } }, ++ { "adcB", { Gb, Eb } }, ++ { "adcS", { Gv, Ev } }, ++ { "adcB", { AL, Ib } }, ++ { "adcS", { eAX, Iv } }, ++ { X86_64_TABLE (X86_64_16) }, ++ { X86_64_TABLE (X86_64_17) }, + /* 18 */ +- { "sbbB", Eb, Gb, XX }, +- { "sbbS", Ev, Gv, XX }, +- { "sbbB", Gb, Eb, XX }, +- { "sbbS", Gv, Ev, XX }, +- { "sbbB", AL, Ib, XX }, +- { "sbbS", eAX, Iv, XX }, +- { "push{T|}", ds, XX, XX }, +- { "pop{T|}", ds, XX, XX }, ++ { "sbbB", { Eb, Gb } }, ++ { "sbbS", { Ev, Gv } }, ++ { "sbbB", { Gb, Eb } }, ++ { "sbbS", { Gv, Ev } }, ++ { "sbbB", { AL, Ib } }, ++ { "sbbS", { eAX, Iv } }, ++ { X86_64_TABLE (X86_64_1E) }, ++ { X86_64_TABLE (X86_64_1F) }, + /* 20 */ +- { "andB", Eb, Gb, XX }, +- { "andS", Ev, Gv, XX }, +- { "andB", Gb, Eb, XX }, +- { "andS", Gv, Ev, XX }, +- { "andB", AL, Ib, XX }, +- { "andS", eAX, Iv, XX }, +- { "(bad)", XX, XX, XX }, /* SEG ES prefix */ +- { "daa{|}", XX, XX, XX }, ++ { "andB", { Eb, Gb } }, ++ { "andS", { Ev, Gv } }, ++ { "andB", { Gb, Eb } }, ++ { "andS", { Gv, Ev } }, ++ { "andB", { AL, Ib } }, ++ { "andS", { eAX, Iv } }, ++ { "(bad)", { XX } }, /* SEG ES prefix */ ++ { X86_64_TABLE (X86_64_27) }, + /* 28 */ +- { "subB", Eb, Gb, XX }, +- { "subS", Ev, Gv, XX }, +- { "subB", Gb, Eb, XX }, +- { "subS", Gv, Ev, XX }, +- { "subB", AL, Ib, XX }, +- { "subS", eAX, Iv, XX }, +- { "(bad)", XX, XX, XX }, /* SEG CS prefix */ +- { "das{|}", XX, XX, XX }, ++ { "subB", { Eb, Gb } }, ++ { "subS", { Ev, Gv } }, ++ { "subB", { Gb, Eb } }, ++ { "subS", { Gv, Ev } }, ++ { "subB", { AL, Ib } }, ++ { "subS", { eAX, Iv } }, ++ { "(bad)", { XX } }, /* SEG CS prefix */ ++ { X86_64_TABLE (X86_64_2F) }, + /* 30 */ +- { "xorB", Eb, Gb, XX }, +- { "xorS", Ev, Gv, XX }, +- { "xorB", Gb, Eb, XX }, +- { "xorS", Gv, Ev, XX }, +- { "xorB", AL, Ib, XX }, +- { "xorS", eAX, Iv, XX }, +- { "(bad)", XX, XX, XX }, /* SEG SS prefix */ +- { "aaa{|}", XX, XX, XX }, ++ { "xorB", { Eb, Gb } }, ++ { "xorS", { Ev, Gv } }, ++ { "xorB", { Gb, Eb } }, ++ { "xorS", { Gv, Ev } }, ++ { "xorB", { AL, Ib } }, ++ { "xorS", { eAX, Iv } }, ++ { "(bad)", { XX } }, /* SEG SS prefix */ ++ { X86_64_TABLE (X86_64_37) }, + /* 38 */ +- { "cmpB", Eb, Gb, XX }, +- { "cmpS", Ev, Gv, XX }, +- { "cmpB", Gb, Eb, XX }, +- { "cmpS", Gv, Ev, XX }, +- { "cmpB", AL, Ib, XX }, +- { "cmpS", eAX, Iv, XX }, +- { "(bad)", XX, XX, XX }, /* SEG DS prefix */ +- { "aas{|}", XX, XX, XX }, ++ { "cmpB", { Eb, Gb } }, ++ { "cmpS", { Ev, Gv } }, ++ { "cmpB", { Gb, Eb } }, ++ { "cmpS", { Gv, Ev } }, ++ { "cmpB", { AL, Ib } }, ++ { "cmpS", { eAX, Iv } }, ++ { "(bad)", { XX } }, /* SEG DS prefix */ ++ { X86_64_TABLE (X86_64_3F) }, + /* 40 */ +- { "inc{S|}", RMeAX, XX, XX }, +- { "inc{S|}", RMeCX, XX, XX }, +- { "inc{S|}", RMeDX, XX, XX }, +- { "inc{S|}", RMeBX, XX, XX }, +- { "inc{S|}", RMeSP, XX, XX }, +- { "inc{S|}", RMeBP, XX, XX }, +- { "inc{S|}", RMeSI, XX, XX }, +- { "inc{S|}", RMeDI, XX, XX }, ++ { "inc{S|}", { RMeAX } }, ++ { "inc{S|}", { RMeCX } }, ++ { "inc{S|}", { RMeDX } }, ++ { "inc{S|}", { RMeBX } }, ++ { "inc{S|}", { RMeSP } }, ++ { "inc{S|}", { RMeBP } }, ++ { "inc{S|}", { RMeSI } }, ++ { "inc{S|}", { RMeDI } }, + /* 48 */ +- { "dec{S|}", RMeAX, XX, XX }, +- { "dec{S|}", RMeCX, XX, XX }, +- { "dec{S|}", RMeDX, XX, XX }, +- { "dec{S|}", RMeBX, XX, XX }, +- { "dec{S|}", RMeSP, XX, XX }, +- { "dec{S|}", RMeBP, XX, XX }, +- { "dec{S|}", RMeSI, XX, XX }, +- { "dec{S|}", RMeDI, XX, XX }, ++ { "dec{S|}", { RMeAX } }, ++ { "dec{S|}", { RMeCX } }, ++ { "dec{S|}", { RMeDX } }, ++ { "dec{S|}", { RMeBX } }, ++ { "dec{S|}", { RMeSP } }, ++ { "dec{S|}", { RMeBP } }, ++ { "dec{S|}", { RMeSI } }, ++ { "dec{S|}", { RMeDI } }, + /* 50 */ +- { "pushS", RMrAX, XX, XX }, +- { "pushS", RMrCX, XX, XX }, +- { "pushS", RMrDX, XX, XX }, +- { "pushS", RMrBX, XX, XX }, +- { "pushS", RMrSP, XX, XX }, +- { "pushS", RMrBP, XX, XX }, +- { "pushS", RMrSI, XX, XX }, +- { "pushS", RMrDI, XX, XX }, ++ { "pushV", { RMrAX } }, ++ { "pushV", { RMrCX } }, ++ { "pushV", { RMrDX } }, ++ { "pushV", { RMrBX } }, ++ { "pushV", { RMrSP } }, ++ { "pushV", { RMrBP } }, ++ { "pushV", { RMrSI } }, ++ { "pushV", { RMrDI } }, + /* 58 */ +- { "popS", RMrAX, XX, XX }, +- { "popS", RMrCX, XX, XX }, +- { "popS", RMrDX, XX, XX }, +- { "popS", RMrBX, XX, XX }, +- { "popS", RMrSP, XX, XX }, +- { "popS", RMrBP, XX, XX }, +- { "popS", RMrSI, XX, XX }, +- { "popS", RMrDI, XX, XX }, ++ { "popV", { RMrAX } }, ++ { "popV", { RMrCX } }, ++ { "popV", { RMrDX } }, ++ { "popV", { RMrBX } }, ++ { "popV", { RMrSP } }, ++ { "popV", { RMrBP } }, ++ { "popV", { RMrSI } }, ++ { "popV", { RMrDI } }, + /* 60 */ +- { "pusha{P|}", XX, XX, XX }, +- { "popa{P|}", XX, XX, XX }, +- { "bound{S|}", Gv, Ma, XX }, +- { X86_64_0 }, +- { "(bad)", XX, XX, XX }, /* seg fs */ +- { "(bad)", XX, XX, XX }, /* seg gs */ +- { "(bad)", XX, XX, XX }, /* op size prefix */ +- { "(bad)", XX, XX, XX }, /* adr size prefix */ ++ { X86_64_TABLE (X86_64_60) }, ++ { X86_64_TABLE (X86_64_61) }, ++ { X86_64_TABLE (X86_64_62) }, ++ { X86_64_TABLE (X86_64_63) }, ++ { "(bad)", { XX } }, /* seg fs */ ++ { "(bad)", { XX } }, /* seg gs */ ++ { "(bad)", { XX } }, /* op size prefix */ ++ { "(bad)", { XX } }, /* adr size prefix */ + /* 68 */ +- { "pushT", Iq, XX, XX }, +- { "imulS", Gv, Ev, Iv }, +- { "pushT", sIb, XX, XX }, +- { "imulS", Gv, Ev, sIb }, +- { "ins{b||b|}", Yb, indirDX, XX }, +- { "ins{R||R|}", Yv, indirDX, XX }, +- { "outs{b||b|}", indirDX, Xb, XX }, +- { "outs{R||R|}", indirDX, Xv, XX }, ++ { "pushT", { Iq } }, ++ { "imulS", { Gv, Ev, Iv } }, ++ { "pushT", { sIb } }, ++ { "imulS", { Gv, Ev, sIb } }, ++ { "ins{b|}", { Ybr, indirDX } }, ++ { X86_64_TABLE (X86_64_6D) }, ++ { "outs{b|}", { indirDXr, Xb } }, ++ { X86_64_TABLE (X86_64_6F) }, + /* 70 */ +- { "joH", Jb, XX, cond_jump_flag }, +- { "jnoH", Jb, XX, cond_jump_flag }, +- { "jbH", Jb, XX, cond_jump_flag }, +- { "jaeH", Jb, XX, cond_jump_flag }, +- { "jeH", Jb, XX, cond_jump_flag }, +- { "jneH", Jb, XX, cond_jump_flag }, +- { "jbeH", Jb, XX, cond_jump_flag }, +- { "jaH", Jb, XX, cond_jump_flag }, ++ { "joH", { Jb, XX, cond_jump_flag } }, ++ { "jnoH", { Jb, XX, cond_jump_flag } }, ++ { "jbH", { Jb, XX, cond_jump_flag } }, ++ { "jaeH", { Jb, XX, cond_jump_flag } }, ++ { "jeH", { Jb, XX, cond_jump_flag } }, ++ { "jneH", { Jb, XX, cond_jump_flag } }, ++ { "jbeH", { Jb, XX, cond_jump_flag } }, ++ { "jaH", { Jb, XX, cond_jump_flag } }, + /* 78 */ +- { "jsH", Jb, XX, cond_jump_flag }, +- { "jnsH", Jb, XX, cond_jump_flag }, +- { "jpH", Jb, XX, cond_jump_flag }, +- { "jnpH", Jb, XX, cond_jump_flag }, +- { "jlH", Jb, XX, cond_jump_flag }, +- { "jgeH", Jb, XX, cond_jump_flag }, +- { "jleH", Jb, XX, cond_jump_flag }, +- { "jgH", Jb, XX, cond_jump_flag }, ++ { "jsH", { Jb, XX, cond_jump_flag } }, ++ { "jnsH", { Jb, XX, cond_jump_flag } }, ++ { "jpH", { Jb, XX, cond_jump_flag } }, ++ { "jnpH", { Jb, XX, cond_jump_flag } }, ++ { "jlH", { Jb, XX, cond_jump_flag } }, ++ { "jgeH", { Jb, XX, cond_jump_flag } }, ++ { "jleH", { Jb, XX, cond_jump_flag } }, ++ { "jgH", { Jb, XX, cond_jump_flag } }, + /* 80 */ +- { GRP1b }, +- { GRP1S }, +- { "(bad)", XX, XX, XX }, +- { GRP1Ss }, +- { "testB", Eb, Gb, XX }, +- { "testS", Ev, Gv, XX }, +- { "xchgB", Eb, Gb, XX }, +- { "xchgS", Ev, Gv, XX }, ++ { REG_TABLE (REG_80) }, ++ { REG_TABLE (REG_81) }, ++ { "(bad)", { XX } }, ++ { REG_TABLE (REG_82) }, ++ { "testB", { Eb, Gb } }, ++ { "testS", { Ev, Gv } }, ++ { "xchgB", { Eb, Gb } }, ++ { "xchgS", { Ev, Gv } }, + /* 88 */ +- { "movB", Eb, Gb, XX }, +- { "movS", Ev, Gv, XX }, +- { "movB", Gb, Eb, XX }, +- { "movS", Gv, Ev, XX }, +- { "movQ", Ev, Sw, XX }, +- { "leaS", Gv, M, XX }, +- { "movQ", Sw, Ev, XX }, +- { "popU", Ev, XX, XX }, ++ { "movB", { Eb, Gb } }, ++ { "movS", { Ev, Gv } }, ++ { "movB", { Gb, Eb } }, ++ { "movS", { Gv, Ev } }, ++ { "movD", { Sv, Sw } }, ++ { MOD_TABLE (MOD_8D) }, ++ { "movD", { Sw, Sv } }, ++ { REG_TABLE (REG_8F) }, + /* 90 */ +- { "nop", XX, XX, XX }, +- /* FIXME: NOP with REPz prefix is called PAUSE. */ +- { "xchgS", RMeCX, eAX, XX }, +- { "xchgS", RMeDX, eAX, XX }, +- { "xchgS", RMeBX, eAX, XX }, +- { "xchgS", RMeSP, eAX, XX }, +- { "xchgS", RMeBP, eAX, XX }, +- { "xchgS", RMeSI, eAX, XX }, +- { "xchgS", RMeDI, eAX, XX }, ++ { PREFIX_TABLE (PREFIX_90) }, ++ { "xchgS", { RMeCX, eAX } }, ++ { "xchgS", { RMeDX, eAX } }, ++ { "xchgS", { RMeBX, eAX } }, ++ { "xchgS", { RMeSP, eAX } }, ++ { "xchgS", { RMeBP, eAX } }, ++ { "xchgS", { RMeSI, eAX } }, ++ { "xchgS", { RMeDI, eAX } }, + /* 98 */ +- { "cW{tR||tR|}", XX, XX, XX }, +- { "cR{tO||tO|}", XX, XX, XX }, +- { "lcall{T|}", Ap, XX, XX }, +- { "(bad)", XX, XX, XX }, /* fwait */ +- { "pushfT", XX, XX, XX }, +- { "popfT", XX, XX, XX }, +- { "sahf{|}", XX, XX, XX }, +- { "lahf{|}", XX, XX, XX }, ++ { "cW{t|}R", { XX } }, ++ { "cR{t|}O", { XX } }, ++ { X86_64_TABLE (X86_64_9A) }, ++ { "(bad)", { XX } }, /* fwait */ ++ { "pushfT", { XX } }, ++ { "popfT", { XX } }, ++ { "sahf", { XX } }, ++ { "lahf", { XX } }, + /* a0 */ +- { "movB", AL, Ob64, XX }, +- { "movS", eAX, Ov64, XX }, +- { "movB", Ob64, AL, XX }, +- { "movS", Ov64, eAX, XX }, +- { "movs{b||b|}", Yb, Xb, XX }, +- { "movs{R||R|}", Yv, Xv, XX }, +- { "cmps{b||b|}", Xb, Yb, XX }, +- { "cmps{R||R|}", Xv, Yv, XX }, ++ { "movB", { AL, Ob } }, ++ { "movS", { eAX, Ov } }, ++ { "movB", { Ob, AL } }, ++ { "movS", { Ov, eAX } }, ++ { "movs{b|}", { Ybr, Xb } }, ++ { "movs{R|}", { Yvr, Xv } }, ++ { "cmps{b|}", { Xb, Yb } }, ++ { "cmps{R|}", { Xv, Yv } }, + /* a8 */ +- { "testB", AL, Ib, XX }, +- { "testS", eAX, Iv, XX }, +- { "stosB", Yb, AL, XX }, +- { "stosS", Yv, eAX, XX }, +- { "lodsB", AL, Xb, XX }, +- { "lodsS", eAX, Xv, XX }, +- { "scasB", AL, Yb, XX }, +- { "scasS", eAX, Yv, XX }, ++ { "testB", { AL, Ib } }, ++ { "testS", { eAX, Iv } }, ++ { "stosB", { Ybr, AL } }, ++ { "stosS", { Yvr, eAX } }, ++ { "lodsB", { ALr, Xb } }, ++ { "lodsS", { eAXr, Xv } }, ++ { "scasB", { AL, Yb } }, ++ { "scasS", { eAX, Yv } }, + /* b0 */ +- { "movB", RMAL, Ib, XX }, +- { "movB", RMCL, Ib, XX }, +- { "movB", RMDL, Ib, XX }, +- { "movB", RMBL, Ib, XX }, +- { "movB", RMAH, Ib, XX }, +- { "movB", RMCH, Ib, XX }, +- { "movB", RMDH, Ib, XX }, +- { "movB", RMBH, Ib, XX }, ++ { "movB", { RMAL, Ib } }, ++ { "movB", { RMCL, Ib } }, ++ { "movB", { RMDL, Ib } }, ++ { "movB", { RMBL, Ib } }, ++ { "movB", { RMAH, Ib } }, ++ { "movB", { RMCH, Ib } }, ++ { "movB", { RMDH, Ib } }, ++ { "movB", { RMBH, Ib } }, + /* b8 */ +- { "movS", RMeAX, Iv64, XX }, +- { "movS", RMeCX, Iv64, XX }, +- { "movS", RMeDX, Iv64, XX }, +- { "movS", RMeBX, Iv64, XX }, +- { "movS", RMeSP, Iv64, XX }, +- { "movS", RMeBP, Iv64, XX }, +- { "movS", RMeSI, Iv64, XX }, +- { "movS", RMeDI, Iv64, XX }, ++ { "movS", { RMeAX, Iv64 } }, ++ { "movS", { RMeCX, Iv64 } }, ++ { "movS", { RMeDX, Iv64 } }, ++ { "movS", { RMeBX, Iv64 } }, ++ { "movS", { RMeSP, Iv64 } }, ++ { "movS", { RMeBP, Iv64 } }, ++ { "movS", { RMeSI, Iv64 } }, ++ { "movS", { RMeDI, Iv64 } }, + /* c0 */ +- { GRP2b }, +- { GRP2S }, +- { "retT", Iw, XX, XX }, +- { "retT", XX, XX, XX }, +- { "les{S|}", Gv, Mp, XX }, +- { "ldsS", Gv, Mp, XX }, +- { "movA", Eb, Ib, XX }, +- { "movQ", Ev, Iv, XX }, ++ { REG_TABLE (REG_C0) }, ++ { REG_TABLE (REG_C1) }, ++ { "retT", { Iw } }, ++ { "retT", { XX } }, ++ { X86_64_TABLE (X86_64_C4) }, ++ { X86_64_TABLE (X86_64_C5) }, ++ { REG_TABLE (REG_C6) }, ++ { REG_TABLE (REG_C7) }, + /* c8 */ +- { "enterT", Iw, Ib, XX }, +- { "leaveT", XX, XX, XX }, +- { "lretP", Iw, XX, XX }, +- { "lretP", XX, XX, XX }, +- { "int3", XX, XX, XX }, +- { "int", Ib, XX, XX }, +- { "into{|}", XX, XX, XX }, +- { "iretP", XX, XX, XX }, ++ { "enterT", { Iw, Ib } }, ++ { "leaveT", { XX } }, ++ { "lretP", { Iw } }, ++ { "lretP", { XX } }, ++ { "int3", { XX } }, ++ { "int", { Ib } }, ++ { X86_64_TABLE (X86_64_CE) }, ++ { "iretP", { XX } }, + /* d0 */ +- { GRP2b_one }, +- { GRP2S_one }, +- { GRP2b_cl }, +- { GRP2S_cl }, +- { "aam{|}", sIb, XX, XX }, +- { "aad{|}", sIb, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "xlat", DSBX, XX, XX }, ++ { REG_TABLE (REG_D0) }, ++ { REG_TABLE (REG_D1) }, ++ { REG_TABLE (REG_D2) }, ++ { REG_TABLE (REG_D3) }, ++ { X86_64_TABLE (X86_64_D4) }, ++ { X86_64_TABLE (X86_64_D5) }, ++ { "(bad)", { XX } }, ++ { "xlat", { DSBX } }, + /* d8 */ + { FLOAT }, + { FLOAT }, +@@ -722,332 +1022,332 @@ static const struct dis386 dis386[] = { + { FLOAT }, + { FLOAT }, + /* e0 */ +- { "loopneFH", Jb, XX, loop_jcxz_flag }, +- { "loopeFH", Jb, XX, loop_jcxz_flag }, +- { "loopFH", Jb, XX, loop_jcxz_flag }, +- { "jEcxzH", Jb, XX, loop_jcxz_flag }, +- { "inB", AL, Ib, XX }, +- { "inS", eAX, Ib, XX }, +- { "outB", Ib, AL, XX }, +- { "outS", Ib, eAX, XX }, ++ { "loopneFH", { Jb, XX, loop_jcxz_flag } }, ++ { "loopeFH", { Jb, XX, loop_jcxz_flag } }, ++ { "loopFH", { Jb, XX, loop_jcxz_flag } }, ++ { "jEcxzH", { Jb, XX, loop_jcxz_flag } }, ++ { "inB", { AL, Ib } }, ++ { "inG", { zAX, Ib } }, ++ { "outB", { Ib, AL } }, ++ { "outG", { Ib, zAX } }, + /* e8 */ +- { "callT", Jv, XX, XX }, +- { "jmpT", Jv, XX, XX }, +- { "ljmp{T|}", Ap, XX, XX }, +- { "jmp", Jb, XX, XX }, +- { "inB", AL, indirDX, XX }, +- { "inS", eAX, indirDX, XX }, +- { "outB", indirDX, AL, XX }, +- { "outS", indirDX, eAX, XX }, ++ { "callT", { Jv } }, ++ { "jmpT", { Jv } }, ++ { X86_64_TABLE (X86_64_EA) }, ++ { "jmp", { Jb } }, ++ { "inB", { AL, indirDX } }, ++ { "inG", { zAX, indirDX } }, ++ { "outB", { indirDX, AL } }, ++ { "outG", { indirDX, zAX } }, + /* f0 */ +- { "(bad)", XX, XX, XX }, /* lock prefix */ +- { "icebp", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, /* repne */ +- { "(bad)", XX, XX, XX }, /* repz */ +- { "hlt", XX, XX, XX }, +- { "cmc", XX, XX, XX }, +- { GRP3b }, +- { GRP3S }, ++ { "(bad)", { XX } }, /* lock prefix */ ++ { "icebp", { XX } }, ++ { "(bad)", { XX } }, /* repne */ ++ { "(bad)", { XX } }, /* repz */ ++ { "hlt", { XX } }, ++ { "cmc", { XX } }, ++ { REG_TABLE (REG_F6) }, ++ { REG_TABLE (REG_F7) }, + /* f8 */ +- { "clc", XX, XX, XX }, +- { "stc", XX, XX, XX }, +- { "cli", XX, XX, XX }, +- { "sti", XX, XX, XX }, +- { "cld", XX, XX, XX }, +- { "std", XX, XX, XX }, +- { GRP4 }, +- { GRP5 }, ++ { "clc", { XX } }, ++ { "stc", { XX } }, ++ { "cli", { XX } }, ++ { "sti", { XX } }, ++ { "cld", { XX } }, ++ { "std", { XX } }, ++ { REG_TABLE (REG_FE) }, ++ { REG_TABLE (REG_FF) }, + }; + + static const struct dis386 dis386_twobyte[] = { + /* 00 */ +- { GRP6 }, +- { GRP7 }, +- { "larS", Gv, Ew, XX }, +- { "lslS", Gv, Ew, XX }, +- { "(bad)", XX, XX, XX }, +- { "syscall", XX, XX, XX }, +- { "clts", XX, XX, XX }, +- { "sysretP", XX, XX, XX }, ++ { REG_TABLE (REG_0F00 ) }, ++ { REG_TABLE (REG_0F01 ) }, ++ { "larS", { Gv, Ew } }, ++ { "lslS", { Gv, Ew } }, ++ { "(bad)", { XX } }, ++ { "syscall", { XX } }, ++ { "clts", { XX } }, ++ { "sysretP", { XX } }, + /* 08 */ +- { "invd", XX, XX, XX }, +- { "wbinvd", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "ud2a", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { GRPAMD }, +- { "femms", XX, XX, XX }, +- { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */ ++ { "invd", { XX } }, ++ { "wbinvd", { XX } }, ++ { "(bad)", { XX } }, ++ { "ud2a", { XX } }, ++ { "(bad)", { XX } }, ++ { REG_TABLE (REG_0F0D) }, ++ { "femms", { XX } }, ++ { "", { MX, EM, OPSUF } }, /* See OP_3DNowSuffix. */ + /* 10 */ +- { PREGRP8 }, +- { PREGRP9 }, +- { PREGRP30 }, +- { "movlpX", EX, XM, SIMD_Fixup, 'h' }, +- { "unpcklpX", XM, EX, XX }, +- { "unpckhpX", XM, EX, XX }, +- { PREGRP31 }, +- { "movhpX", EX, XM, SIMD_Fixup, 'l' }, ++ { PREFIX_TABLE (PREFIX_0F10) }, ++ { PREFIX_TABLE (PREFIX_0F11) }, ++ { PREFIX_TABLE (PREFIX_0F12) }, ++ { MOD_TABLE (MOD_0F13) }, ++ { "unpcklpX", { XM, EXx } }, ++ { "unpckhpX", { XM, EXx } }, ++ { PREFIX_TABLE (PREFIX_0F16) }, ++ { MOD_TABLE (MOD_0F17) }, + /* 18 */ +- { GRP14 }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, ++ { REG_TABLE (REG_0F18) }, ++ { "nopQ", { Ev } }, ++ { "nopQ", { Ev } }, ++ { "nopQ", { Ev } }, ++ { "nopQ", { Ev } }, ++ { "nopQ", { Ev } }, ++ { "nopQ", { Ev } }, ++ { "nopQ", { Ev } }, + /* 20 */ +- { "movL", Rm, Cm, XX }, +- { "movL", Rm, Dm, XX }, +- { "movL", Cm, Rm, XX }, +- { "movL", Dm, Rm, XX }, +- { "movL", Rd, Td, XX }, +- { "(bad)", XX, XX, XX }, +- { "movL", Td, Rd, XX }, +- { "(bad)", XX, XX, XX }, ++ { MOD_TABLE (MOD_0F20) }, ++ { MOD_TABLE (MOD_0F21) }, ++ { MOD_TABLE (MOD_0F22) }, ++ { MOD_TABLE (MOD_0F23) }, ++ { MOD_TABLE (MOD_0F24) }, ++ { THREE_BYTE_TABLE (THREE_BYTE_0F25) }, ++ { MOD_TABLE (MOD_0F26) }, ++ { "(bad)", { XX } }, + /* 28 */ +- { "movapX", XM, EX, XX }, +- { "movapX", EX, XM, XX }, +- { PREGRP2 }, +- { "movntpX", Ev, XM, XX }, +- { PREGRP4 }, +- { PREGRP3 }, +- { "ucomisX", XM,EX, XX }, +- { "comisX", XM,EX, XX }, ++ { "movapX", { XM, EXx } }, ++ { "movapX", { EXx, XM } }, ++ { PREFIX_TABLE (PREFIX_0F2A) }, ++ { PREFIX_TABLE (PREFIX_0F2B) }, ++ { PREFIX_TABLE (PREFIX_0F2C) }, ++ { PREFIX_TABLE (PREFIX_0F2D) }, ++ { PREFIX_TABLE (PREFIX_0F2E) }, ++ { PREFIX_TABLE (PREFIX_0F2F) }, + /* 30 */ +- { "wrmsr", XX, XX, XX }, +- { "rdtsc", XX, XX, XX }, +- { "rdmsr", XX, XX, XX }, +- { "rdpmc", XX, XX, XX }, +- { "sysenter", XX, XX, XX }, +- { "sysexit", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, ++ { "wrmsr", { XX } }, ++ { "rdtsc", { XX } }, ++ { "rdmsr", { XX } }, ++ { "rdpmc", { XX } }, ++ { "sysenter", { XX } }, ++ { "sysexit", { XX } }, ++ { "(bad)", { XX } }, ++ { "getsec", { XX } }, + /* 38 */ +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, ++ { THREE_BYTE_TABLE (THREE_BYTE_0F38) }, ++ { "(bad)", { XX } }, ++ { THREE_BYTE_TABLE (THREE_BYTE_0F3A) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, + /* 40 */ +- { "cmovo", Gv, Ev, XX }, +- { "cmovno", Gv, Ev, XX }, +- { "cmovb", Gv, Ev, XX }, +- { "cmovae", Gv, Ev, XX }, +- { "cmove", Gv, Ev, XX }, +- { "cmovne", Gv, Ev, XX }, +- { "cmovbe", Gv, Ev, XX }, +- { "cmova", Gv, Ev, XX }, ++ { "cmovo", { Gv, Ev } }, ++ { "cmovno", { Gv, Ev } }, ++ { "cmovb", { Gv, Ev } }, ++ { "cmovae", { Gv, Ev } }, ++ { "cmove", { Gv, Ev } }, ++ { "cmovne", { Gv, Ev } }, ++ { "cmovbe", { Gv, Ev } }, ++ { "cmova", { Gv, Ev } }, + /* 48 */ +- { "cmovs", Gv, Ev, XX }, +- { "cmovns", Gv, Ev, XX }, +- { "cmovp", Gv, Ev, XX }, +- { "cmovnp", Gv, Ev, XX }, +- { "cmovl", Gv, Ev, XX }, +- { "cmovge", Gv, Ev, XX }, +- { "cmovle", Gv, Ev, XX }, +- { "cmovg", Gv, Ev, XX }, ++ { "cmovs", { Gv, Ev } }, ++ { "cmovns", { Gv, Ev } }, ++ { "cmovp", { Gv, Ev } }, ++ { "cmovnp", { Gv, Ev } }, ++ { "cmovl", { Gv, Ev } }, ++ { "cmovge", { Gv, Ev } }, ++ { "cmovle", { Gv, Ev } }, ++ { "cmovg", { Gv, Ev } }, + /* 50 */ +- { "movmskpX", Gd, XS, XX }, +- { PREGRP13 }, +- { PREGRP12 }, +- { PREGRP11 }, +- { "andpX", XM, EX, XX }, +- { "andnpX", XM, EX, XX }, +- { "orpX", XM, EX, XX }, +- { "xorpX", XM, EX, XX }, ++ { MOD_TABLE (MOD_0F51) }, ++ { PREFIX_TABLE (PREFIX_0F51) }, ++ { PREFIX_TABLE (PREFIX_0F52) }, ++ { PREFIX_TABLE (PREFIX_0F53) }, ++ { "andpX", { XM, EXx } }, ++ { "andnpX", { XM, EXx } }, ++ { "orpX", { XM, EXx } }, ++ { "xorpX", { XM, EXx } }, + /* 58 */ +- { PREGRP0 }, +- { PREGRP10 }, +- { PREGRP17 }, +- { PREGRP16 }, +- { PREGRP14 }, +- { PREGRP7 }, +- { PREGRP5 }, +- { PREGRP6 }, ++ { PREFIX_TABLE (PREFIX_0F58) }, ++ { PREFIX_TABLE (PREFIX_0F59) }, ++ { PREFIX_TABLE (PREFIX_0F5A) }, ++ { PREFIX_TABLE (PREFIX_0F5B) }, ++ { PREFIX_TABLE (PREFIX_0F5C) }, ++ { PREFIX_TABLE (PREFIX_0F5D) }, ++ { PREFIX_TABLE (PREFIX_0F5E) }, ++ { PREFIX_TABLE (PREFIX_0F5F) }, + /* 60 */ +- { "punpcklbw", MX, EM, XX }, +- { "punpcklwd", MX, EM, XX }, +- { "punpckldq", MX, EM, XX }, +- { "packsswb", MX, EM, XX }, +- { "pcmpgtb", MX, EM, XX }, +- { "pcmpgtw", MX, EM, XX }, +- { "pcmpgtd", MX, EM, XX }, +- { "packuswb", MX, EM, XX }, ++ { PREFIX_TABLE (PREFIX_0F60) }, ++ { PREFIX_TABLE (PREFIX_0F61) }, ++ { PREFIX_TABLE (PREFIX_0F62) }, ++ { "packsswb", { MX, EM } }, ++ { "pcmpgtb", { MX, EM } }, ++ { "pcmpgtw", { MX, EM } }, ++ { "pcmpgtd", { MX, EM } }, ++ { "packuswb", { MX, EM } }, + /* 68 */ +- { "punpckhbw", MX, EM, XX }, +- { "punpckhwd", MX, EM, XX }, +- { "punpckhdq", MX, EM, XX }, +- { "packssdw", MX, EM, XX }, +- { PREGRP26 }, +- { PREGRP24 }, +- { "movd", MX, Edq, XX }, +- { PREGRP19 }, ++ { "punpckhbw", { MX, EM } }, ++ { "punpckhwd", { MX, EM } }, ++ { "punpckhdq", { MX, EM } }, ++ { "packssdw", { MX, EM } }, ++ { PREFIX_TABLE (PREFIX_0F6C) }, ++ { PREFIX_TABLE (PREFIX_0F6D) }, ++ { "movK", { MX, Edq } }, ++ { PREFIX_TABLE (PREFIX_0F6F) }, + /* 70 */ +- { PREGRP22 }, +- { GRP10 }, +- { GRP11 }, +- { GRP12 }, +- { "pcmpeqb", MX, EM, XX }, +- { "pcmpeqw", MX, EM, XX }, +- { "pcmpeqd", MX, EM, XX }, +- { "emms", XX, XX, XX }, ++ { PREFIX_TABLE (PREFIX_0F70) }, ++ { REG_TABLE (REG_0F71) }, ++ { REG_TABLE (REG_0F72) }, ++ { REG_TABLE (REG_0F73) }, ++ { "pcmpeqb", { MX, EM } }, ++ { "pcmpeqw", { MX, EM } }, ++ { "pcmpeqd", { MX, EM } }, ++ { "emms", { XX } }, + /* 78 */ +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { PREGRP28 }, +- { PREGRP29 }, +- { PREGRP23 }, +- { PREGRP20 }, ++ { PREFIX_TABLE (PREFIX_0F78) }, ++ { PREFIX_TABLE (PREFIX_0F79) }, ++ { THREE_BYTE_TABLE (THREE_BYTE_0F7A) }, ++ { THREE_BYTE_TABLE (THREE_BYTE_0F7B) }, ++ { PREFIX_TABLE (PREFIX_0F7C) }, ++ { PREFIX_TABLE (PREFIX_0F7D) }, ++ { PREFIX_TABLE (PREFIX_0F7E) }, ++ { PREFIX_TABLE (PREFIX_0F7F) }, + /* 80 */ +- { "joH", Jv, XX, cond_jump_flag }, +- { "jnoH", Jv, XX, cond_jump_flag }, +- { "jbH", Jv, XX, cond_jump_flag }, +- { "jaeH", Jv, XX, cond_jump_flag }, +- { "jeH", Jv, XX, cond_jump_flag }, +- { "jneH", Jv, XX, cond_jump_flag }, +- { "jbeH", Jv, XX, cond_jump_flag }, +- { "jaH", Jv, XX, cond_jump_flag }, ++ { "joH", { Jv, XX, cond_jump_flag } }, ++ { "jnoH", { Jv, XX, cond_jump_flag } }, ++ { "jbH", { Jv, XX, cond_jump_flag } }, ++ { "jaeH", { Jv, XX, cond_jump_flag } }, ++ { "jeH", { Jv, XX, cond_jump_flag } }, ++ { "jneH", { Jv, XX, cond_jump_flag } }, ++ { "jbeH", { Jv, XX, cond_jump_flag } }, ++ { "jaH", { Jv, XX, cond_jump_flag } }, + /* 88 */ +- { "jsH", Jv, XX, cond_jump_flag }, +- { "jnsH", Jv, XX, cond_jump_flag }, +- { "jpH", Jv, XX, cond_jump_flag }, +- { "jnpH", Jv, XX, cond_jump_flag }, +- { "jlH", Jv, XX, cond_jump_flag }, +- { "jgeH", Jv, XX, cond_jump_flag }, +- { "jleH", Jv, XX, cond_jump_flag }, +- { "jgH", Jv, XX, cond_jump_flag }, ++ { "jsH", { Jv, XX, cond_jump_flag } }, ++ { "jnsH", { Jv, XX, cond_jump_flag } }, ++ { "jpH", { Jv, XX, cond_jump_flag } }, ++ { "jnpH", { Jv, XX, cond_jump_flag } }, ++ { "jlH", { Jv, XX, cond_jump_flag } }, ++ { "jgeH", { Jv, XX, cond_jump_flag } }, ++ { "jleH", { Jv, XX, cond_jump_flag } }, ++ { "jgH", { Jv, XX, cond_jump_flag } }, + /* 90 */ +- { "seto", Eb, XX, XX }, +- { "setno", Eb, XX, XX }, +- { "setb", Eb, XX, XX }, +- { "setae", Eb, XX, XX }, +- { "sete", Eb, XX, XX }, +- { "setne", Eb, XX, XX }, +- { "setbe", Eb, XX, XX }, +- { "seta", Eb, XX, XX }, ++ { "seto", { Eb } }, ++ { "setno", { Eb } }, ++ { "setb", { Eb } }, ++ { "setae", { Eb } }, ++ { "sete", { Eb } }, ++ { "setne", { Eb } }, ++ { "setbe", { Eb } }, ++ { "seta", { Eb } }, + /* 98 */ +- { "sets", Eb, XX, XX }, +- { "setns", Eb, XX, XX }, +- { "setp", Eb, XX, XX }, +- { "setnp", Eb, XX, XX }, +- { "setl", Eb, XX, XX }, +- { "setge", Eb, XX, XX }, +- { "setle", Eb, XX, XX }, +- { "setg", Eb, XX, XX }, ++ { "sets", { Eb } }, ++ { "setns", { Eb } }, ++ { "setp", { Eb } }, ++ { "setnp", { Eb } }, ++ { "setl", { Eb } }, ++ { "setge", { Eb } }, ++ { "setle", { Eb } }, ++ { "setg", { Eb } }, + /* a0 */ +- { "pushT", fs, XX, XX }, +- { "popT", fs, XX, XX }, +- { "cpuid", XX, XX, XX }, +- { "btS", Ev, Gv, XX }, +- { "shldS", Ev, Gv, Ib }, +- { "shldS", Ev, Gv, CL }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, ++ { "pushT", { fs } }, ++ { "popT", { fs } }, ++ { "cpuid", { XX } }, ++ { "btS", { Ev, Gv } }, ++ { "shldS", { Ev, Gv, Ib } }, ++ { "shldS", { Ev, Gv, CL } }, ++ { REG_TABLE (REG_0FA6) }, ++ { REG_TABLE (REG_0FA7) }, + /* a8 */ +- { "pushT", gs, XX, XX }, +- { "popT", gs, XX, XX }, +- { "rsm", XX, XX, XX }, +- { "btsS", Ev, Gv, XX }, +- { "shrdS", Ev, Gv, Ib }, +- { "shrdS", Ev, Gv, CL }, +- { GRP13 }, +- { "imulS", Gv, Ev, XX }, ++ { "pushT", { gs } }, ++ { "popT", { gs } }, ++ { "rsm", { XX } }, ++ { "btsS", { Ev, Gv } }, ++ { "shrdS", { Ev, Gv, Ib } }, ++ { "shrdS", { Ev, Gv, CL } }, ++ { REG_TABLE (REG_0FAE) }, ++ { "imulS", { Gv, Ev } }, + /* b0 */ +- { "cmpxchgB", Eb, Gb, XX }, +- { "cmpxchgS", Ev, Gv, XX }, +- { "lssS", Gv, Mp, XX }, +- { "btrS", Ev, Gv, XX }, +- { "lfsS", Gv, Mp, XX }, +- { "lgsS", Gv, Mp, XX }, +- { "movz{bR|x|bR|x}", Gv, Eb, XX }, +- { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */ ++ { "cmpxchgB", { Eb, Gb } }, ++ { "cmpxchgS", { Ev, Gv } }, ++ { MOD_TABLE (MOD_0FB2) }, ++ { "btrS", { Ev, Gv } }, ++ { MOD_TABLE (MOD_0FB4) }, ++ { MOD_TABLE (MOD_0FB5) }, ++ { "movz{bR|x}", { Gv, Eb } }, ++ { "movz{wR|x}", { Gv, Ew } }, /* yes, there really is movzww ! */ + /* b8 */ +- { "(bad)", XX, XX, XX }, +- { "ud2b", XX, XX, XX }, +- { GRP8 }, +- { "btcS", Ev, Gv, XX }, +- { "bsfS", Gv, Ev, XX }, +- { "bsrS", Gv, Ev, XX }, +- { "movs{bR|x|bR|x}", Gv, Eb, XX }, +- { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */ ++ { PREFIX_TABLE (PREFIX_0FB8) }, ++ { "ud2b", { XX } }, ++ { REG_TABLE (REG_0FBA) }, ++ { "btcS", { Ev, Gv } }, ++ { "bsfS", { Gv, Ev } }, ++ { PREFIX_TABLE (PREFIX_0FBD) }, ++ { "movs{bR|x}", { Gv, Eb } }, ++ { "movs{wR|x}", { Gv, Ew } }, /* yes, there really is movsww ! */ + /* c0 */ +- { "xaddB", Eb, Gb, XX }, +- { "xaddS", Ev, Gv, XX }, +- { PREGRP1 }, +- { "movntiS", Ev, Gv, XX }, +- { "pinsrw", MX, Ed, Ib }, +- { "pextrw", Gd, MS, Ib }, +- { "shufpX", XM, EX, Ib }, +- { GRP9 }, ++ { "xaddB", { Eb, Gb } }, ++ { "xaddS", { Ev, Gv } }, ++ { PREFIX_TABLE (PREFIX_0FC2) }, ++ { PREFIX_TABLE (PREFIX_0FC3) }, ++ { "pinsrw", { MX, Edqw, Ib } }, ++ { "pextrw", { Gdq, MS, Ib } }, ++ { "shufpX", { XM, EXx, Ib } }, ++ { REG_TABLE (REG_0FC7) }, + /* c8 */ +- { "bswap", RMeAX, XX, XX }, +- { "bswap", RMeCX, XX, XX }, +- { "bswap", RMeDX, XX, XX }, +- { "bswap", RMeBX, XX, XX }, +- { "bswap", RMeSP, XX, XX }, +- { "bswap", RMeBP, XX, XX }, +- { "bswap", RMeSI, XX, XX }, +- { "bswap", RMeDI, XX, XX }, ++ { "bswap", { RMeAX } }, ++ { "bswap", { RMeCX } }, ++ { "bswap", { RMeDX } }, ++ { "bswap", { RMeBX } }, ++ { "bswap", { RMeSP } }, ++ { "bswap", { RMeBP } }, ++ { "bswap", { RMeSI } }, ++ { "bswap", { RMeDI } }, + /* d0 */ +- { PREGRP27 }, +- { "psrlw", MX, EM, XX }, +- { "psrld", MX, EM, XX }, +- { "psrlq", MX, EM, XX }, +- { "paddq", MX, EM, XX }, +- { "pmullw", MX, EM, XX }, +- { PREGRP21 }, +- { "pmovmskb", Gd, MS, XX }, ++ { PREFIX_TABLE (PREFIX_0FD0) }, ++ { "psrlw", { MX, EM } }, ++ { "psrld", { MX, EM } }, ++ { "psrlq", { MX, EM } }, ++ { "paddq", { MX, EM } }, ++ { "pmullw", { MX, EM } }, ++ { PREFIX_TABLE (PREFIX_0FD6) }, ++ { MOD_TABLE (MOD_0FD7) }, + /* d8 */ +- { "psubusb", MX, EM, XX }, +- { "psubusw", MX, EM, XX }, +- { "pminub", MX, EM, XX }, +- { "pand", MX, EM, XX }, +- { "paddusb", MX, EM, XX }, +- { "paddusw", MX, EM, XX }, +- { "pmaxub", MX, EM, XX }, +- { "pandn", MX, EM, XX }, ++ { "psubusb", { MX, EM } }, ++ { "psubusw", { MX, EM } }, ++ { "pminub", { MX, EM } }, ++ { "pand", { MX, EM } }, ++ { "paddusb", { MX, EM } }, ++ { "paddusw", { MX, EM } }, ++ { "pmaxub", { MX, EM } }, ++ { "pandn", { MX, EM } }, + /* e0 */ +- { "pavgb", MX, EM, XX }, +- { "psraw", MX, EM, XX }, +- { "psrad", MX, EM, XX }, +- { "pavgw", MX, EM, XX }, +- { "pmulhuw", MX, EM, XX }, +- { "pmulhw", MX, EM, XX }, +- { PREGRP15 }, +- { PREGRP25 }, ++ { "pavgb", { MX, EM } }, ++ { "psraw", { MX, EM } }, ++ { "psrad", { MX, EM } }, ++ { "pavgw", { MX, EM } }, ++ { "pmulhuw", { MX, EM } }, ++ { "pmulhw", { MX, EM } }, ++ { PREFIX_TABLE (PREFIX_0FE6) }, ++ { PREFIX_TABLE (PREFIX_0FE7) }, + /* e8 */ +- { "psubsb", MX, EM, XX }, +- { "psubsw", MX, EM, XX }, +- { "pminsw", MX, EM, XX }, +- { "por", MX, EM, XX }, +- { "paddsb", MX, EM, XX }, +- { "paddsw", MX, EM, XX }, +- { "pmaxsw", MX, EM, XX }, +- { "pxor", MX, EM, XX }, ++ { "psubsb", { MX, EM } }, ++ { "psubsw", { MX, EM } }, ++ { "pminsw", { MX, EM } }, ++ { "por", { MX, EM } }, ++ { "paddsb", { MX, EM } }, ++ { "paddsw", { MX, EM } }, ++ { "pmaxsw", { MX, EM } }, ++ { "pxor", { MX, EM } }, + /* f0 */ +- { PREGRP32 }, +- { "psllw", MX, EM, XX }, +- { "pslld", MX, EM, XX }, +- { "psllq", MX, EM, XX }, +- { "pmuludq", MX, EM, XX }, +- { "pmaddwd", MX, EM, XX }, +- { "psadbw", MX, EM, XX }, +- { PREGRP18 }, ++ { PREFIX_TABLE (PREFIX_0FF0) }, ++ { "psllw", { MX, EM } }, ++ { "pslld", { MX, EM } }, ++ { "psllq", { MX, EM } }, ++ { "pmuludq", { MX, EM } }, ++ { "pmaddwd", { MX, EM } }, ++ { "psadbw", { MX, EM } }, ++ { PREFIX_TABLE (PREFIX_0FF7) }, + /* f8 */ +- { "psubb", MX, EM, XX }, +- { "psubw", MX, EM, XX }, +- { "psubd", MX, EM, XX }, +- { "psubq", MX, EM, XX }, +- { "paddb", MX, EM, XX }, +- { "paddw", MX, EM, XX }, +- { "paddd", MX, EM, XX }, +- { "(bad)", XX, XX, XX } ++ { "psubb", { MX, EM } }, ++ { "psubw", { MX, EM } }, ++ { "psubd", { MX, EM } }, ++ { "psubq", { MX, EM } }, ++ { "paddb", { MX, EM } }, ++ { "paddw", { MX, EM } }, ++ { "paddd", { MX, EM } }, ++ { "(bad)", { XX } }, + }; + + static const unsigned char onebyte_has_modrm[256] = { +@@ -1077,17 +1377,17 @@ static const unsigned char twobyte_has_m + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + /* ------------------------------- */ + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */ +- /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */ +- /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */ +- /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ ++ /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */ ++ /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */ ++ /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */ + /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */ + /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */ + /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */ +- /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1, /* 7f */ ++ /* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */ + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ + /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */ +- /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */ +- /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */ ++ /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */ ++ /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */ + /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */ + /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */ + /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */ +@@ -1096,39 +1396,25 @@ static const unsigned char twobyte_has_m + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ + }; + +-static const unsigned char twobyte_uses_SSE_prefix[256] = { +- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +- /* ------------------------------- */ +- /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */ +- /* 10 */ 1,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0, /* 1f */ +- /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */ +- /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */ +- /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */ +- /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */ +- /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */ +- /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, /* 7f */ +- /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */ +- /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */ +- /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */ +- /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */ +- /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */ +- /* d0 */ 1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */ +- /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */ +- /* f0 */ 1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */ +- /* ------------------------------- */ +- /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */ +-}; +- + static char obuf[100]; + static char *obufp; + static char scratchbuf[100]; + static unsigned char *start_codep; + static unsigned char *insn_codep; + static unsigned char *codep; ++static const char *lock_prefix; ++static const char *data_prefix; ++static const char *addr_prefix; ++static const char *repz_prefix; ++static const char *repnz_prefix; + static disassemble_info *the_info; +-static int mod; +-static int rm; +-static int reg; ++static struct ++ { ++ int mod; ++ int reg; ++ int rm; ++ } ++modrm; + static unsigned char need_modrm; + + /* If we are accessing mod/rm/reg without need_modrm set, then the +@@ -1142,6 +1428,8 @@ static const char **names16; + static const char **names8; + static const char **names8rex; + static const char **names_seg; ++static const char *index64; ++static const char *index32; + static const char **index16; + + static const char *intel_names64[] = { +@@ -1166,6 +1454,8 @@ static const char *intel_names8rex[] = { + static const char *intel_names_seg[] = { + "es", "cs", "ss", "ds", "fs", "gs", "?", "?", + }; ++static const char *intel_index64 = "riz"; ++static const char *intel_index32 = "eiz"; + static const char *intel_index16[] = { + "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx" + }; +@@ -1192,717 +1482,3645 @@ static const char *att_names8rex[] = { + static const char *att_names_seg[] = { + "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?", + }; ++static const char *att_index64 = "%riz"; ++static const char *att_index32 = "%eiz"; + static const char *att_index16[] = { + "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx" + }; + +-static const struct dis386 grps[][8] = { +- /* GRP1b */ ++static const struct dis386 reg_table[][8] = { ++ /* REG_80 */ + { +- { "addA", Eb, Ib, XX }, +- { "orA", Eb, Ib, XX }, +- { "adcA", Eb, Ib, XX }, +- { "sbbA", Eb, Ib, XX }, +- { "andA", Eb, Ib, XX }, +- { "subA", Eb, Ib, XX }, +- { "xorA", Eb, Ib, XX }, +- { "cmpA", Eb, Ib, XX } +- }, +- /* GRP1S */ +- { +- { "addQ", Ev, Iv, XX }, +- { "orQ", Ev, Iv, XX }, +- { "adcQ", Ev, Iv, XX }, +- { "sbbQ", Ev, Iv, XX }, +- { "andQ", Ev, Iv, XX }, +- { "subQ", Ev, Iv, XX }, +- { "xorQ", Ev, Iv, XX }, +- { "cmpQ", Ev, Iv, XX } +- }, +- /* GRP1Ss */ +- { +- { "addQ", Ev, sIb, XX }, +- { "orQ", Ev, sIb, XX }, +- { "adcQ", Ev, sIb, XX }, +- { "sbbQ", Ev, sIb, XX }, +- { "andQ", Ev, sIb, XX }, +- { "subQ", Ev, sIb, XX }, +- { "xorQ", Ev, sIb, XX }, +- { "cmpQ", Ev, sIb, XX } +- }, +- /* GRP2b */ +- { +- { "rolA", Eb, Ib, XX }, +- { "rorA", Eb, Ib, XX }, +- { "rclA", Eb, Ib, XX }, +- { "rcrA", Eb, Ib, XX }, +- { "shlA", Eb, Ib, XX }, +- { "shrA", Eb, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- { "sarA", Eb, Ib, XX }, +- }, +- /* GRP2S */ +- { +- { "rolQ", Ev, Ib, XX }, +- { "rorQ", Ev, Ib, XX }, +- { "rclQ", Ev, Ib, XX }, +- { "rcrQ", Ev, Ib, XX }, +- { "shlQ", Ev, Ib, XX }, +- { "shrQ", Ev, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- { "sarQ", Ev, Ib, XX }, +- }, +- /* GRP2b_one */ +- { +- { "rolA", Eb, XX, XX }, +- { "rorA", Eb, XX, XX }, +- { "rclA", Eb, XX, XX }, +- { "rcrA", Eb, XX, XX }, +- { "shlA", Eb, XX, XX }, +- { "shrA", Eb, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "sarA", Eb, XX, XX }, +- }, +- /* GRP2S_one */ +- { +- { "rolQ", Ev, XX, XX }, +- { "rorQ", Ev, XX, XX }, +- { "rclQ", Ev, XX, XX }, +- { "rcrQ", Ev, XX, XX }, +- { "shlQ", Ev, XX, XX }, +- { "shrQ", Ev, XX, XX }, +- { "(bad)", XX, XX, XX}, +- { "sarQ", Ev, XX, XX }, +- }, +- /* GRP2b_cl */ +- { +- { "rolA", Eb, CL, XX }, +- { "rorA", Eb, CL, XX }, +- { "rclA", Eb, CL, XX }, +- { "rcrA", Eb, CL, XX }, +- { "shlA", Eb, CL, XX }, +- { "shrA", Eb, CL, XX }, +- { "(bad)", XX, XX, XX }, +- { "sarA", Eb, CL, XX }, +- }, +- /* GRP2S_cl */ +- { +- { "rolQ", Ev, CL, XX }, +- { "rorQ", Ev, CL, XX }, +- { "rclQ", Ev, CL, XX }, +- { "rcrQ", Ev, CL, XX }, +- { "shlQ", Ev, CL, XX }, +- { "shrQ", Ev, CL, XX }, +- { "(bad)", XX, XX, XX }, +- { "sarQ", Ev, CL, XX } +- }, +- /* GRP3b */ +- { +- { "testA", Eb, Ib, XX }, +- { "(bad)", Eb, XX, XX }, +- { "notA", Eb, XX, XX }, +- { "negA", Eb, XX, XX }, +- { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */ +- { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */ +- { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */ +- { "idivA", Eb, XX, XX } /* and idiv for consistency. */ +- }, +- /* GRP3S */ +- { +- { "testQ", Ev, Iv, XX }, +- { "(bad)", XX, XX, XX }, +- { "notQ", Ev, XX, XX }, +- { "negQ", Ev, XX, XX }, +- { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */ +- { "imulQ", Ev, XX, XX }, +- { "divQ", Ev, XX, XX }, +- { "idivQ", Ev, XX, XX }, +- }, +- /* GRP4 */ +- { +- { "incA", Eb, XX, XX }, +- { "decA", Eb, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- }, +- /* GRP5 */ +- { +- { "incQ", Ev, XX, XX }, +- { "decQ", Ev, XX, XX }, +- { "callT", indirEv, XX, XX }, +- { "lcallT", indirEv, XX, XX }, +- { "jmpT", indirEv, XX, XX }, +- { "ljmpT", indirEv, XX, XX }, +- { "pushU", Ev, XX, XX }, +- { "(bad)", XX, XX, XX }, +- }, +- /* GRP6 */ +- { +- { "sldtQ", Ev, XX, XX }, +- { "strQ", Ev, XX, XX }, +- { "lldt", Ew, XX, XX }, +- { "ltr", Ew, XX, XX }, +- { "verr", Ew, XX, XX }, +- { "verw", Ew, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX } +- }, +- /* GRP7 */ +- { +- { "sgdtQ", M, XX, XX }, +- { "sidtQ", PNI_Fixup, 0, XX, XX }, +- { "lgdtQ", M, XX, XX }, +- { "lidtQ", M, XX, XX }, +- { "smswQ", Ev, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "lmsw", Ew, XX, XX }, +- { "invlpg", Ew, XX, XX }, +- }, +- /* GRP8 */ +- { +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "btQ", Ev, Ib, XX }, +- { "btsQ", Ev, Ib, XX }, +- { "btrQ", Ev, Ib, XX }, +- { "btcQ", Ev, Ib, XX }, +- }, +- /* GRP9 */ +- { +- { "(bad)", XX, XX, XX }, +- { "cmpxchg8b", Ev, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- }, +- /* GRP10 */ +- { +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "psrlw", MS, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- { "psraw", MS, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- { "psllw", MS, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- }, +- /* GRP11 */ +- { +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "psrld", MS, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- { "psrad", MS, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- { "pslld", MS, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- }, +- /* GRP12 */ +- { +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "psrlq", MS, Ib, XX }, +- { "psrldq", MS, Ib, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "psllq", MS, Ib, XX }, +- { "pslldq", MS, Ib, XX }, +- }, +- /* GRP13 */ +- { +- { "fxsave", Ev, XX, XX }, +- { "fxrstor", Ev, XX, XX }, +- { "ldmxcsr", Ev, XX, XX }, +- { "stmxcsr", Ev, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "lfence", None, XX, XX }, +- { "mfence", None, XX, XX }, +- { "sfence", None, XX, XX }, +- /* FIXME: the sfence with memory operand is clflush! */ +- }, +- /* GRP14 */ +- { +- { "prefetchnta", Ev, XX, XX }, +- { "prefetcht0", Ev, XX, XX }, +- { "prefetcht1", Ev, XX, XX }, +- { "prefetcht2", Ev, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- }, +- /* GRPAMD */ +- { +- { "prefetch", Eb, XX, XX }, +- { "prefetchw", Eb, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- } ++ { "addA", { Eb, Ib } }, ++ { "orA", { Eb, Ib } }, ++ { "adcA", { Eb, Ib } }, ++ { "sbbA", { Eb, Ib } }, ++ { "andA", { Eb, Ib } }, ++ { "subA", { Eb, Ib } }, ++ { "xorA", { Eb, Ib } }, ++ { "cmpA", { Eb, Ib } }, ++ }, ++ /* REG_81 */ ++ { ++ { "addQ", { Ev, Iv } }, ++ { "orQ", { Ev, Iv } }, ++ { "adcQ", { Ev, Iv } }, ++ { "sbbQ", { Ev, Iv } }, ++ { "andQ", { Ev, Iv } }, ++ { "subQ", { Ev, Iv } }, ++ { "xorQ", { Ev, Iv } }, ++ { "cmpQ", { Ev, Iv } }, ++ }, ++ /* REG_82 */ ++ { ++ { "addQ", { Ev, sIb } }, ++ { "orQ", { Ev, sIb } }, ++ { "adcQ", { Ev, sIb } }, ++ { "sbbQ", { Ev, sIb } }, ++ { "andQ", { Ev, sIb } }, ++ { "subQ", { Ev, sIb } }, ++ { "xorQ", { Ev, sIb } }, ++ { "cmpQ", { Ev, sIb } }, ++ }, ++ /* REG_8F */ ++ { ++ { "popU", { stackEv } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_C0 */ ++ { ++ { "rolA", { Eb, Ib } }, ++ { "rorA", { Eb, Ib } }, ++ { "rclA", { Eb, Ib } }, ++ { "rcrA", { Eb, Ib } }, ++ { "shlA", { Eb, Ib } }, ++ { "shrA", { Eb, Ib } }, ++ { "(bad)", { XX } }, ++ { "sarA", { Eb, Ib } }, ++ }, ++ /* REG_C1 */ ++ { ++ { "rolQ", { Ev, Ib } }, ++ { "rorQ", { Ev, Ib } }, ++ { "rclQ", { Ev, Ib } }, ++ { "rcrQ", { Ev, Ib } }, ++ { "shlQ", { Ev, Ib } }, ++ { "shrQ", { Ev, Ib } }, ++ { "(bad)", { XX } }, ++ { "sarQ", { Ev, Ib } }, ++ }, ++ /* REG_C6 */ ++ { ++ { "movA", { Eb, Ib } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_C7 */ ++ { ++ { "movQ", { Ev, Iv } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_D0 */ ++ { ++ { "rolA", { Eb, I1 } }, ++ { "rorA", { Eb, I1 } }, ++ { "rclA", { Eb, I1 } }, ++ { "rcrA", { Eb, I1 } }, ++ { "shlA", { Eb, I1 } }, ++ { "shrA", { Eb, I1 } }, ++ { "(bad)", { XX } }, ++ { "sarA", { Eb, I1 } }, ++ }, ++ /* REG_D1 */ ++ { ++ { "rolQ", { Ev, I1 } }, ++ { "rorQ", { Ev, I1 } }, ++ { "rclQ", { Ev, I1 } }, ++ { "rcrQ", { Ev, I1 } }, ++ { "shlQ", { Ev, I1 } }, ++ { "shrQ", { Ev, I1 } }, ++ { "(bad)", { XX } }, ++ { "sarQ", { Ev, I1 } }, ++ }, ++ /* REG_D2 */ ++ { ++ { "rolA", { Eb, CL } }, ++ { "rorA", { Eb, CL } }, ++ { "rclA", { Eb, CL } }, ++ { "rcrA", { Eb, CL } }, ++ { "shlA", { Eb, CL } }, ++ { "shrA", { Eb, CL } }, ++ { "(bad)", { XX } }, ++ { "sarA", { Eb, CL } }, ++ }, ++ /* REG_D3 */ ++ { ++ { "rolQ", { Ev, CL } }, ++ { "rorQ", { Ev, CL } }, ++ { "rclQ", { Ev, CL } }, ++ { "rcrQ", { Ev, CL } }, ++ { "shlQ", { Ev, CL } }, ++ { "shrQ", { Ev, CL } }, ++ { "(bad)", { XX } }, ++ { "sarQ", { Ev, CL } }, ++ }, ++ /* REG_F6 */ ++ { ++ { "testA", { Eb, Ib } }, ++ { "(bad)", { XX } }, ++ { "notA", { Eb } }, ++ { "negA", { Eb } }, ++ { "mulA", { Eb } }, /* Don't print the implicit %al register, */ ++ { "imulA", { Eb } }, /* to distinguish these opcodes from other */ ++ { "divA", { Eb } }, /* mul/imul opcodes. Do the same for div */ ++ { "idivA", { Eb } }, /* and idiv for consistency. */ ++ }, ++ /* REG_F7 */ ++ { ++ { "testQ", { Ev, Iv } }, ++ { "(bad)", { XX } }, ++ { "notQ", { Ev } }, ++ { "negQ", { Ev } }, ++ { "mulQ", { Ev } }, /* Don't print the implicit register. */ ++ { "imulQ", { Ev } }, ++ { "divQ", { Ev } }, ++ { "idivQ", { Ev } }, ++ }, ++ /* REG_FE */ ++ { ++ { "incA", { Eb } }, ++ { "decA", { Eb } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_FF */ ++ { ++ { "incQ", { Ev } }, ++ { "decQ", { Ev } }, ++ { "callT", { indirEv } }, ++ { "JcallT", { indirEp } }, ++ { "jmpT", { indirEv } }, ++ { "JjmpT", { indirEp } }, ++ { "pushU", { stackEv } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_0F00 */ ++ { ++ { "sldtD", { Sv } }, ++ { "strD", { Sv } }, ++ { "lldt", { Ew } }, ++ { "ltr", { Ew } }, ++ { "verr", { Ew } }, ++ { "verw", { Ew } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_0F01 */ ++ { ++ { MOD_TABLE (MOD_0F01_REG_0) }, ++ { MOD_TABLE (MOD_0F01_REG_1) }, ++ { MOD_TABLE (MOD_0F01_REG_2) }, ++ { MOD_TABLE (MOD_0F01_REG_3) }, ++ { "smswD", { Sv } }, ++ { "(bad)", { XX } }, ++ { "lmsw", { Ew } }, ++ { MOD_TABLE (MOD_0F01_REG_7) }, ++ }, ++ /* REG_0F0D */ ++ { ++ { "prefetch", { Eb } }, ++ { "prefetchw", { Eb } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_0F18 */ ++ { ++ { MOD_TABLE (MOD_0F18_REG_0) }, ++ { MOD_TABLE (MOD_0F18_REG_1) }, ++ { MOD_TABLE (MOD_0F18_REG_2) }, ++ { MOD_TABLE (MOD_0F18_REG_3) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_0F71 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F71_REG_2) }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F71_REG_4) }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F71_REG_6) }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_0F72 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F72_REG_2) }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F72_REG_4) }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F72_REG_6) }, ++ { "(bad)", { XX } }, ++ }, ++ /* REG_0F73 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F73_REG_2) }, ++ { MOD_TABLE (MOD_0F73_REG_3) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F73_REG_6) }, ++ { MOD_TABLE (MOD_0F73_REG_7) }, ++ }, ++ /* REG_0FA6 */ ++ { ++ { "montmul", { { OP_0f07, 0 } } }, ++ { "xsha1", { { OP_0f07, 0 } } }, ++ { "xsha256", { { OP_0f07, 0 } } }, ++ { "(bad)", { { OP_0f07, 0 } } }, ++ { "(bad)", { { OP_0f07, 0 } } }, ++ { "(bad)", { { OP_0f07, 0 } } }, ++ { "(bad)", { { OP_0f07, 0 } } }, ++ { "(bad)", { { OP_0f07, 0 } } }, ++ }, ++ /* REG_0FA7 */ ++ { ++ { "xstore-rng", { { OP_0f07, 0 } } }, ++ { "xcrypt-ecb", { { OP_0f07, 0 } } }, ++ { "xcrypt-cbc", { { OP_0f07, 0 } } }, ++ { "xcrypt-ctr", { { OP_0f07, 0 } } }, ++ { "xcrypt-cfb", { { OP_0f07, 0 } } }, ++ { "xcrypt-ofb", { { OP_0f07, 0 } } }, ++ { "(bad)", { { OP_0f07, 0 } } }, ++ { "(bad)", { { OP_0f07, 0 } } }, ++ }, ++ /* REG_0FAE */ ++ { ++ { MOD_TABLE (MOD_0FAE_REG_0) }, ++ { MOD_TABLE (MOD_0FAE_REG_1) }, ++ { MOD_TABLE (MOD_0FAE_REG_2) }, ++ { MOD_TABLE (MOD_0FAE_REG_3) }, ++ { MOD_TABLE (MOD_0FAE_REG_4) }, ++ { MOD_TABLE (MOD_0FAE_REG_5) }, ++ { MOD_TABLE (MOD_0FAE_REG_6) }, ++ { MOD_TABLE (MOD_0FAE_REG_7) }, ++ }, ++ /* REG_0FBA */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "btQ", { Ev, Ib } }, ++ { "btsQ", { Ev, Ib } }, ++ { "btrQ", { Ev, Ib } }, ++ { "btcQ", { Ev, Ib } }, ++ }, ++ /* REG_0FC7 */ ++ { ++ { "(bad)", { XX } }, ++ { "cmpxchg8b", { { CMPXCHG8B_Fixup, q_mode } } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0FC7_REG_6) }, ++ { MOD_TABLE (MOD_0FC7_REG_7) }, ++ }, + }; + +-static const struct dis386 prefix_user_table[][4] = { +- /* PREGRP0 */ ++static const struct dis386 prefix_table[][4] = { ++ /* PREFIX_90 */ + { +- { "addps", XM, EX, XX }, +- { "addss", XM, EX, XX }, +- { "addpd", XM, EX, XX }, +- { "addsd", XM, EX, XX }, ++ { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, ++ { "pause", { XX } }, ++ { "xchgS", { { NOP_Fixup1, eAX_reg }, { NOP_Fixup2, eAX_reg } } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP1 */ ++ ++ /* PREFIX_0F10 */ + { +- { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */ +- { "", XM, EX, OPSIMD }, +- { "", XM, EX, OPSIMD }, +- { "", XM, EX, OPSIMD }, ++ { "movups", { XM, EXx } }, ++ { "movss", { XM, EXd } }, ++ { "movupd", { XM, EXx } }, ++ { "movsd", { XM, EXq } }, + }, +- /* PREGRP2 */ ++ ++ /* PREFIX_0F11 */ + { +- { "cvtpi2ps", XM, EM, XX }, +- { "cvtsi2ssY", XM, Ev, XX }, +- { "cvtpi2pd", XM, EM, XX }, +- { "cvtsi2sdY", XM, Ev, XX }, ++ { "movups", { EXx, XM } }, ++ { "movss", { EXd, XM } }, ++ { "movupd", { EXx, XM } }, ++ { "movsd", { EXq, XM } }, + }, +- /* PREGRP3 */ ++ ++ /* PREFIX_0F12 */ + { +- { "cvtps2pi", MX, EX, XX }, +- { "cvtss2siY", Gv, EX, XX }, +- { "cvtpd2pi", MX, EX, XX }, +- { "cvtsd2siY", Gv, EX, XX }, ++ { MOD_TABLE (MOD_0F12_PREFIX_0) }, ++ { "movsldup", { XM, EXx } }, ++ { "movlpd", { XM, EXq } }, ++ { "movddup", { XM, EXq } }, + }, +- /* PREGRP4 */ ++ ++ /* PREFIX_0F16 */ + { +- { "cvttps2pi", MX, EX, XX }, +- { "cvttss2siY", Gv, EX, XX }, +- { "cvttpd2pi", MX, EX, XX }, +- { "cvttsd2siY", Gv, EX, XX }, ++ { MOD_TABLE (MOD_0F16_PREFIX_0) }, ++ { "movshdup", { XM, EXx } }, ++ { "movhpd", { XM, EXq } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP5 */ ++ ++ /* PREFIX_0F2A */ + { +- { "divps", XM, EX, XX }, +- { "divss", XM, EX, XX }, +- { "divpd", XM, EX, XX }, +- { "divsd", XM, EX, XX }, ++ { "cvtpi2ps", { XM, EMCq } }, ++ { "cvtsi2ss%LQ", { XM, Ev } }, ++ { "cvtpi2pd", { XM, EMCq } }, ++ { "cvtsi2sd%LQ", { XM, Ev } }, + }, +- /* PREGRP6 */ ++ ++ /* PREFIX_0F2B */ + { +- { "maxps", XM, EX, XX }, +- { "maxss", XM, EX, XX }, +- { "maxpd", XM, EX, XX }, +- { "maxsd", XM, EX, XX }, ++ { MOD_TABLE (MOD_0F2B_PREFIX_0) }, ++ { MOD_TABLE (MOD_0F2B_PREFIX_1) }, ++ { MOD_TABLE (MOD_0F2B_PREFIX_2) }, ++ { MOD_TABLE (MOD_0F2B_PREFIX_3) }, + }, +- /* PREGRP7 */ ++ ++ /* PREFIX_0F2C */ + { +- { "minps", XM, EX, XX }, +- { "minss", XM, EX, XX }, +- { "minpd", XM, EX, XX }, +- { "minsd", XM, EX, XX }, ++ { "cvttps2pi", { MXC, EXq } }, ++ { "cvttss2siY", { Gv, EXd } }, ++ { "cvttpd2pi", { MXC, EXx } }, ++ { "cvttsd2siY", { Gv, EXq } }, + }, +- /* PREGRP8 */ ++ ++ /* PREFIX_0F2D */ + { +- { "movups", XM, EX, XX }, +- { "movss", XM, EX, XX }, +- { "movupd", XM, EX, XX }, +- { "movsd", XM, EX, XX }, ++ { "cvtps2pi", { MXC, EXq } }, ++ { "cvtss2siY", { Gv, EXd } }, ++ { "cvtpd2pi", { MXC, EXx } }, ++ { "cvtsd2siY", { Gv, EXq } }, + }, +- /* PREGRP9 */ ++ ++ /* PREFIX_0F2E */ + { +- { "movups", EX, XM, XX }, +- { "movss", EX, XM, XX }, +- { "movupd", EX, XM, XX }, +- { "movsd", EX, XM, XX }, ++ { "ucomiss",{ XM, EXd } }, ++ { "(bad)", { XX } }, ++ { "ucomisd",{ XM, EXq } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP10 */ ++ ++ /* PREFIX_0F2F */ + { +- { "mulps", XM, EX, XX }, +- { "mulss", XM, EX, XX }, +- { "mulpd", XM, EX, XX }, +- { "mulsd", XM, EX, XX }, ++ { "comiss", { XM, EXd } }, ++ { "(bad)", { XX } }, ++ { "comisd", { XM, EXq } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP11 */ ++ ++ /* PREFIX_0F51 */ + { +- { "rcpps", XM, EX, XX }, +- { "rcpss", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ { "sqrtps", { XM, EXx } }, ++ { "sqrtss", { XM, EXd } }, ++ { "sqrtpd", { XM, EXx } }, ++ { "sqrtsd", { XM, EXq } }, + }, +- /* PREGRP12 */ ++ ++ /* PREFIX_0F52 */ + { +- { "rsqrtps", XM, EX, XX }, +- { "rsqrtss", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ { "rsqrtps",{ XM, EXx } }, ++ { "rsqrtss",{ XM, EXd } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP13 */ ++ ++ /* PREFIX_0F53 */ + { +- { "sqrtps", XM, EX, XX }, +- { "sqrtss", XM, EX, XX }, +- { "sqrtpd", XM, EX, XX }, +- { "sqrtsd", XM, EX, XX }, ++ { "rcpps", { XM, EXx } }, ++ { "rcpss", { XM, EXd } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP14 */ ++ ++ /* PREFIX_0F58 */ + { +- { "subps", XM, EX, XX }, +- { "subss", XM, EX, XX }, +- { "subpd", XM, EX, XX }, +- { "subsd", XM, EX, XX }, ++ { "addps", { XM, EXx } }, ++ { "addss", { XM, EXd } }, ++ { "addpd", { XM, EXx } }, ++ { "addsd", { XM, EXq } }, + }, +- /* PREGRP15 */ ++ ++ /* PREFIX_0F59 */ + { +- { "(bad)", XM, EX, XX }, +- { "cvtdq2pd", XM, EX, XX }, +- { "cvttpd2dq", XM, EX, XX }, +- { "cvtpd2dq", XM, EX, XX }, ++ { "mulps", { XM, EXx } }, ++ { "mulss", { XM, EXd } }, ++ { "mulpd", { XM, EXx } }, ++ { "mulsd", { XM, EXq } }, + }, +- /* PREGRP16 */ ++ ++ /* PREFIX_0F5A */ + { +- { "cvtdq2ps", XM, EX, XX }, +- { "cvttps2dq",XM, EX, XX }, +- { "cvtps2dq",XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ { "cvtps2pd", { XM, EXq } }, ++ { "cvtss2sd", { XM, EXd } }, ++ { "cvtpd2ps", { XM, EXx } }, ++ { "cvtsd2ss", { XM, EXq } }, + }, +- /* PREGRP17 */ ++ ++ /* PREFIX_0F5B */ + { +- { "cvtps2pd", XM, EX, XX }, +- { "cvtss2sd", XM, EX, XX }, +- { "cvtpd2ps", XM, EX, XX }, +- { "cvtsd2ss", XM, EX, XX }, ++ { "cvtdq2ps", { XM, EXx } }, ++ { "cvttps2dq", { XM, EXx } }, ++ { "cvtps2dq", { XM, EXx } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP18 */ ++ ++ /* PREFIX_0F5C */ + { +- { "maskmovq", MX, MS, XX }, +- { "(bad)", XM, EX, XX }, +- { "maskmovdqu", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ { "subps", { XM, EXx } }, ++ { "subss", { XM, EXd } }, ++ { "subpd", { XM, EXx } }, ++ { "subsd", { XM, EXq } }, + }, +- /* PREGRP19 */ ++ ++ /* PREFIX_0F5D */ + { +- { "movq", MX, EM, XX }, +- { "movdqu", XM, EX, XX }, +- { "movdqa", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ { "minps", { XM, EXx } }, ++ { "minss", { XM, EXd } }, ++ { "minpd", { XM, EXx } }, ++ { "minsd", { XM, EXq } }, + }, +- /* PREGRP20 */ ++ ++ /* PREFIX_0F5E */ + { +- { "movq", EM, MX, XX }, +- { "movdqu", EX, XM, XX }, +- { "movdqa", EX, XM, XX }, +- { "(bad)", EX, XM, XX }, ++ { "divps", { XM, EXx } }, ++ { "divss", { XM, EXd } }, ++ { "divpd", { XM, EXx } }, ++ { "divsd", { XM, EXq } }, + }, +- /* PREGRP21 */ ++ ++ /* PREFIX_0F5F */ + { +- { "(bad)", EX, XM, XX }, +- { "movq2dq", XM, MS, XX }, +- { "movq", EX, XM, XX }, +- { "movdq2q", MX, XS, XX }, ++ { "maxps", { XM, EXx } }, ++ { "maxss", { XM, EXd } }, ++ { "maxpd", { XM, EXx } }, ++ { "maxsd", { XM, EXq } }, + }, +- /* PREGRP22 */ ++ ++ /* PREFIX_0F60 */ + { +- { "pshufw", MX, EM, Ib }, +- { "pshufhw", XM, EX, Ib }, +- { "pshufd", XM, EX, Ib }, +- { "pshuflw", XM, EX, Ib }, ++ { "punpcklbw",{ MX, EMd } }, ++ { "(bad)", { XX } }, ++ { "punpcklbw",{ MX, EMx } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP23 */ ++ ++ /* PREFIX_0F61 */ + { +- { "movd", Edq, MX, XX }, +- { "movq", XM, EX, XX }, +- { "movd", Edq, XM, XX }, +- { "(bad)", Ed, XM, XX }, ++ { "punpcklwd",{ MX, EMd } }, ++ { "(bad)", { XX } }, ++ { "punpcklwd",{ MX, EMx } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP24 */ ++ ++ /* PREFIX_0F62 */ + { +- { "(bad)", MX, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "punpckhqdq", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ { "punpckldq",{ MX, EMd } }, ++ { "(bad)", { XX } }, ++ { "punpckldq",{ MX, EMx } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP25 */ ++ ++ /* PREFIX_0F6C */ + { +- { "movntq", Ev, MX, XX }, +- { "(bad)", Ev, XM, XX }, +- { "movntdq", Ev, XM, XX }, +- { "(bad)", Ev, XM, XX }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "punpcklqdq", { XM, EXx } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP26 */ ++ ++ /* PREFIX_0F6D */ + { +- { "(bad)", MX, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "punpcklqdq", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "punpckhqdq", { XM, EXx } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP27 */ ++ ++ /* PREFIX_0F6F */ + { +- { "(bad)", MX, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "addsubpd", XM, EX, XX }, +- { "addsubps", XM, EX, XX }, ++ { "movq", { MX, EM } }, ++ { "movdqu", { XM, EXx } }, ++ { "movdqa", { XM, EXx } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP28 */ ++ ++ /* PREFIX_0F70 */ + { +- { "(bad)", MX, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "haddpd", XM, EX, XX }, +- { "haddps", XM, EX, XX }, ++ { "pshufw", { MX, EM, Ib } }, ++ { "pshufhw",{ XM, EXx, Ib } }, ++ { "pshufd", { XM, EXx, Ib } }, ++ { "pshuflw",{ XM, EXx, Ib } }, + }, +- /* PREGRP29 */ ++ ++ /* PREFIX_0F73_REG_3 */ + { +- { "(bad)", MX, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "hsubpd", XM, EX, XX }, +- { "hsubps", XM, EX, XX }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "psrldq", { XS, Ib } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP30 */ ++ ++ /* PREFIX_0F73_REG_7 */ + { +- { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */ +- { "movsldup", XM, EX, XX }, +- { "movlpd", XM, EX, XX }, +- { "movddup", XM, EX, XX }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pslldq", { XS, Ib } }, ++ { "(bad)", { XX } }, + }, +- /* PREGRP31 */ ++ ++ /* PREFIX_0F78 */ + { +- { "movhpX", XM, EX, SIMD_Fixup, 'l' }, +- { "movshdup", XM, EX, XX }, +- { "movhpd", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, ++ {"vmread", { Em, Gm } }, ++ {"(bad)", { XX } }, ++ {"extrq", { XS, Ib, Ib } }, ++ {"insertq", { XM, XS, Ib, Ib } }, + }, +- /* PREGRP32 */ ++ ++ /* PREFIX_0F79 */ + { +- { "(bad)", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "(bad)", XM, EX, XX }, +- { "lddqu", XM, M, XX }, ++ {"vmwrite", { Gm, Em } }, ++ {"(bad)", { XX } }, ++ {"extrq", { XM, XS } }, ++ {"insertq", { XM, XS } }, + }, +-}; + +-static const struct dis386 x86_64_table[][2] = { ++ /* PREFIX_0F7C */ + { +- { "arpl", Ew, Gw, XX }, +- { "movs{||lq|xd}", Gv, Ed, XX }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "haddpd", { XM, EXx } }, ++ { "haddps", { XM, EXx } }, + }, +-}; + +-#define INTERNAL_DISASSEMBLER_ERROR _("") ++ /* PREFIX_0F7D */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "hsubpd", { XM, EXx } }, ++ { "hsubps", { XM, EXx } }, ++ }, + +-static void +-ckprefix (void) +-{ +- int newrex; +- rex = 0; +- prefixes = 0; +- used_prefixes = 0; +- rex_used = 0; +- while (1) +- { +- FETCH_DATA (the_info, codep + 1); +- newrex = 0; +- switch (*codep) +- { +- /* REX prefixes family. */ +- case 0x40: +- case 0x41: +- case 0x42: +- case 0x43: +- case 0x44: +- case 0x45: +- case 0x46: +- case 0x47: +- case 0x48: +- case 0x49: +- case 0x4a: +- case 0x4b: +- case 0x4c: +- case 0x4d: +- case 0x4e: +- case 0x4f: +- if (mode_64bit) +- newrex = *codep; +- else +- return; +- break; +- case 0xf3: +- prefixes |= PREFIX_REPZ; +- break; +- case 0xf2: +- prefixes |= PREFIX_REPNZ; +- break; +- case 0xf0: +- prefixes |= PREFIX_LOCK; +- break; +- case 0x2e: +- prefixes |= PREFIX_CS; +- break; +- case 0x36: +- prefixes |= PREFIX_SS; +- break; +- case 0x3e: +- prefixes |= PREFIX_DS; +- break; +- case 0x26: +- prefixes |= PREFIX_ES; +- break; +- case 0x64: +- prefixes |= PREFIX_FS; +- break; +- case 0x65: +- prefixes |= PREFIX_GS; +- break; +- case 0x66: +- prefixes |= PREFIX_DATA; +- break; +- case 0x67: +- prefixes |= PREFIX_ADDR; +- break; +- case FWAIT_OPCODE: +- /* fwait is really an instruction. If there are prefixes +- before the fwait, they belong to the fwait, *not* to the +- following instruction. */ +- if (prefixes) +- { +- prefixes |= PREFIX_FWAIT; +- codep++; +- return; +- } +- prefixes = PREFIX_FWAIT; +- break; +- default: +- return; +- } +- /* Rex is ignored when followed by another prefix. */ +- if (rex) +- { +- oappend (prefix_name (rex, 0)); +- oappend (" "); +- } +- rex = newrex; +- codep++; +- } +-} ++ /* PREFIX_0F7E */ ++ { ++ { "movK", { Edq, MX } }, ++ { "movq", { XM, EXq } }, ++ { "movK", { Edq, XM } }, ++ { "(bad)", { XX } }, ++ }, + +-/* Return the name of the prefix byte PREF, or NULL if PREF is not a +- prefix byte. */ ++ /* PREFIX_0F7F */ ++ { ++ { "movq", { EM, MX } }, ++ { "movdqu", { EXx, XM } }, ++ { "movdqa", { EXx, XM } }, ++ { "(bad)", { XX } }, ++ }, + +-static const char * +-prefix_name (int pref, int sizeflag) +-{ +- switch (pref) +- { +- /* REX prefixes family. */ +- case 0x40: +- return "rex"; +- case 0x41: +- return "rexZ"; +- case 0x42: +- return "rexY"; +- case 0x43: +- return "rexYZ"; +- case 0x44: +- return "rexX"; +- case 0x45: +- return "rexXZ"; +- case 0x46: +- return "rexXY"; +- case 0x47: +- return "rexXYZ"; +- case 0x48: +- return "rex64"; +- case 0x49: +- return "rex64Z"; +- case 0x4a: +- return "rex64Y"; +- case 0x4b: +- return "rex64YZ"; +- case 0x4c: +- return "rex64X"; +- case 0x4d: +- return "rex64XZ"; +- case 0x4e: +- return "rex64XY"; +- case 0x4f: +- return "rex64XYZ"; +- case 0xf3: +- return "repz"; +- case 0xf2: +- return "repnz"; +- case 0xf0: +- return "lock"; +- case 0x2e: +- return "cs"; +- case 0x36: +- return "ss"; +- case 0x3e: +- return "ds"; +- case 0x26: +- return "es"; +- case 0x64: +- return "fs"; +- case 0x65: +- return "gs"; +- case 0x66: +- return (sizeflag & DFLAG) ? "data16" : "data32"; +- case 0x67: +- if (mode_64bit) +- return (sizeflag & AFLAG) ? "addr32" : "addr64"; +- else +- return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32"; +- case FWAIT_OPCODE: +- return "fwait"; +- default: +- return NULL; +- } +-} ++ /* PREFIX_0FB8 */ ++ { ++ { "(bad)", { XX } }, ++ { "popcntS", { Gv, Ev } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, + +-static char op1out[100], op2out[100], op3out[100]; +-static int op_ad, op_index[3]; +-static bfd_vma op_address[3]; +-static bfd_vma op_riprel[3]; +-static bfd_vma start_pc; +- +-/* +- * On the 386's of 1988, the maximum length of an instruction is 15 bytes. +- * (see topic "Redundant prefixes" in the "Differences from 8086" +- * section of the "Virtual 8086 Mode" chapter.) +- * 'pc' should be the address of this instruction, it will +- * be used to print the target address if this is a relative jump or call +- * The function returns the length of this instruction in bytes. +- */ ++ /* PREFIX_0FBD */ ++ { ++ { "bsrS", { Gv, Ev } }, ++ { "lzcntS", { Gv, Ev } }, ++ { "bsrS", { Gv, Ev } }, ++ { "(bad)", { XX } }, ++ }, + +-static char intel_syntax; +-static char open_char; +-static char close_char; +-static char separator_char; +-static char scale_char; ++ /* PREFIX_0FC2 */ ++ { ++ { "cmpps", { XM, EXx, CMP } }, ++ { "cmpss", { XM, EXd, CMP } }, ++ { "cmppd", { XM, EXx, CMP } }, ++ { "cmpsd", { XM, EXq, CMP } }, ++ }, + +-/* Here for backwards compatibility. When gdb stops using +- print_insn_i386_att and print_insn_i386_intel these functions can +- disappear, and print_insn_i386 be merged into print_insn. */ +-int +-print_insn_i386_att (bfd_vma pc, disassemble_info *info) +-{ +- intel_syntax = 0; ++ /* PREFIX_0FC3 */ ++ { ++ { "movntiS", { Ma, Gv } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, + +- return print_insn (pc, info); +-} ++ /* PREFIX_0FC7_REG_6 */ ++ { ++ { "vmptrld",{ Mq } }, ++ { "vmxon", { Mq } }, ++ { "vmclear",{ Mq } }, ++ { "(bad)", { XX } }, ++ }, + +-int +-print_insn_i386_intel (bfd_vma pc, disassemble_info *info) +-{ +- intel_syntax = 1; ++ /* PREFIX_0FD0 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "addsubpd", { XM, EXx } }, ++ { "addsubps", { XM, EXx } }, ++ }, + +- return print_insn (pc, info); +-} ++ /* PREFIX_0FD6 */ ++ { ++ { "(bad)", { XX } }, ++ { "movq2dq",{ XM, MS } }, ++ { "movq", { EXq, XM } }, ++ { "movdq2q",{ MX, XS } }, ++ }, ++ ++ /* PREFIX_0FE6 */ ++ { ++ { "(bad)", { XX } }, ++ { "cvtdq2pd", { XM, EXq } }, ++ { "cvttpd2dq", { XM, EXx } }, ++ { "cvtpd2dq", { XM, EXx } }, ++ }, ++ ++ /* PREFIX_0FE7 */ ++ { ++ { "movntq", { Mq, MX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0FE7_PREFIX_2) }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0FF0 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0FF0_PREFIX_3) }, ++ }, ++ ++ /* PREFIX_0FF7 */ ++ { ++ { "maskmovq", { MX, MS } }, ++ { "(bad)", { XX } }, ++ { "maskmovdqu", { XM, XS } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3810 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pblendvb", { XM, EXx, XMM0 } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3814 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "blendvps", { XM, EXx, XMM0 } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3815 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "blendvpd", { XM, EXx, XMM0 } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3817 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "ptest", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3820 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovsxbw", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3821 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovsxbd", { XM, EXd } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3822 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovsxbq", { XM, EXw } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3823 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovsxwd", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3824 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovsxwq", { XM, EXd } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3825 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovsxdq", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3828 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmuldq", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3829 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcmpeqq", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F382A */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { MOD_TABLE (MOD_0F382A_PREFIX_2) }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F382B */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "packusdw", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3830 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovzxbw", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3831 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovzxbd", { XM, EXd } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3832 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovzxbq", { XM, EXw } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3833 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovzxwd", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3834 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovzxwq", { XM, EXd } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3835 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmovzxdq", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3837 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcmpgtq", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3838 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pminsb", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3839 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pminsd", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F383A */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pminuw", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F383B */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pminud", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F383C */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmaxsb", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F383D */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmaxsd", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F383E */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmaxuw", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F383F */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmaxud", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3840 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmulld", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3841 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "phminposuw", { XM, EXx } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F38F0 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "crc32", { Gdq, { CRC32_Fixup, b_mode } } }, ++ }, ++ ++ /* PREFIX_0F38F1 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "crc32", { Gdq, { CRC32_Fixup, v_mode } } }, ++ }, ++ ++ /* PREFIX_0F3A08 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "roundps", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A09 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "roundpd", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A0A */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "roundss", { XM, EXd, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A0B */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "roundsd", { XM, EXq, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A0C */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "blendps", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A0D */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "blendpd", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A0E */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pblendw", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A14 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pextrb", { Edqb, XM, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A15 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pextrw", { Edqw, XM, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A16 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pextrK", { Edq, XM, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A17 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "extractps", { Edqd, XM, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A20 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pinsrb", { XM, Edqb, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A21 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "insertps", { XM, EXd, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A22 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pinsrK", { XM, Edq, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A40 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "dpps", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A41 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "dppd", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A42 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "mpsadbw", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A60 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcmpestrm", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A61 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcmpestri", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A62 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcmpistrm", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* PREFIX_0F3A63 */ ++ { ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcmpistri", { XM, EXx, Ib } }, ++ { "(bad)", { XX } }, ++ }, ++}; ++ ++static const struct dis386 x86_64_table[][2] = { ++ /* X86_64_06 */ ++ { ++ { "push{T|}", { es } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_07 */ ++ { ++ { "pop{T|}", { es } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_0D */ ++ { ++ { "push{T|}", { cs } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_16 */ ++ { ++ { "push{T|}", { ss } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_17 */ ++ { ++ { "pop{T|}", { ss } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_1E */ ++ { ++ { "push{T|}", { ds } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_1F */ ++ { ++ { "pop{T|}", { ds } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_27 */ ++ { ++ { "daa", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_2F */ ++ { ++ { "das", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_37 */ ++ { ++ { "aaa", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_3F */ ++ { ++ { "aas", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_60 */ ++ { ++ { "pusha{P|}", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_61 */ ++ { ++ { "popa{P|}", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_62 */ ++ { ++ { MOD_TABLE (MOD_62_32BIT) }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_63 */ ++ { ++ { "arpl", { Ew, Gw } }, ++ { "movs{lq|xd}", { Gv, Ed } }, ++ }, ++ ++ /* X86_64_6D */ ++ { ++ { "ins{R|}", { Yzr, indirDX } }, ++ { "ins{G|}", { Yzr, indirDX } }, ++ }, ++ ++ /* X86_64_6F */ ++ { ++ { "outs{R|}", { indirDXr, Xz } }, ++ { "outs{G|}", { indirDXr, Xz } }, ++ }, ++ ++ /* X86_64_9A */ ++ { ++ { "Jcall{T|}", { Ap } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_C4 */ ++ { ++ { MOD_TABLE (MOD_C4_32BIT) }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_C5 */ ++ { ++ { MOD_TABLE (MOD_C5_32BIT) }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_CE */ ++ { ++ { "into", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_D4 */ ++ { ++ { "aam", { sIb } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_D5 */ ++ { ++ { "aad", { sIb } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_EA */ ++ { ++ { "Jjmp{T|}", { Ap } }, ++ { "(bad)", { XX } }, ++ }, ++ ++ /* X86_64_0F01_REG_0 */ ++ { ++ { "sgdt{Q|IQ}", { M } }, ++ { "sgdt", { M } }, ++ }, ++ ++ /* X86_64_0F01_REG_1 */ ++ { ++ { "sidt{Q|IQ}", { M } }, ++ { "sidt", { M } }, ++ }, ++ ++ /* X86_64_0F01_REG_2 */ ++ { ++ { "lgdt{Q|Q}", { M } }, ++ { "lgdt", { M } }, ++ }, ++ ++ /* X86_64_0F01_REG_3 */ ++ { ++ { "lidt{Q|Q}", { M } }, ++ { "lidt", { M } }, ++ }, ++}; ++ ++static const struct dis386 three_byte_table[][256] = { ++ /* THREE_BYTE_0F24 */ ++ { ++ /* 00 */ ++ { "fmaddps", { { OP_DREX4, q_mode } } }, ++ { "fmaddpd", { { OP_DREX4, q_mode } } }, ++ { "fmaddss", { { OP_DREX4, w_mode } } }, ++ { "fmaddsd", { { OP_DREX4, d_mode } } }, ++ { "fmaddps", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fmaddpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fmaddss", { { OP_DREX4, DREX_OC1 + w_mode } } }, ++ { "fmaddsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, ++ /* 08 */ ++ { "fmsubps", { { OP_DREX4, q_mode } } }, ++ { "fmsubpd", { { OP_DREX4, q_mode } } }, ++ { "fmsubss", { { OP_DREX4, w_mode } } }, ++ { "fmsubsd", { { OP_DREX4, d_mode } } }, ++ { "fmsubps", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fmsubpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fmsubss", { { OP_DREX4, DREX_OC1 + w_mode } } }, ++ { "fmsubsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, ++ /* 10 */ ++ { "fnmaddps", { { OP_DREX4, q_mode } } }, ++ { "fnmaddpd", { { OP_DREX4, q_mode } } }, ++ { "fnmaddss", { { OP_DREX4, w_mode } } }, ++ { "fnmaddsd", { { OP_DREX4, d_mode } } }, ++ { "fnmaddps", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fnmaddpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fnmaddss", { { OP_DREX4, DREX_OC1 + w_mode } } }, ++ { "fnmaddsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, ++ /* 18 */ ++ { "fnmsubps", { { OP_DREX4, q_mode } } }, ++ { "fnmsubpd", { { OP_DREX4, q_mode } } }, ++ { "fnmsubss", { { OP_DREX4, w_mode } } }, ++ { "fnmsubsd", { { OP_DREX4, d_mode } } }, ++ { "fnmsubps", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fnmsubpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "fnmsubss", { { OP_DREX4, DREX_OC1 + w_mode } } }, ++ { "fnmsubsd", { { OP_DREX4, DREX_OC1 + d_mode } } }, ++ /* 20 */ ++ { "permps", { { OP_DREX4, q_mode } } }, ++ { "permpd", { { OP_DREX4, q_mode } } }, ++ { "pcmov", { { OP_DREX4, q_mode } } }, ++ { "pperm", { { OP_DREX4, q_mode } } }, ++ { "permps", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "permpd", { { OP_DREX4, DREX_OC1 + q_mode } } }, ++ { "pcmov", { { OP_DREX4, DREX_OC1 + w_mode } } }, ++ { "pperm", { { OP_DREX4, DREX_OC1 + d_mode } } }, ++ /* 28 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 30 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 38 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 40 */ ++ { "protb", { { OP_DREX3, q_mode } } }, ++ { "protw", { { OP_DREX3, q_mode } } }, ++ { "protd", { { OP_DREX3, q_mode } } }, ++ { "protq", { { OP_DREX3, q_mode } } }, ++ { "pshlb", { { OP_DREX3, q_mode } } }, ++ { "pshlw", { { OP_DREX3, q_mode } } }, ++ { "pshld", { { OP_DREX3, q_mode } } }, ++ { "pshlq", { { OP_DREX3, q_mode } } }, ++ /* 48 */ ++ { "pshab", { { OP_DREX3, q_mode } } }, ++ { "pshaw", { { OP_DREX3, q_mode } } }, ++ { "pshad", { { OP_DREX3, q_mode } } }, ++ { "pshaq", { { OP_DREX3, q_mode } } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 50 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 58 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 60 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 68 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 70 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 78 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 80 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmacssww", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "pmacsswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "pmacssdql", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ /* 88 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmacssdd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "pmacssdqh", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ /* 90 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmacsww", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "pmacswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "pmacsdql", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ /* 98 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmacsdd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "pmacsdqh", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ /* a0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmadcsswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "(bad)", { XX } }, ++ /* a8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pmadcswd", { { OP_DREX4, DREX_OC1 + DREX_NO_OC0 + q_mode } } }, ++ { "(bad)", { XX } }, ++ /* b8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* THREE_BYTE_0F25 */ ++ { ++ /* 00 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 08 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 10 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 18 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 20 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 28 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "comps", { { OP_DREX3, q_mode }, { OP_DREX_FCMP, b_mode } } }, ++ { "compd", { { OP_DREX3, q_mode }, { OP_DREX_FCMP, b_mode } } }, ++ { "comss", { { OP_DREX3, w_mode }, { OP_DREX_FCMP, b_mode } } }, ++ { "comsd", { { OP_DREX3, d_mode }, { OP_DREX_FCMP, b_mode } } }, ++ /* 30 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 38 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 40 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 48 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcomb", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ { "pcomw", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ { "pcomd", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ { "pcomq", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ /* 50 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 58 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 60 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 68 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pcomub", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ { "pcomuw", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ { "pcomud", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ { "pcomuq", { { OP_DREX3, q_mode }, { OP_DREX_ICMP, b_mode } } }, ++ /* 70 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 78 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 80 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 88 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 90 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 98 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* THREE_BYTE_0F38 */ ++ { ++ /* 00 */ ++ { "pshufb", { MX, EM } }, ++ { "phaddw", { MX, EM } }, ++ { "phaddd", { MX, EM } }, ++ { "phaddsw", { MX, EM } }, ++ { "pmaddubsw", { MX, EM } }, ++ { "phsubw", { MX, EM } }, ++ { "phsubd", { MX, EM } }, ++ { "phsubsw", { MX, EM } }, ++ /* 08 */ ++ { "psignb", { MX, EM } }, ++ { "psignw", { MX, EM } }, ++ { "psignd", { MX, EM } }, ++ { "pmulhrsw", { MX, EM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 10 */ ++ { PREFIX_TABLE (PREFIX_0F3810) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { PREFIX_TABLE (PREFIX_0F3814) }, ++ { PREFIX_TABLE (PREFIX_0F3815) }, ++ { "(bad)", { XX } }, ++ { PREFIX_TABLE (PREFIX_0F3817) }, ++ /* 18 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "pabsb", { MX, EM } }, ++ { "pabsw", { MX, EM } }, ++ { "pabsd", { MX, EM } }, ++ { "(bad)", { XX } }, ++ /* 20 */ ++ { PREFIX_TABLE (PREFIX_0F3820) }, ++ { PREFIX_TABLE (PREFIX_0F3821) }, ++ { PREFIX_TABLE (PREFIX_0F3822) }, ++ { PREFIX_TABLE (PREFIX_0F3823) }, ++ { PREFIX_TABLE (PREFIX_0F3824) }, ++ { PREFIX_TABLE (PREFIX_0F3825) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 28 */ ++ { PREFIX_TABLE (PREFIX_0F3828) }, ++ { PREFIX_TABLE (PREFIX_0F3829) }, ++ { PREFIX_TABLE (PREFIX_0F382A) }, ++ { PREFIX_TABLE (PREFIX_0F382B) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 30 */ ++ { PREFIX_TABLE (PREFIX_0F3830) }, ++ { PREFIX_TABLE (PREFIX_0F3831) }, ++ { PREFIX_TABLE (PREFIX_0F3832) }, ++ { PREFIX_TABLE (PREFIX_0F3833) }, ++ { PREFIX_TABLE (PREFIX_0F3834) }, ++ { PREFIX_TABLE (PREFIX_0F3835) }, ++ { "(bad)", { XX } }, ++ { PREFIX_TABLE (PREFIX_0F3837) }, ++ /* 38 */ ++ { PREFIX_TABLE (PREFIX_0F3838) }, ++ { PREFIX_TABLE (PREFIX_0F3839) }, ++ { PREFIX_TABLE (PREFIX_0F383A) }, ++ { PREFIX_TABLE (PREFIX_0F383B) }, ++ { PREFIX_TABLE (PREFIX_0F383C) }, ++ { PREFIX_TABLE (PREFIX_0F383D) }, ++ { PREFIX_TABLE (PREFIX_0F383E) }, ++ { PREFIX_TABLE (PREFIX_0F383F) }, ++ /* 40 */ ++ { PREFIX_TABLE (PREFIX_0F3840) }, ++ { PREFIX_TABLE (PREFIX_0F3841) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 48 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 50 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 58 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 60 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 68 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 70 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 78 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 80 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 88 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 90 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 98 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f0 */ ++ { PREFIX_TABLE (PREFIX_0F38F0) }, ++ { PREFIX_TABLE (PREFIX_0F38F1) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* THREE_BYTE_0F3A */ ++ { ++ /* 00 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 08 */ ++ { PREFIX_TABLE (PREFIX_0F3A08) }, ++ { PREFIX_TABLE (PREFIX_0F3A09) }, ++ { PREFIX_TABLE (PREFIX_0F3A0A) }, ++ { PREFIX_TABLE (PREFIX_0F3A0B) }, ++ { PREFIX_TABLE (PREFIX_0F3A0C) }, ++ { PREFIX_TABLE (PREFIX_0F3A0D) }, ++ { PREFIX_TABLE (PREFIX_0F3A0E) }, ++ { "palignr", { MX, EM, Ib } }, ++ /* 10 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { PREFIX_TABLE (PREFIX_0F3A14) }, ++ { PREFIX_TABLE (PREFIX_0F3A15) }, ++ { PREFIX_TABLE (PREFIX_0F3A16) }, ++ { PREFIX_TABLE (PREFIX_0F3A17) }, ++ /* 18 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 20 */ ++ { PREFIX_TABLE (PREFIX_0F3A20) }, ++ { PREFIX_TABLE (PREFIX_0F3A21) }, ++ { PREFIX_TABLE (PREFIX_0F3A22) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 28 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 30 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 38 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 40 */ ++ { PREFIX_TABLE (PREFIX_0F3A40) }, ++ { PREFIX_TABLE (PREFIX_0F3A41) }, ++ { PREFIX_TABLE (PREFIX_0F3A42) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 48 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 50 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 58 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 60 */ ++ { PREFIX_TABLE (PREFIX_0F3A60) }, ++ { PREFIX_TABLE (PREFIX_0F3A61) }, ++ { PREFIX_TABLE (PREFIX_0F3A62) }, ++ { PREFIX_TABLE (PREFIX_0F3A63) }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 68 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 70 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 78 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 80 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 88 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 90 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 98 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* THREE_BYTE_0F7A */ ++ { ++ /* 00 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 08 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 10 */ ++ { "frczps", { XM, EXq } }, ++ { "frczpd", { XM, EXq } }, ++ { "frczss", { XM, EXq } }, ++ { "frczsd", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 18 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 20 */ ++ { "ptest", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 28 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 30 */ ++ { "cvtph2ps", { XM, EXd } }, ++ { "cvtps2ph", { EXd, XM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 38 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 40 */ ++ { "(bad)", { XX } }, ++ { "phaddbw", { XM, EXq } }, ++ { "phaddbd", { XM, EXq } }, ++ { "phaddbq", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "phaddwd", { XM, EXq } }, ++ { "phaddwq", { XM, EXq } }, ++ /* 48 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "phadddq", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 50 */ ++ { "(bad)", { XX } }, ++ { "phaddubw", { XM, EXq } }, ++ { "phaddubd", { XM, EXq } }, ++ { "phaddubq", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "phadduwd", { XM, EXq } }, ++ { "phadduwq", { XM, EXq } }, ++ /* 58 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "phaddudq", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 60 */ ++ { "(bad)", { XX } }, ++ { "phsubbw", { XM, EXq } }, ++ { "phsubbd", { XM, EXq } }, ++ { "phsubbq", { XM, EXq } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 68 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 70 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 78 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 80 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 88 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 90 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 98 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ /* THREE_BYTE_0F7B */ ++ { ++ /* 00 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 08 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 10 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 18 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 20 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 28 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 30 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 38 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 40 */ ++ { "protb", { XM, EXq, Ib } }, ++ { "protw", { XM, EXq, Ib } }, ++ { "protd", { XM, EXq, Ib } }, ++ { "protq", { XM, EXq, Ib } }, ++ { "pshlb", { XM, EXq, Ib } }, ++ { "pshlw", { XM, EXq, Ib } }, ++ { "pshld", { XM, EXq, Ib } }, ++ { "pshlq", { XM, EXq, Ib } }, ++ /* 48 */ ++ { "pshab", { XM, EXq, Ib } }, ++ { "pshaw", { XM, EXq, Ib } }, ++ { "pshad", { XM, EXq, Ib } }, ++ { "pshaq", { XM, EXq, Ib } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 50 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 58 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 60 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 68 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 70 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 78 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 80 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 88 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 90 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* 98 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* a8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* b8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* c8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* d8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* e8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f0 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ /* f8 */ ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ } ++}; ++ ++static const struct dis386 mod_table[][2] = { ++ { ++ /* MOD_8D */ ++ { "leaS", { Gv, M } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F01_REG_0 */ ++ { X86_64_TABLE (X86_64_0F01_REG_0) }, ++ { RM_TABLE (RM_0F01_REG_0) }, ++ }, ++ { ++ /* MOD_0F01_REG_1 */ ++ { X86_64_TABLE (X86_64_0F01_REG_1) }, ++ { RM_TABLE (RM_0F01_REG_1) }, ++ }, ++ { ++ /* MOD_0F01_REG_2 */ ++ { X86_64_TABLE (X86_64_0F01_REG_2) }, ++ { RM_TABLE (RM_0F01_REG_2) }, ++ }, ++ { ++ /* MOD_0F01_REG_3 */ ++ { X86_64_TABLE (X86_64_0F01_REG_3) }, ++ { RM_TABLE (RM_0F01_REG_3) }, ++ }, ++ { ++ /* MOD_0F01_REG_7 */ ++ { "invlpg", { Mb } }, ++ { RM_TABLE (RM_0F01_REG_7) }, ++ }, ++ { ++ /* MOD_0F12_PREFIX_0 */ ++ { "movlps", { XM, EXq } }, ++ { "movhlps", { XM, EXq } }, ++ }, ++ { ++ /* MOD_0F13 */ ++ { "movlpX", { EXq, XM } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F16_PREFIX_0 */ ++ { "movhps", { XM, EXq } }, ++ { "movlhps", { XM, EXq } }, ++ }, ++ { ++ /* MOD_0F17 */ ++ { "movhpX", { EXq, XM } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F18_REG_0 */ ++ { "prefetchnta", { Mb } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F18_REG_1 */ ++ { "prefetcht0", { Mb } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F18_REG_2 */ ++ { "prefetcht1", { Mb } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F18_REG_3 */ ++ { "prefetcht2", { Mb } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F20 */ ++ { "(bad)", { XX } }, ++ { "movZ", { Rm, Cm } }, ++ }, ++ { ++ /* MOD_0F21 */ ++ { "(bad)", { XX } }, ++ { "movZ", { Rm, Dm } }, ++ }, ++ { ++ /* MOD_0F22 */ ++ { "(bad)", { XX } }, ++ { "movZ", { Cm, Rm } }, ++ }, ++ { ++ /* MOD_0F23 */ ++ { "(bad)", { XX } }, ++ { "movZ", { Dm, Rm } }, ++ }, ++ { ++ /* MOD_0F24 */ ++ { THREE_BYTE_TABLE (THREE_BYTE_0F24) }, ++ { "movL", { Rd, Td } }, ++ }, ++ { ++ /* MOD_0F26 */ ++ { "(bad)", { XX } }, ++ { "movL", { Td, Rd } }, ++ }, ++ { ++ /* MOD_0F2B_PREFIX_0 */ ++ {"movntps", { Mx, XM } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F2B_PREFIX_1 */ ++ {"movntss", { Md, XM } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F2B_PREFIX_2 */ ++ {"movntpd", { Mx, XM } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F2B_PREFIX_3 */ ++ {"movntsd", { Mq, XM } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F51 */ ++ { "(bad)", { XX } }, ++ { "movmskpX", { Gdq, XS } }, ++ }, ++ { ++ /* MOD_0F71_REG_2 */ ++ { "(bad)", { XX } }, ++ { "psrlw", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F71_REG_4 */ ++ { "(bad)", { XX } }, ++ { "psraw", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F71_REG_6 */ ++ { "(bad)", { XX } }, ++ { "psllw", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F72_REG_2 */ ++ { "(bad)", { XX } }, ++ { "psrld", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F72_REG_4 */ ++ { "(bad)", { XX } }, ++ { "psrad", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F72_REG_6 */ ++ { "(bad)", { XX } }, ++ { "pslld", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F73_REG_2 */ ++ { "(bad)", { XX } }, ++ { "psrlq", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F73_REG_3 */ ++ { "(bad)", { XX } }, ++ { PREFIX_TABLE (PREFIX_0F73_REG_3) }, ++ }, ++ { ++ /* MOD_0F73_REG_6 */ ++ { "(bad)", { XX } }, ++ { "psllq", { MS, Ib } }, ++ }, ++ { ++ /* MOD_0F73_REG_7 */ ++ { "(bad)", { XX } }, ++ { PREFIX_TABLE (PREFIX_0F73_REG_7) }, ++ }, ++ { ++ /* MOD_0FAE_REG_0 */ ++ { "fxsave", { M } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FAE_REG_1 */ ++ { "fxrstor", { M } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FAE_REG_2 */ ++ { "ldmxcsr", { Md } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FAE_REG_3 */ ++ { "stmxcsr", { Md } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FAE_REG_4 */ ++ { "xsave", { M } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FAE_REG_5 */ ++ { "xrstor", { M } }, ++ { RM_TABLE (RM_0FAE_REG_5) }, ++ }, ++ { ++ /* MOD_0FAE_REG_6 */ ++ { "(bad)", { XX } }, ++ { RM_TABLE (RM_0FAE_REG_6) }, ++ }, ++ { ++ /* MOD_0FAE_REG_7 */ ++ { "clflush", { Mb } }, ++ { RM_TABLE (RM_0FAE_REG_7) }, ++ }, ++ { ++ /* MOD_0FB2 */ ++ { "lssS", { Gv, Mp } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FB4 */ ++ { "lfsS", { Gv, Mp } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FB5 */ ++ { "lgsS", { Gv, Mp } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FC7_REG_6 */ ++ { PREFIX_TABLE (PREFIX_0FC7_REG_6) }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FC7_REG_7 */ ++ { "vmptrst", { Mq } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FD7 */ ++ { "(bad)", { XX } }, ++ { "pmovmskb", { Gdq, MS } }, ++ }, ++ { ++ /* MOD_0FE7_PREFIX_2 */ ++ { "movntdq", { Mx, XM } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0FF0_PREFIX_3 */ ++ { "lddqu", { XM, M } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_0F382A_PREFIX_2 */ ++ { "movntdqa", { XM, Mx } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_62_32BIT */ ++ { "bound{S|}", { Gv, Ma } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_C4_32BIT */ ++ { "lesS", { Gv, Mp } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* MOD_C5_32BIT */ ++ { "ldsS", { Gv, Mp } }, ++ { "(bad)", { XX } }, ++ }, ++}; ++ ++static const struct dis386 rm_table[][8] = { ++ { ++ /* RM_0F01_REG_0 */ ++ { "(bad)", { XX } }, ++ { "vmcall", { Skip_MODRM } }, ++ { "vmlaunch", { Skip_MODRM } }, ++ { "vmresume", { Skip_MODRM } }, ++ { "vmxoff", { Skip_MODRM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* RM_0F01_REG_1 */ ++ { "monitor", { { OP_Monitor, 0 } } }, ++ { "mwait", { { OP_Mwait, 0 } } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* RM_0F01_REG_2 */ ++ { "xgetbv", { Skip_MODRM } }, ++ { "xsetbv", { Skip_MODRM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* RM_0F01_REG_3 */ ++ { "vmrun", { Skip_MODRM } }, ++ { "vmmcall", { Skip_MODRM } }, ++ { "vmload", { Skip_MODRM } }, ++ { "vmsave", { Skip_MODRM } }, ++ { "stgi", { Skip_MODRM } }, ++ { "clgi", { Skip_MODRM } }, ++ { "skinit", { Skip_MODRM } }, ++ { "invlpga", { Skip_MODRM } }, ++ }, ++ { ++ /* RM_0F01_REG_7 */ ++ { "swapgs", { Skip_MODRM } }, ++ { "rdtscp", { Skip_MODRM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* RM_0FAE_REG_5 */ ++ { "lfence", { Skip_MODRM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* RM_0FAE_REG_6 */ ++ { "mfence", { Skip_MODRM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++ { ++ /* RM_0FAE_REG_7 */ ++ { "sfence", { Skip_MODRM } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ }, ++}; ++ ++#define INTERNAL_DISASSEMBLER_ERROR _("") ++ ++static void ++ckprefix (void) ++{ ++ int newrex; ++ rex = 0; ++ prefixes = 0; ++ used_prefixes = 0; ++ rex_used = 0; ++ while (1) ++ { ++ FETCH_DATA (the_info, codep + 1); ++ newrex = 0; ++ switch (*codep) ++ { ++ /* REX prefixes family. */ ++ case 0x40: ++ case 0x41: ++ case 0x42: ++ case 0x43: ++ case 0x44: ++ case 0x45: ++ case 0x46: ++ case 0x47: ++ case 0x48: ++ case 0x49: ++ case 0x4a: ++ case 0x4b: ++ case 0x4c: ++ case 0x4d: ++ case 0x4e: ++ case 0x4f: ++ if (address_mode == mode_64bit) ++ newrex = *codep; ++ else ++ return; ++ break; ++ case 0xf3: ++ prefixes |= PREFIX_REPZ; ++ break; ++ case 0xf2: ++ prefixes |= PREFIX_REPNZ; ++ break; ++ case 0xf0: ++ prefixes |= PREFIX_LOCK; ++ break; ++ case 0x2e: ++ prefixes |= PREFIX_CS; ++ break; ++ case 0x36: ++ prefixes |= PREFIX_SS; ++ break; ++ case 0x3e: ++ prefixes |= PREFIX_DS; ++ break; ++ case 0x26: ++ prefixes |= PREFIX_ES; ++ break; ++ case 0x64: ++ prefixes |= PREFIX_FS; ++ break; ++ case 0x65: ++ prefixes |= PREFIX_GS; ++ break; ++ case 0x66: ++ prefixes |= PREFIX_DATA; ++ break; ++ case 0x67: ++ prefixes |= PREFIX_ADDR; ++ break; ++ case FWAIT_OPCODE: ++ /* fwait is really an instruction. If there are prefixes ++ before the fwait, they belong to the fwait, *not* to the ++ following instruction. */ ++ if (prefixes || rex) ++ { ++ prefixes |= PREFIX_FWAIT; ++ codep++; ++ return; ++ } ++ prefixes = PREFIX_FWAIT; ++ break; ++ default: ++ return; ++ } ++ /* Rex is ignored when followed by another prefix. */ ++ if (rex) ++ { ++ rex_used = rex; ++ return; ++ } ++ rex = newrex; ++ codep++; ++ } ++} ++ ++/* Return the name of the prefix byte PREF, or NULL if PREF is not a ++ prefix byte. */ ++ ++static const char * ++prefix_name (int pref, int sizeflag) ++{ ++ static const char *rexes [16] = ++ { ++ "rex", /* 0x40 */ ++ "rex.B", /* 0x41 */ ++ "rex.X", /* 0x42 */ ++ "rex.XB", /* 0x43 */ ++ "rex.R", /* 0x44 */ ++ "rex.RB", /* 0x45 */ ++ "rex.RX", /* 0x46 */ ++ "rex.RXB", /* 0x47 */ ++ "rex.W", /* 0x48 */ ++ "rex.WB", /* 0x49 */ ++ "rex.WX", /* 0x4a */ ++ "rex.WXB", /* 0x4b */ ++ "rex.WR", /* 0x4c */ ++ "rex.WRB", /* 0x4d */ ++ "rex.WRX", /* 0x4e */ ++ "rex.WRXB", /* 0x4f */ ++ }; ++ ++ switch (pref) ++ { ++ /* REX prefixes family. */ ++ case 0x40: ++ case 0x41: ++ case 0x42: ++ case 0x43: ++ case 0x44: ++ case 0x45: ++ case 0x46: ++ case 0x47: ++ case 0x48: ++ case 0x49: ++ case 0x4a: ++ case 0x4b: ++ case 0x4c: ++ case 0x4d: ++ case 0x4e: ++ case 0x4f: ++ return rexes [pref - 0x40]; ++ case 0xf3: ++ return "repz"; ++ case 0xf2: ++ return "repnz"; ++ case 0xf0: ++ return "lock"; ++ case 0x2e: ++ return "cs"; ++ case 0x36: ++ return "ss"; ++ case 0x3e: ++ return "ds"; ++ case 0x26: ++ return "es"; ++ case 0x64: ++ return "fs"; ++ case 0x65: ++ return "gs"; ++ case 0x66: ++ return (sizeflag & DFLAG) ? "data16" : "data32"; ++ case 0x67: ++ if (address_mode == mode_64bit) ++ return (sizeflag & AFLAG) ? "addr32" : "addr64"; ++ else ++ return (sizeflag & AFLAG) ? "addr16" : "addr32"; ++ case FWAIT_OPCODE: ++ return "fwait"; ++ default: ++ return NULL; ++ } ++} ++ ++static char op_out[MAX_OPERANDS][100]; ++static int op_ad, op_index[MAX_OPERANDS]; ++static int two_source_ops; ++static bfd_vma op_address[MAX_OPERANDS]; ++static bfd_vma op_riprel[MAX_OPERANDS]; ++static bfd_vma start_pc; ++ ++/* ++ * On the 386's of 1988, the maximum length of an instruction is 15 bytes. ++ * (see topic "Redundant prefixes" in the "Differences from 8086" ++ * section of the "Virtual 8086 Mode" chapter.) ++ * 'pc' should be the address of this instruction, it will ++ * be used to print the target address if this is a relative jump or call ++ * The function returns the length of this instruction in bytes. ++ */ ++ ++static char intel_syntax; ++static char intel_mnemonic = !SYSV386_COMPAT; ++static char open_char; ++static char close_char; ++static char separator_char; ++static char scale_char; ++ ++/* Here for backwards compatibility. When gdb stops using ++ print_insn_i386_att and print_insn_i386_intel these functions can ++ disappear, and print_insn_i386 be merged into print_insn. */ ++int ++print_insn_i386_att (bfd_vma pc, disassemble_info *info) ++{ ++ intel_syntax = 0; ++ ++ return print_insn (pc, info); ++} ++ ++int ++print_insn_i386_intel (bfd_vma pc, disassemble_info *info) ++{ ++ intel_syntax = 1; ++ ++ return print_insn (pc, info); ++} + + int + print_insn_i386 (bfd_vma pc, disassemble_info *info) +@@ -1912,21 +5130,130 @@ print_insn_i386 (bfd_vma pc, disassemble + return print_insn (pc, info); + } + ++void ++print_i386_disassembler_options (FILE *stream) ++{ ++ fprintf (stream, _("\n\ ++The following i386/x86-64 specific disassembler options are supported for use\n\ ++with the -M switch (multiple options should be separated by commas):\n")); ++ ++ fprintf (stream, _(" x86-64 Disassemble in 64bit mode\n")); ++ fprintf (stream, _(" i386 Disassemble in 32bit mode\n")); ++ fprintf (stream, _(" i8086 Disassemble in 16bit mode\n")); ++ fprintf (stream, _(" att Display instruction in AT&T syntax\n")); ++ fprintf (stream, _(" intel Display instruction in Intel syntax\n")); ++ fprintf (stream, _(" att-mnemonic\n" ++ " Display instruction in AT&T mnemonic\n")); ++ fprintf (stream, _(" intel-mnemonic\n" ++ " Display instruction in Intel mnemonic\n")); ++ fprintf (stream, _(" addr64 Assume 64bit address size\n")); ++ fprintf (stream, _(" addr32 Assume 32bit address size\n")); ++ fprintf (stream, _(" addr16 Assume 16bit address size\n")); ++ fprintf (stream, _(" data32 Assume 32bit data size\n")); ++ fprintf (stream, _(" data16 Assume 16bit data size\n")); ++ fprintf (stream, _(" suffix Always display instruction suffix in AT&T syntax\n")); ++} ++ ++/* Get a pointer to struct dis386 with a valid name. */ ++ ++static const struct dis386 * ++get_valid_dis386 (const struct dis386 *dp, disassemble_info *info) ++{ ++ int index; ++ ++ if (dp->name != NULL) ++ return dp; ++ ++ switch (dp->op[0].bytemode) ++ { ++ case USE_REG_TABLE: ++ dp = ®_table[dp->op[1].bytemode][modrm.reg]; ++ break; ++ ++ case USE_MOD_TABLE: ++ index = modrm.mod == 0x3 ? 1 : 0; ++ dp = &mod_table[dp->op[1].bytemode][index]; ++ break; ++ ++ case USE_RM_TABLE: ++ dp = &rm_table[dp->op[1].bytemode][modrm.rm]; ++ break; ++ ++ case USE_PREFIX_TABLE: ++ index = 0; ++ used_prefixes |= (prefixes & PREFIX_REPZ); ++ if (prefixes & PREFIX_REPZ) ++ { ++ index = 1; ++ repz_prefix = NULL; ++ } ++ else ++ { ++ /* We should check PREFIX_REPNZ and PREFIX_REPZ before ++ PREFIX_DATA. */ ++ used_prefixes |= (prefixes & PREFIX_REPNZ); ++ if (prefixes & PREFIX_REPNZ) ++ { ++ index = 3; ++ repnz_prefix = NULL; ++ } ++ else ++ { ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ if (prefixes & PREFIX_DATA) ++ { ++ index = 2; ++ data_prefix = NULL; ++ } ++ } ++ } ++ dp = &prefix_table[dp->op[1].bytemode][index]; ++ break; ++ ++ case USE_X86_64_TABLE: ++ index = address_mode == mode_64bit ? 1 : 0; ++ dp = &x86_64_table[dp->op[1].bytemode][index]; ++ break; ++ ++ case USE_3BYTE_TABLE: ++ FETCH_DATA (info, codep + 2); ++ index = *codep++; ++ dp = &three_byte_table[dp->op[1].bytemode][index]; ++ modrm.mod = (*codep >> 6) & 3; ++ modrm.reg = (*codep >> 3) & 7; ++ modrm.rm = *codep & 7; ++ break; ++ ++ default: ++ oappend (INTERNAL_DISASSEMBLER_ERROR); ++ return NULL; ++ } ++ ++ if (dp->name != NULL) ++ return dp; ++ else ++ return get_valid_dis386 (dp, info); ++} ++ + static int + print_insn (bfd_vma pc, disassemble_info *info) + { + const struct dis386 *dp; + int i; +- int two_source_ops; +- char *first, *second, *third; ++ char *op_txt[MAX_OPERANDS]; + int needcomma; +- unsigned char uses_SSE_prefix; + int sizeflag; + const char *p; + struct dis_private priv; +- +- mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax +- || info->mach == bfd_mach_x86_64); ++ unsigned char op; ++ char prefix_obuf[32]; ++ char *prefix_obufp; ++ ++ if (info->mach == bfd_mach_x86_64_intel_syntax ++ || info->mach == bfd_mach_x86_64) ++ address_mode = mode_64bit; ++ else ++ address_mode = mode_32bit; + + if (intel_syntax == (char) -1) + intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax +@@ -1944,44 +5271,58 @@ print_insn (bfd_vma pc, disassemble_info + + for (p = info->disassembler_options; p != NULL; ) + { +- if (strncmp (p, "x86-64", 6) == 0) ++ if (CONST_STRNEQ (p, "x86-64")) + { +- mode_64bit = 1; ++ address_mode = mode_64bit; + priv.orig_sizeflag = AFLAG | DFLAG; + } +- else if (strncmp (p, "i386", 4) == 0) ++ else if (CONST_STRNEQ (p, "i386")) + { +- mode_64bit = 0; ++ address_mode = mode_32bit; + priv.orig_sizeflag = AFLAG | DFLAG; + } +- else if (strncmp (p, "i8086", 5) == 0) ++ else if (CONST_STRNEQ (p, "i8086")) + { +- mode_64bit = 0; ++ address_mode = mode_16bit; + priv.orig_sizeflag = 0; + } +- else if (strncmp (p, "intel", 5) == 0) ++ else if (CONST_STRNEQ (p, "intel")) + { + intel_syntax = 1; ++ if (CONST_STRNEQ (p + 5, "-mnemonic")) ++ intel_mnemonic = 1; + } +- else if (strncmp (p, "att", 3) == 0) ++ else if (CONST_STRNEQ (p, "att")) + { + intel_syntax = 0; ++ if (CONST_STRNEQ (p + 3, "-mnemonic")) ++ intel_mnemonic = 0; + } +- else if (strncmp (p, "addr", 4) == 0) ++ else if (CONST_STRNEQ (p, "addr")) + { +- if (p[4] == '1' && p[5] == '6') +- priv.orig_sizeflag &= ~AFLAG; +- else if (p[4] == '3' && p[5] == '2') +- priv.orig_sizeflag |= AFLAG; ++ if (address_mode == mode_64bit) ++ { ++ if (p[4] == '3' && p[5] == '2') ++ priv.orig_sizeflag &= ~AFLAG; ++ else if (p[4] == '6' && p[5] == '4') ++ priv.orig_sizeflag |= AFLAG; ++ } ++ else ++ { ++ if (p[4] == '1' && p[5] == '6') ++ priv.orig_sizeflag &= ~AFLAG; ++ else if (p[4] == '3' && p[5] == '2') ++ priv.orig_sizeflag |= AFLAG; ++ } + } +- else if (strncmp (p, "data", 4) == 0) ++ else if (CONST_STRNEQ (p, "data")) + { + if (p[4] == '1' && p[5] == '6') + priv.orig_sizeflag &= ~DFLAG; + else if (p[4] == '3' && p[5] == '2') + priv.orig_sizeflag |= DFLAG; + } +- else if (strncmp (p, "suffix", 6) == 0) ++ else if (CONST_STRNEQ (p, "suffix")) + priv.orig_sizeflag |= SUFFIX_ALWAYS; + + p = strchr (p, ','); +@@ -1997,6 +5338,8 @@ print_insn (bfd_vma pc, disassemble_info + names8 = intel_names8; + names8rex = intel_names8rex; + names_seg = intel_names_seg; ++ index64 = intel_index64; ++ index32 = intel_index32; + index16 = intel_index16; + open_char = '['; + close_char = ']'; +@@ -2011,6 +5354,8 @@ print_insn (bfd_vma pc, disassemble_info + names8 = att_names8; + names8rex = att_names8rex; + names_seg = att_names_seg; ++ index64 = att_index64; ++ index32 = att_index32; + index16 = att_index16; + open_char = '('; + close_char = ')'; +@@ -2027,11 +5372,11 @@ print_insn (bfd_vma pc, disassemble_info + priv.insn_start = pc; + + obuf[0] = 0; +- op1out[0] = 0; +- op2out[0] = 0; +- op3out[0] = 0; +- +- op_index[0] = op_index[1] = op_index[2] = -1; ++ for (i = 0; i < MAX_OPERANDS; ++i) ++ { ++ op_out[i][0] = 0; ++ op_index[i] = -1; ++ } + + the_info = info; + start_pc = pc; +@@ -2072,13 +5417,14 @@ print_insn (bfd_vma pc, disassemble_info + FETCH_DATA (info, codep + 1); + two_source_ops = (*codep == 0x62) || (*codep == 0xc8); + +- if ((prefixes & PREFIX_FWAIT) +- && ((*codep < 0xd8) || (*codep > 0xdf))) ++ if (((prefixes & PREFIX_FWAIT) ++ && ((*codep < 0xd8) || (*codep > 0xdf))) ++ || (rex && rex_used)) + { + const char *name; + +- /* fwait not followed by floating point instruction. Print the +- first prefix, which is probably fwait itself. */ ++ /* fwait not followed by floating point instruction, or rex followed ++ by other prefixes. Print the first prefix. */ + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag); + if (name == NULL) + name = INTERNAL_DISASSEMBLER_ERROR; +@@ -2086,65 +5432,77 @@ print_insn (bfd_vma pc, disassemble_info + return 1; + } + ++ op = 0; + if (*codep == 0x0f) + { ++ unsigned char threebyte; + FETCH_DATA (info, codep + 2); +- dp = &dis386_twobyte[*++codep]; ++ threebyte = *++codep; ++ dp = &dis386_twobyte[threebyte]; + need_modrm = twobyte_has_modrm[*codep]; +- uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep]; + if (dp->name && strcmp(dp->name, "ud2a") == 0) { + extern int kernel_BUG_encoding_bytes(void); + codep += kernel_BUG_encoding_bytes(); + } ++ codep++; + } + else + { + dp = &dis386[*codep]; + need_modrm = onebyte_has_modrm[*codep]; +- uses_SSE_prefix = 0; ++ codep++; + } +- codep++; + +- if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ)) ++ if ((prefixes & PREFIX_REPZ)) + { +- oappend ("repz "); ++ repz_prefix = "repz "; + used_prefixes |= PREFIX_REPZ; + } +- if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ)) ++ else ++ repz_prefix = NULL; ++ ++ if ((prefixes & PREFIX_REPNZ)) + { +- oappend ("repnz "); ++ repnz_prefix = "repnz "; + used_prefixes |= PREFIX_REPNZ; + } +- if (prefixes & PREFIX_LOCK) ++ else ++ repnz_prefix = NULL; ++ ++ if ((prefixes & PREFIX_LOCK)) + { +- oappend ("lock "); ++ lock_prefix = "lock "; + used_prefixes |= PREFIX_LOCK; + } ++ else ++ lock_prefix = NULL; + ++ addr_prefix = NULL; + if (prefixes & PREFIX_ADDR) + { + sizeflag ^= AFLAG; +- if (dp->bytemode3 != loop_jcxz_mode || intel_syntax) ++ if (dp->op[2].bytemode != loop_jcxz_mode || intel_syntax) + { +- if ((sizeflag & AFLAG) || mode_64bit) +- oappend ("addr32 "); ++ if ((sizeflag & AFLAG) || address_mode == mode_64bit) ++ addr_prefix = "addr32 "; + else +- oappend ("addr16 "); ++ addr_prefix = "addr16 "; + used_prefixes |= PREFIX_ADDR; + } + } + +- if (!uses_SSE_prefix && (prefixes & PREFIX_DATA)) ++ data_prefix = NULL; ++ if ((prefixes & PREFIX_DATA)) + { + sizeflag ^= DFLAG; +- if (dp->bytemode3 == cond_jump_mode +- && dp->bytemode1 == v_mode ++ if (dp->op[2].bytemode == cond_jump_mode ++ && dp->op[0].bytemode == v_mode + && !intel_syntax) + { + if (sizeflag & DFLAG) +- oappend ("data32 "); ++ data_prefix = "data32 "; + else +- oappend ("data16 "); ++ data_prefix = "data16 "; + used_prefixes |= PREFIX_DATA; + } + } +@@ -2152,73 +5510,28 @@ print_insn (bfd_vma pc, disassemble_info + if (need_modrm) + { + FETCH_DATA (info, codep + 1); +- mod = (*codep >> 6) & 3; +- reg = (*codep >> 3) & 7; +- rm = *codep & 7; ++ modrm.mod = (*codep >> 6) & 3; ++ modrm.reg = (*codep >> 3) & 7; ++ modrm.rm = *codep & 7; + } + +- if (dp->name == NULL && dp->bytemode1 == FLOATCODE) ++ if (dp->name == NULL && dp->op[0].bytemode == FLOATCODE) + { + dofloat (sizeflag); + } + else + { +- int index; +- if (dp->name == NULL) +- { +- switch (dp->bytemode1) ++ dp = get_valid_dis386 (dp, info); ++ if (dp != NULL && putop (dp->name, sizeflag) == 0) ++ { ++ for (i = 0; i < MAX_OPERANDS; ++i) + { +- case USE_GROUPS: +- dp = &grps[dp->bytemode2][reg]; +- break; +- +- case USE_PREFIX_USER_TABLE: +- index = 0; +- used_prefixes |= (prefixes & PREFIX_REPZ); +- if (prefixes & PREFIX_REPZ) +- index = 1; +- else +- { +- used_prefixes |= (prefixes & PREFIX_DATA); +- if (prefixes & PREFIX_DATA) +- index = 2; +- else +- { +- used_prefixes |= (prefixes & PREFIX_REPNZ); +- if (prefixes & PREFIX_REPNZ) +- index = 3; +- } +- } +- dp = &prefix_user_table[dp->bytemode2][index]; +- break; +- +- case X86_64_SPECIAL: +- dp = &x86_64_table[dp->bytemode2][mode_64bit]; +- break; +- +- default: +- oappend (INTERNAL_DISASSEMBLER_ERROR); +- break; ++ obufp = op_out[i]; ++ op_ad = MAX_OPERANDS - 1 - i; ++ if (dp->op[i].rtn) ++ (*dp->op[i].rtn) (dp->op[i].bytemode, sizeflag); + } + } +- +- if (putop (dp->name, sizeflag) == 0) +- { +- obufp = op1out; +- op_ad = 2; +- if (dp->op1) +- (*dp->op1) (dp->bytemode1, sizeflag); +- +- obufp = op2out; +- op_ad = 1; +- if (dp->op2) +- (*dp->op2) (dp->bytemode2, sizeflag); +- +- obufp = op3out; +- op_ad = 0; +- if (dp->op3) +- (*dp->op3) (dp->bytemode3, sizeflag); +- } + } + + /* See if any prefixes were not used. If so, print the first one +@@ -2244,8 +5557,24 @@ print_insn (bfd_vma pc, disassemble_info + (*info->fprintf_func) (info->stream, "%s ", name); + } + ++ prefix_obuf[0] = 0; ++ prefix_obufp = prefix_obuf; ++ if (lock_prefix) ++ prefix_obufp = stpcpy (prefix_obufp, lock_prefix); ++ if (repz_prefix) ++ prefix_obufp = stpcpy (prefix_obufp, repz_prefix); ++ if (repnz_prefix) ++ prefix_obufp = stpcpy (prefix_obufp, repnz_prefix); ++ if (addr_prefix) ++ prefix_obufp = stpcpy (prefix_obufp, addr_prefix); ++ if (data_prefix) ++ prefix_obufp = stpcpy (prefix_obufp, data_prefix); ++ ++ if (prefix_obuf[0] != 0) ++ (*info->fprintf_func) (info->stream, "%s", prefix_obuf); ++ + obufp = obuf + strlen (obuf); +- for (i = strlen (obuf); i < 6; i++) ++ for (i = strlen (obuf) + strlen (prefix_obuf); i < 6; i++) + oappend (" "); + oappend (" "); + (*info->fprintf_func) (info->stream, "%s", obuf); +@@ -2254,111 +5583,105 @@ print_insn (bfd_vma pc, disassemble_info + order as the intel book; everything else is printed in reverse order. */ + if (intel_syntax || two_source_ops) + { +- first = op1out; +- second = op2out; +- third = op3out; +- op_ad = op_index[0]; +- op_index[0] = op_index[2]; +- op_index[2] = op_ad; ++ bfd_vma riprel; ++ ++ for (i = 0; i < MAX_OPERANDS; ++i) ++ op_txt[i] = op_out[i]; ++ ++ for (i = 0; i < (MAX_OPERANDS >> 1); ++i) ++ { ++ op_ad = op_index[i]; ++ op_index[i] = op_index[MAX_OPERANDS - 1 - i]; ++ op_index[MAX_OPERANDS - 1 - i] = op_ad; ++ riprel = op_riprel[i]; ++ op_riprel[i] = op_riprel [MAX_OPERANDS - 1 - i]; ++ op_riprel[MAX_OPERANDS - 1 - i] = riprel; ++ } + } + else + { +- first = op3out; +- second = op2out; +- third = op1out; ++ for (i = 0; i < MAX_OPERANDS; ++i) ++ op_txt[MAX_OPERANDS - 1 - i] = op_out[i]; + } ++ + needcomma = 0; +- if (*first) +- { +- if (op_index[0] != -1 && !op_riprel[0]) +- (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info); +- else +- (*info->fprintf_func) (info->stream, "%s", first); +- needcomma = 1; +- } +- if (*second) +- { +- if (needcomma) +- (*info->fprintf_func) (info->stream, ","); +- if (op_index[1] != -1 && !op_riprel[1]) +- (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info); +- else +- (*info->fprintf_func) (info->stream, "%s", second); +- needcomma = 1; +- } +- if (*third) +- { +- if (needcomma) +- (*info->fprintf_func) (info->stream, ","); +- if (op_index[2] != -1 && !op_riprel[2]) +- (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info); +- else +- (*info->fprintf_func) (info->stream, "%s", third); +- } +- for (i = 0; i < 3; i++) ++ for (i = 0; i < MAX_OPERANDS; ++i) ++ if (*op_txt[i]) ++ { ++ if (needcomma) ++ (*info->fprintf_func) (info->stream, ","); ++ if (op_index[i] != -1 && !op_riprel[i]) ++ (*info->print_address_func) ((bfd_vma) op_address[op_index[i]], info); ++ else ++ (*info->fprintf_func) (info->stream, "%s", op_txt[i]); ++ needcomma = 1; ++ } ++ ++ for (i = 0; i < MAX_OPERANDS; i++) + if (op_index[i] != -1 && op_riprel[i]) + { + (*info->fprintf_func) (info->stream, " # "); + (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep + + op_address[op_index[i]]), info); ++ break; + } + return codep - priv.the_buffer; + } + + static const char *float_mem[] = { + /* d8 */ +- "fadd{s||s|}", +- "fmul{s||s|}", +- "fcom{s||s|}", +- "fcomp{s||s|}", +- "fsub{s||s|}", +- "fsubr{s||s|}", +- "fdiv{s||s|}", +- "fdivr{s||s|}", ++ "fadd{s|}", ++ "fmul{s|}", ++ "fcom{s|}", ++ "fcomp{s|}", ++ "fsub{s|}", ++ "fsubr{s|}", ++ "fdiv{s|}", ++ "fdivr{s|}", + /* d9 */ +- "fld{s||s|}", ++ "fld{s|}", + "(bad)", +- "fst{s||s|}", +- "fstp{s||s|}", +- "fldenv", ++ "fst{s|}", ++ "fstp{s|}", ++ "fldenvIC", + "fldcw", +- "fNstenv", ++ "fNstenvIC", + "fNstcw", + /* da */ +- "fiadd{l||l|}", +- "fimul{l||l|}", +- "ficom{l||l|}", +- "ficomp{l||l|}", +- "fisub{l||l|}", +- "fisubr{l||l|}", +- "fidiv{l||l|}", +- "fidivr{l||l|}", ++ "fiadd{l|}", ++ "fimul{l|}", ++ "ficom{l|}", ++ "ficomp{l|}", ++ "fisub{l|}", ++ "fisubr{l|}", ++ "fidiv{l|}", ++ "fidivr{l|}", + /* db */ +- "fild{l||l|}", +- "fisttp{l||l|}", +- "fist{l||l|}", +- "fistp{l||l|}", ++ "fild{l|}", ++ "fisttp{l|}", ++ "fist{l|}", ++ "fistp{l|}", + "(bad)", + "fld{t||t|}", + "(bad)", + "fstp{t||t|}", + /* dc */ +- "fadd{l||l|}", +- "fmul{l||l|}", +- "fcom{l||l|}", +- "fcomp{l||l|}", +- "fsub{l||l|}", +- "fsubr{l||l|}", +- "fdiv{l||l|}", +- "fdivr{l||l|}", ++ "fadd{l|}", ++ "fmul{l|}", ++ "fcom{l|}", ++ "fcomp{l|}", ++ "fsub{l|}", ++ "fsubr{l|}", ++ "fdiv{l|}", ++ "fdivr{l|}", + /* dd */ +- "fld{l||l|}", +- "fisttpll", +- "fst{l||l|}", +- "fstp{l||l|}", +- "frstor", ++ "fld{l|}", ++ "fisttp{ll|}", ++ "fst{l||}", ++ "fstp{l|}", ++ "frstorIC", + "(bad)", +- "fNsave", ++ "fNsaveIC", + "fNstsw", + /* de */ + "fiadd", +@@ -2375,42 +5698,117 @@ static const char *float_mem[] = { + "fist", + "fistp", + "fbld", +- "fild{ll||ll|}", ++ "fild{ll|}", + "fbstp", +- "fistpll", ++ "fistp{ll|}", ++}; ++ ++static const unsigned char float_mem_mode[] = { ++ /* d8 */ ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ /* d9 */ ++ d_mode, ++ 0, ++ d_mode, ++ d_mode, ++ 0, ++ w_mode, ++ 0, ++ w_mode, ++ /* da */ ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ /* db */ ++ d_mode, ++ d_mode, ++ d_mode, ++ d_mode, ++ 0, ++ t_mode, ++ 0, ++ t_mode, ++ /* dc */ ++ q_mode, ++ q_mode, ++ q_mode, ++ q_mode, ++ q_mode, ++ q_mode, ++ q_mode, ++ q_mode, ++ /* dd */ ++ q_mode, ++ q_mode, ++ q_mode, ++ q_mode, ++ 0, ++ 0, ++ 0, ++ w_mode, ++ /* de */ ++ w_mode, ++ w_mode, ++ w_mode, ++ w_mode, ++ w_mode, ++ w_mode, ++ w_mode, ++ w_mode, ++ /* df */ ++ w_mode, ++ w_mode, ++ w_mode, ++ w_mode, ++ t_mode, ++ q_mode, ++ t_mode, ++ q_mode + }; + +-#define ST OP_ST, 0 +-#define STi OP_STi, 0 ++#define ST { OP_ST, 0 } ++#define STi { OP_STi, 0 } + +-#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0 +-#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0 +-#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0 +-#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0 +-#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0 +-#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0 +-#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0 +-#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0 +-#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0 ++#define FGRPd9_2 NULL, { { NULL, 0 } } ++#define FGRPd9_4 NULL, { { NULL, 1 } } ++#define FGRPd9_5 NULL, { { NULL, 2 } } ++#define FGRPd9_6 NULL, { { NULL, 3 } } ++#define FGRPd9_7 NULL, { { NULL, 4 } } ++#define FGRPda_5 NULL, { { NULL, 5 } } ++#define FGRPdb_4 NULL, { { NULL, 6 } } ++#define FGRPde_3 NULL, { { NULL, 7 } } ++#define FGRPdf_4 NULL, { { NULL, 8 } } + + static const struct dis386 float_reg[][8] = { + /* d8 */ + { +- { "fadd", ST, STi, XX }, +- { "fmul", ST, STi, XX }, +- { "fcom", STi, XX, XX }, +- { "fcomp", STi, XX, XX }, +- { "fsub", ST, STi, XX }, +- { "fsubr", ST, STi, XX }, +- { "fdiv", ST, STi, XX }, +- { "fdivr", ST, STi, XX }, ++ { "fadd", { ST, STi } }, ++ { "fmul", { ST, STi } }, ++ { "fcom", { STi } }, ++ { "fcomp", { STi } }, ++ { "fsub", { ST, STi } }, ++ { "fsubr", { ST, STi } }, ++ { "fdiv", { ST, STi } }, ++ { "fdivr", { ST, STi } }, + }, + /* d9 */ + { +- { "fld", STi, XX, XX }, +- { "fxch", STi, XX, XX }, ++ { "fld", { STi } }, ++ { "fxch", { STi } }, + { FGRPd9_2 }, +- { "(bad)", XX, XX, XX }, ++ { "(bad)", { XX } }, + { FGRPd9_4 }, + { FGRPd9_5 }, + { FGRPd9_6 }, +@@ -2418,83 +5816,69 @@ static const struct dis386 float_reg[][8 + }, + /* da */ + { +- { "fcmovb", ST, STi, XX }, +- { "fcmove", ST, STi, XX }, +- { "fcmovbe",ST, STi, XX }, +- { "fcmovu", ST, STi, XX }, +- { "(bad)", XX, XX, XX }, ++ { "fcmovb", { ST, STi } }, ++ { "fcmove", { ST, STi } }, ++ { "fcmovbe",{ ST, STi } }, ++ { "fcmovu", { ST, STi } }, ++ { "(bad)", { XX } }, + { FGRPda_5 }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, + }, + /* db */ + { +- { "fcmovnb",ST, STi, XX }, +- { "fcmovne",ST, STi, XX }, +- { "fcmovnbe",ST, STi, XX }, +- { "fcmovnu",ST, STi, XX }, ++ { "fcmovnb",{ ST, STi } }, ++ { "fcmovne",{ ST, STi } }, ++ { "fcmovnbe",{ ST, STi } }, ++ { "fcmovnu",{ ST, STi } }, + { FGRPdb_4 }, +- { "fucomi", ST, STi, XX }, +- { "fcomi", ST, STi, XX }, +- { "(bad)", XX, XX, XX }, ++ { "fucomi", { ST, STi } }, ++ { "fcomi", { ST, STi } }, ++ { "(bad)", { XX } }, + }, + /* dc */ + { +- { "fadd", STi, ST, XX }, +- { "fmul", STi, ST, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +-#if UNIXWARE_COMPAT +- { "fsub", STi, ST, XX }, +- { "fsubr", STi, ST, XX }, +- { "fdiv", STi, ST, XX }, +- { "fdivr", STi, ST, XX }, +-#else +- { "fsubr", STi, ST, XX }, +- { "fsub", STi, ST, XX }, +- { "fdivr", STi, ST, XX }, +- { "fdiv", STi, ST, XX }, +-#endif ++ { "fadd", { STi, ST } }, ++ { "fmul", { STi, ST } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "fsub!M", { STi, ST } }, ++ { "fsubM", { STi, ST } }, ++ { "fdiv!M", { STi, ST } }, ++ { "fdivM", { STi, ST } }, + }, + /* dd */ + { +- { "ffree", STi, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "fst", STi, XX, XX }, +- { "fstp", STi, XX, XX }, +- { "fucom", STi, XX, XX }, +- { "fucomp", STi, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, ++ { "ffree", { STi } }, ++ { "(bad)", { XX } }, ++ { "fst", { STi } }, ++ { "fstp", { STi } }, ++ { "fucom", { STi } }, ++ { "fucomp", { STi } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, + }, + /* de */ + { +- { "faddp", STi, ST, XX }, +- { "fmulp", STi, ST, XX }, +- { "(bad)", XX, XX, XX }, ++ { "faddp", { STi, ST } }, ++ { "fmulp", { STi, ST } }, ++ { "(bad)", { XX } }, + { FGRPde_3 }, +-#if UNIXWARE_COMPAT +- { "fsubp", STi, ST, XX }, +- { "fsubrp", STi, ST, XX }, +- { "fdivp", STi, ST, XX }, +- { "fdivrp", STi, ST, XX }, +-#else +- { "fsubrp", STi, ST, XX }, +- { "fsubp", STi, ST, XX }, +- { "fdivrp", STi, ST, XX }, +- { "fdivp", STi, ST, XX }, +-#endif ++ { "fsub!Mp", { STi, ST } }, ++ { "fsubMp", { STi, ST } }, ++ { "fdiv!Mp", { STi, ST } }, ++ { "fdivMp", { STi, ST } }, + }, + /* df */ + { +- { "ffreep", STi, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, +- { "(bad)", XX, XX, XX }, ++ { "ffreep", { STi } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, ++ { "(bad)", { XX } }, + { FGRPdf_4 }, +- { "fucomip",ST, STi, XX }, +- { "fcomip", ST, STi, XX }, +- { "(bad)", XX, XX, XX }, ++ { "fucomip", { ST, STi } }, ++ { "fcomip", { ST, STi } }, ++ { "(bad)", { XX } }, + }, + }; + +@@ -2547,6 +5931,15 @@ static char *fgrps[][8] = { + }; + + static void ++OP_Skip_MODRM (int bytemode ATTRIBUTE_UNUSED, ++ int sizeflag ATTRIBUTE_UNUSED) ++{ ++ /* Skip mod/rm byte. */ ++ MODRM_CHECK; ++ codep++; ++} ++ ++static void + dofloat (int sizeflag) + { + const struct dis386 *dp; +@@ -2554,54 +5947,55 @@ dofloat (int sizeflag) + + floatop = codep[-1]; + +- if (mod != 3) ++ if (modrm.mod != 3) + { +- putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag); +- obufp = op1out; +- if (floatop == 0xdb) +- OP_E (x_mode, sizeflag); +- else if (floatop == 0xdd) +- OP_E (d_mode, sizeflag); +- else +- OP_E (v_mode, sizeflag); ++ int fp_indx = (floatop - 0xd8) * 8 + modrm.reg; ++ ++ putop (float_mem[fp_indx], sizeflag); ++ obufp = op_out[0]; ++ op_ad = 2; ++ OP_E (float_mem_mode[fp_indx], sizeflag); + return; + } + /* Skip mod/rm byte. */ + MODRM_CHECK; + codep++; + +- dp = &float_reg[floatop - 0xd8][reg]; ++ dp = &float_reg[floatop - 0xd8][modrm.reg]; + if (dp->name == NULL) + { +- putop (fgrps[dp->bytemode1][rm], sizeflag); ++ putop (fgrps[dp->op[0].bytemode][modrm.rm], sizeflag); + + /* Instruction fnstsw is only one with strange arg. */ + if (floatop == 0xdf && codep[-1] == 0xe0) +- strcpy (op1out, names16[0]); ++ strcpy (op_out[0], names16[0]); + } + else + { + putop (dp->name, sizeflag); + +- obufp = op1out; +- if (dp->op1) +- (*dp->op1) (dp->bytemode1, sizeflag); +- obufp = op2out; +- if (dp->op2) +- (*dp->op2) (dp->bytemode2, sizeflag); ++ obufp = op_out[0]; ++ op_ad = 2; ++ if (dp->op[0].rtn) ++ (*dp->op[0].rtn) (dp->op[0].bytemode, sizeflag); ++ ++ obufp = op_out[1]; ++ op_ad = 1; ++ if (dp->op[1].rtn) ++ (*dp->op[1].rtn) (dp->op[1].bytemode, sizeflag); + } + } + + static void + OP_ST (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { +- oappend ("%st"); ++ oappend ("%st" + intel_syntax); + } + + static void + OP_STi (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { +- sprintf (scratchbuf, "%%st(%d)", rm); ++ sprintf (scratchbuf, "%%st(%d)", modrm.rm); + oappend (scratchbuf + intel_syntax); + } + +@@ -2610,7 +6004,16 @@ static int + putop (const char *template, int sizeflag) + { + const char *p; +- int alt; ++ int alt = 0; ++ int cond = 1; ++ unsigned int l = 0, len = 1; ++ char last[4]; ++ ++#define SAVE_LAST(c) \ ++ if (l < len && l < sizeof (last)) \ ++ last[l++] = c; \ ++ else \ ++ abort (); + + for (p = template; *p; p++) + { +@@ -2619,29 +6022,24 @@ putop (const char *template, int sizefla + default: + *obufp++ = *p; + break; ++ case '%': ++ len++; ++ break; ++ case '!': ++ cond = 0; ++ break; + case '{': + alt = 0; + if (intel_syntax) +- alt += 1; +- if (mode_64bit) +- alt += 2; +- while (alt != 0) + { + while (*++p != '|') +- { +- if (*p == '}') +- { +- /* Alternative not valid. */ +- strcpy (obuf, "(bad)"); +- obufp = obuf + 5; +- return 1; +- } +- else if (*p == '\0') +- abort (); +- } +- alt--; ++ if (*p == '}' || *p == '\0') ++ abort (); + } +- break; ++ /* Fall through. */ ++ case 'I': ++ alt = 1; ++ continue; + case '|': + while (*++p != '}') + { +@@ -2654,7 +6052,7 @@ putop (const char *template, int sizefla + case 'A': + if (intel_syntax) + break; +- if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) ++ if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS)) + *obufp++ = 'b'; + break; + case 'B': +@@ -2663,8 +6061,37 @@ putop (const char *template, int sizefla + if (sizeflag & SUFFIX_ALWAYS) + *obufp++ = 'b'; + break; ++ case 'C': ++ if (intel_syntax && !alt) ++ break; ++ if ((prefixes & PREFIX_DATA) || (sizeflag & SUFFIX_ALWAYS)) ++ { ++ if (sizeflag & DFLAG) ++ *obufp++ = intel_syntax ? 'd' : 'l'; ++ else ++ *obufp++ = intel_syntax ? 'w' : 's'; ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ } ++ break; ++ case 'D': ++ if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS)) ++ break; ++ USED_REX (REX_W); ++ if (modrm.mod == 3) ++ { ++ if (rex & REX_W) ++ *obufp++ = 'q'; ++ else if (sizeflag & DFLAG) ++ *obufp++ = intel_syntax ? 'd' : 'l'; ++ else ++ *obufp++ = 'w'; ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ } ++ else ++ *obufp++ = 'w'; ++ break; + case 'E': /* For jcxz/jecxz */ +- if (mode_64bit) ++ if (address_mode == mode_64bit) + { + if (sizeflag & AFLAG) + *obufp++ = 'r'; +@@ -2682,12 +6109,22 @@ putop (const char *template, int sizefla + if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS)) + { + if (sizeflag & AFLAG) +- *obufp++ = mode_64bit ? 'q' : 'l'; ++ *obufp++ = address_mode == mode_64bit ? 'q' : 'l'; + else +- *obufp++ = mode_64bit ? 'l' : 'w'; ++ *obufp++ = address_mode == mode_64bit ? 'l' : 'w'; + used_prefixes |= (prefixes & PREFIX_ADDR); + } + break; ++ case 'G': ++ if (intel_syntax || (obufp[-1] != 's' && !(sizeflag & SUFFIX_ALWAYS))) ++ break; ++ if ((rex & REX_W) || (sizeflag & DFLAG)) ++ *obufp++ = 'l'; ++ else ++ *obufp++ = 'w'; ++ if (!(rex & REX_W)) ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; + case 'H': + if (intel_syntax) + break; +@@ -2703,12 +6140,44 @@ putop (const char *template, int sizefla + *obufp++ = 'n'; + } + break; ++ case 'J': ++ if (intel_syntax) ++ break; ++ *obufp++ = 'l'; ++ break; ++ case 'K': ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ *obufp++ = 'q'; ++ else ++ *obufp++ = 'd'; ++ break; ++ case 'Z': ++ if (intel_syntax) ++ break; ++ if (address_mode == mode_64bit && (sizeflag & SUFFIX_ALWAYS)) ++ { ++ *obufp++ = 'q'; ++ break; ++ } ++ /* Fall through. */ ++ goto case_L; + case 'L': ++ if (l != 0 || len != 1) ++ { ++ SAVE_LAST (*p); ++ break; ++ } ++case_L: + if (intel_syntax) + break; + if (sizeflag & SUFFIX_ALWAYS) + *obufp++ = 'l'; + break; ++ case 'M': ++ if (intel_mnemonic != cond) ++ *obufp++ = 'r'; ++ break; + case 'N': + if ((prefixes & PREFIX_FWAIT) == 0) + *obufp++ = 'n'; +@@ -2716,16 +6185,20 @@ putop (const char *template, int sizefla + used_prefixes |= PREFIX_FWAIT; + break; + case 'O': +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ USED_REX (REX_W); ++ if (rex & REX_W) + *obufp++ = 'o'; ++ else if (intel_syntax && (sizeflag & DFLAG)) ++ *obufp++ = 'q'; + else + *obufp++ = 'd'; ++ if (!(rex & REX_W)) ++ used_prefixes |= (prefixes & PREFIX_DATA); + break; + case 'T': + if (intel_syntax) + break; +- if (mode_64bit) ++ if (address_mode == mode_64bit && (sizeflag & DFLAG)) + { + *obufp++ = 'q'; + break; +@@ -2735,11 +6208,11 @@ putop (const char *template, int sizefla + if (intel_syntax) + break; + if ((prefixes & PREFIX_DATA) +- || (rex & REX_MODE64) ++ || (rex & REX_W) + || (sizeflag & SUFFIX_ALWAYS)) + { +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ USED_REX (REX_W); ++ if (rex & REX_W) + *obufp++ = 'q'; + else + { +@@ -2747,75 +6220,96 @@ putop (const char *template, int sizefla + *obufp++ = 'l'; + else + *obufp++ = 'w'; +- used_prefixes |= (prefixes & PREFIX_DATA); + } ++ used_prefixes |= (prefixes & PREFIX_DATA); + } + break; + case 'U': + if (intel_syntax) + break; +- if (mode_64bit) ++ if (address_mode == mode_64bit && (sizeflag & DFLAG)) + { +- *obufp++ = 'q'; ++ if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS)) ++ *obufp++ = 'q'; + break; + } + /* Fall through. */ ++ goto case_Q; + case 'Q': +- if (intel_syntax) +- break; +- USED_REX (REX_MODE64); +- if (mod != 3 || (sizeflag & SUFFIX_ALWAYS)) ++ if (l == 0 && len == 1) + { +- if (rex & REX_MODE64) +- *obufp++ = 'q'; +- else ++case_Q: ++ if (intel_syntax && !alt) ++ break; ++ USED_REX (REX_W); ++ if (modrm.mod != 3 || (sizeflag & SUFFIX_ALWAYS)) + { +- if (sizeflag & DFLAG) +- *obufp++ = 'l'; ++ if (rex & REX_W) ++ *obufp++ = 'q'; + else +- *obufp++ = 'w'; ++ { ++ if (sizeflag & DFLAG) ++ *obufp++ = intel_syntax ? 'd' : 'l'; ++ else ++ *obufp++ = 'w'; ++ } + used_prefixes |= (prefixes & PREFIX_DATA); + } + } +- break; +- case 'R': +- USED_REX (REX_MODE64); +- if (intel_syntax) ++ else + { +- if (rex & REX_MODE64) ++ if (l != 1 || len != 2 || last[0] != 'L') + { +- *obufp++ = 'q'; +- *obufp++ = 't'; ++ SAVE_LAST (*p); ++ break; + } +- else if (sizeflag & DFLAG) ++ if (intel_syntax ++ || (modrm.mod == 3 && !(sizeflag & SUFFIX_ALWAYS))) ++ break; ++ if ((rex & REX_W)) + { +- *obufp++ = 'd'; ++ USED_REX (REX_W); + *obufp++ = 'q'; + } + else +- { +- *obufp++ = 'w'; +- *obufp++ = 'd'; +- } ++ *obufp++ = 'l'; + } +- else ++ break; ++ case 'R': ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ *obufp++ = 'q'; ++ else if (sizeflag & DFLAG) + { +- if (rex & REX_MODE64) +- *obufp++ = 'q'; +- else if (sizeflag & DFLAG) +- *obufp++ = 'l'; ++ if (intel_syntax) ++ *obufp++ = 'd'; + else +- *obufp++ = 'w'; ++ *obufp++ = 'l'; + } +- if (!(rex & REX_MODE64)) ++ else ++ *obufp++ = 'w'; ++ if (intel_syntax && !p[1] ++ && ((rex & REX_W) || (sizeflag & DFLAG))) ++ *obufp++ = 'e'; ++ if (!(rex & REX_W)) + used_prefixes |= (prefixes & PREFIX_DATA); + break; ++ case 'V': ++ if (intel_syntax) ++ break; ++ if (address_mode == mode_64bit && (sizeflag & DFLAG)) ++ { ++ if (sizeflag & SUFFIX_ALWAYS) ++ *obufp++ = 'q'; ++ break; ++ } ++ /* Fall through. */ + case 'S': + if (intel_syntax) + break; + if (sizeflag & SUFFIX_ALWAYS) + { +- if (rex & REX_MODE64) ++ if (rex & REX_W) + *obufp++ = 'q'; + else + { +@@ -2835,45 +6329,34 @@ putop (const char *template, int sizefla + used_prefixes |= (prefixes & PREFIX_DATA); + break; + case 'Y': +- if (intel_syntax) ++ if (intel_syntax || !(sizeflag & SUFFIX_ALWAYS)) + break; +- if (rex & REX_MODE64) ++ if (rex & REX_W) + { +- USED_REX (REX_MODE64); ++ USED_REX (REX_W); + *obufp++ = 'q'; + } + break; + /* implicit operand size 'l' for i386 or 'q' for x86-64 */ + case 'W': + /* operand size flag for cwtl, cbtw */ +- USED_REX (0); +- if (rex) +- *obufp++ = 'l'; ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ { ++ if (intel_syntax) ++ *obufp++ = 'd'; ++ else ++ *obufp++ = 'l'; ++ } + else if (sizeflag & DFLAG) + *obufp++ = 'w'; + else + *obufp++ = 'b'; +- if (intel_syntax) +- { +- if (rex) +- { +- *obufp++ = 'q'; +- *obufp++ = 'e'; +- } +- if (sizeflag & DFLAG) +- { +- *obufp++ = 'd'; +- *obufp++ = 'e'; +- } +- else +- { +- *obufp++ = 'w'; +- } +- } +- if (!rex) ++ if (!(rex & REX_W)) + used_prefixes |= (prefixes & PREFIX_DATA); + break; + } ++ alt = 0; + } + *obufp = 0; + return 0; +@@ -2932,7 +6415,7 @@ OP_indirE (int bytemode, int sizeflag) + static void + print_operand_value (char *buf, int hex, bfd_vma disp) + { +- if (mode_64bit) ++ if (address_mode == mode_64bit) + { + if (hex) + { +@@ -2986,62 +6469,194 @@ print_operand_value (char *buf, int hex, + } + } + ++/* Put DISP in BUF as signed hex number. */ ++ + static void +-OP_E (int bytemode, int sizeflag) ++print_displacement (char *buf, bfd_vma disp) ++{ ++ bfd_signed_vma val = disp; ++ char tmp[30]; ++ int i, j = 0; ++ ++ if (val < 0) ++ { ++ buf[j++] = '-'; ++ val = -disp; ++ ++ /* Check for possible overflow. */ ++ if (val < 0) ++ { ++ switch (address_mode) ++ { ++ case mode_64bit: ++ strcpy (buf + j, "0x8000000000000000"); ++ break; ++ case mode_32bit: ++ strcpy (buf + j, "0x80000000"); ++ break; ++ case mode_16bit: ++ strcpy (buf + j, "0x8000"); ++ break; ++ } ++ return; ++ } ++ } ++ ++ buf[j++] = '0'; ++ buf[j++] = 'x'; ++ ++ sprintf_vma (tmp, val); ++ for (i = 0; tmp[i] == '0'; i++) ++ continue; ++ if (tmp[i] == '\0') ++ i--; ++ strcpy (buf + j, tmp + i); ++} ++ ++static void ++intel_operand_size (int bytemode, int sizeflag) ++{ ++ switch (bytemode) ++ { ++ case b_mode: ++ case dqb_mode: ++ oappend ("BYTE PTR "); ++ break; ++ case w_mode: ++ case dqw_mode: ++ oappend ("WORD PTR "); ++ break; ++ case stack_v_mode: ++ if (address_mode == mode_64bit && (sizeflag & DFLAG)) ++ { ++ oappend ("QWORD PTR "); ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; ++ } ++ /* FALLTHRU */ ++ case v_mode: ++ case dq_mode: ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ oappend ("QWORD PTR "); ++ else if ((sizeflag & DFLAG) || bytemode == dq_mode) ++ oappend ("DWORD PTR "); ++ else ++ oappend ("WORD PTR "); ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; ++ case z_mode: ++ if ((rex & REX_W) || (sizeflag & DFLAG)) ++ *obufp++ = 'D'; ++ oappend ("WORD PTR "); ++ if (!(rex & REX_W)) ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; ++ case a_mode: ++ if (sizeflag & DFLAG) ++ oappend ("QWORD PTR "); ++ else ++ oappend ("DWORD PTR "); ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; ++ case d_mode: ++ case dqd_mode: ++ oappend ("DWORD PTR "); ++ break; ++ case q_mode: ++ oappend ("QWORD PTR "); ++ break; ++ case m_mode: ++ if (address_mode == mode_64bit) ++ oappend ("QWORD PTR "); ++ else ++ oappend ("DWORD PTR "); ++ break; ++ case f_mode: ++ if (sizeflag & DFLAG) ++ oappend ("FWORD PTR "); ++ else ++ oappend ("DWORD PTR "); ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; ++ case t_mode: ++ oappend ("TBYTE PTR "); ++ break; ++ case x_mode: ++ oappend ("XMMWORD PTR "); ++ break; ++ case o_mode: ++ oappend ("OWORD PTR "); ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ++OP_E_extended (int bytemode, int sizeflag, int has_drex) + { + bfd_vma disp; + int add = 0; + int riprel = 0; +- USED_REX (REX_EXTZ); +- if (rex & REX_EXTZ) ++ USED_REX (REX_B); ++ if (rex & REX_B) + add += 8; + + /* Skip mod/rm byte. */ + MODRM_CHECK; + codep++; + +- if (mod == 3) ++ if (modrm.mod == 3) + { + switch (bytemode) + { + case b_mode: + USED_REX (0); + if (rex) +- oappend (names8rex[rm + add]); ++ oappend (names8rex[modrm.rm + add]); + else +- oappend (names8[rm + add]); ++ oappend (names8[modrm.rm + add]); + break; + case w_mode: +- oappend (names16[rm + add]); ++ oappend (names16[modrm.rm + add]); + break; + case d_mode: +- oappend (names32[rm + add]); ++ oappend (names32[modrm.rm + add]); + break; + case q_mode: +- oappend (names64[rm + add]); ++ oappend (names64[modrm.rm + add]); + break; + case m_mode: +- if (mode_64bit) +- oappend (names64[rm + add]); ++ if (address_mode == mode_64bit) ++ oappend (names64[modrm.rm + add]); + else +- oappend (names32[rm + add]); ++ oappend (names32[modrm.rm + add]); + break; ++ case stack_v_mode: ++ if (address_mode == mode_64bit && (sizeflag & DFLAG)) ++ { ++ oappend (names64[modrm.rm + add]); ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; ++ } ++ bytemode = v_mode; ++ /* FALLTHRU */ + case v_mode: + case dq_mode: +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) +- oappend (names64[rm + add]); +- else if ((sizeflag & DFLAG) || bytemode == dq_mode) +- oappend (names32[rm + add]); ++ case dqb_mode: ++ case dqd_mode: ++ case dqw_mode: ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ oappend (names64[modrm.rm + add]); ++ else if ((sizeflag & DFLAG) || bytemode != v_mode) ++ oappend (names32[modrm.rm + add]); + else +- oappend (names16[rm + add]); ++ oappend (names16[modrm.rm + add]); + used_prefixes |= (prefixes & PREFIX_DATA); + break; + case 0: +- if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */) +- && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */) +- && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */)) +- BadOp (); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */ + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); +@@ -3051,43 +6666,57 @@ OP_E (int bytemode, int sizeflag) + } + + disp = 0; ++ if (intel_syntax) ++ intel_operand_size (bytemode, sizeflag); + append_seg (); + +- if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */ ++ if ((sizeflag & AFLAG) || address_mode == mode_64bit) + { ++ /* 32/64 bit address mode */ ++ int havedisp; + int havesib; + int havebase; +- int base; ++ int haveindex; ++ int needindex; ++ int base, rbase; + int index = 0; + int scale = 0; + + havesib = 0; + havebase = 1; +- base = rm; ++ haveindex = 0; ++ base = modrm.rm; + + if (base == 4) + { + havesib = 1; + FETCH_DATA (the_info, codep + 1); +- scale = (*codep >> 6) & 3; + index = (*codep >> 3) & 7; ++ scale = (*codep >> 6) & 3; + base = *codep & 7; +- USED_REX (REX_EXTY); +- USED_REX (REX_EXTZ); +- if (rex & REX_EXTY) ++ USED_REX (REX_X); ++ if (rex & REX_X) + index += 8; +- if (rex & REX_EXTZ) +- base += 8; ++ haveindex = index != 4; ++ codep++; ++ } ++ rbase = base + add; ++ ++ /* If we have a DREX byte, skip it now ++ (it has already been handled) */ ++ if (has_drex) ++ { ++ FETCH_DATA (the_info, codep + 1); + codep++; + } + +- switch (mod) ++ switch (modrm.mod) + { + case 0: +- if ((base & 7) == 5) ++ if (base == 5) + { + havebase = 0; +- if (mode_64bit && !havesib && (sizeflag & AFLAG)) ++ if (address_mode == mode_64bit && !havesib) + riprel = 1; + disp = get32s (); + } +@@ -3103,111 +6732,103 @@ OP_E (int bytemode, int sizeflag) + break; + } + ++ /* In 32bit mode, we need index register to tell [offset] from ++ [eiz*1 + offset]. */ ++ needindex = (havesib ++ && !havebase ++ && !haveindex ++ && address_mode == mode_32bit); ++ havedisp = (havebase ++ || needindex ++ || (havesib && (haveindex || scale != 0))); ++ + if (!intel_syntax) +- if (mod != 0 || (base & 7) == 5) ++ if (modrm.mod != 0 || base == 5) + { +- print_operand_value (scratchbuf, !riprel, disp); ++ if (havedisp || riprel) ++ print_displacement (scratchbuf, disp); ++ else ++ print_operand_value (scratchbuf, 1, disp); + oappend (scratchbuf); + if (riprel) + { + set_op (disp, 1); +- oappend ("(%rip)"); ++ oappend (sizeflag & AFLAG ? "(%rip)" : "(%eip)"); + } + } + +- if (havebase || (havesib && (index != 4 || scale != 0))) ++ if (havebase || haveindex || riprel) ++ used_prefixes |= PREFIX_ADDR; ++ ++ if (havedisp || (intel_syntax && riprel)) + { +- if (intel_syntax) +- { +- switch (bytemode) +- { +- case b_mode: +- oappend ("BYTE PTR "); +- break; +- case w_mode: +- oappend ("WORD PTR "); +- break; +- case v_mode: +- oappend ("DWORD PTR "); +- break; +- case d_mode: +- oappend ("QWORD PTR "); +- break; +- case m_mode: +- if (mode_64bit) +- oappend ("DWORD PTR "); +- else +- oappend ("QWORD PTR "); +- break; +- case x_mode: +- oappend ("XWORD PTR "); +- break; +- default: +- break; +- } +- } + *obufp++ = open_char; + if (intel_syntax && riprel) +- oappend ("rip + "); ++ { ++ set_op (disp, 1); ++ oappend (sizeflag & AFLAG ? "rip" : "eip"); ++ } + *obufp = '\0'; +- USED_REX (REX_EXTZ); +- if (!havesib && (rex & REX_EXTZ)) +- base += 8; + if (havebase) +- oappend (mode_64bit && (sizeflag & AFLAG) +- ? names64[base] : names32[base]); ++ oappend (address_mode == mode_64bit && (sizeflag & AFLAG) ++ ? names64[rbase] : names32[rbase]); + if (havesib) + { +- if (index != 4) ++ /* ESP/RSP won't allow index. If base isn't ESP/RSP, ++ print index to tell base + index from base. */ ++ if (scale != 0 ++ || needindex ++ || haveindex ++ || (havebase && base != ESP_REG_NUM)) + { +- if (intel_syntax) ++ if (!intel_syntax || havebase) + { +- if (havebase) +- { +- *obufp++ = separator_char; +- *obufp = '\0'; +- } +- sprintf (scratchbuf, "%s", +- mode_64bit && (sizeflag & AFLAG) +- ? names64[index] : names32[index]); ++ *obufp++ = separator_char; ++ *obufp = '\0'; + } +- else +- sprintf (scratchbuf, ",%s", +- mode_64bit && (sizeflag & AFLAG) ++ if (haveindex) ++ oappend (address_mode == mode_64bit ++ && (sizeflag & AFLAG) + ? names64[index] : names32[index]); +- oappend (scratchbuf); +- } +- if (scale != 0 || (!intel_syntax && index != 4)) +- { ++ else ++ oappend (address_mode == mode_64bit ++ && (sizeflag & AFLAG) ++ ? index64 : index32); ++ + *obufp++ = scale_char; + *obufp = '\0'; + sprintf (scratchbuf, "%d", 1 << scale); + oappend (scratchbuf); + } + } +- if (intel_syntax) +- if (mod != 0 || (base & 7) == 5) +- { +- /* Don't print zero displacements. */ +- if (disp != 0) +- { +- if ((bfd_signed_vma) disp > 0) +- { +- *obufp++ = '+'; +- *obufp = '\0'; +- } +- +- print_operand_value (scratchbuf, 0, disp); +- oappend (scratchbuf); +- } +- } ++ if (intel_syntax ++ && (disp || modrm.mod != 0 || base == 5)) ++ { ++ if (!havedisp || (bfd_signed_vma) disp >= 0) ++ { ++ *obufp++ = '+'; ++ *obufp = '\0'; ++ } ++ else if (modrm.mod != 1) ++ { ++ *obufp++ = '-'; ++ *obufp = '\0'; ++ disp = - (bfd_signed_vma) disp; ++ } ++ ++ if (havedisp) ++ print_displacement (scratchbuf, disp); ++ else ++ print_operand_value (scratchbuf, 1, disp); ++ oappend (scratchbuf); ++ } + + *obufp++ = close_char; + *obufp = '\0'; + } + else if (intel_syntax) + { +- if (mod != 0 || (base & 7) == 5) ++ if (modrm.mod != 0 || base == 5) + { + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS + | PREFIX_ES | PREFIX_FS | PREFIX_GS)) +@@ -3224,10 +6845,10 @@ OP_E (int bytemode, int sizeflag) + } + else + { /* 16 bit address mode */ +- switch (mod) ++ switch (modrm.mod) + { + case 0: +- if ((rm & 7) == 6) ++ if (modrm.rm == 6) + { + disp = get16 (); + if ((disp & 0x8000) != 0) +@@ -3248,58 +6869,107 @@ OP_E (int bytemode, int sizeflag) + } + + if (!intel_syntax) +- if (mod != 0 || (rm & 7) == 6) ++ if (modrm.mod != 0 || modrm.rm == 6) + { +- print_operand_value (scratchbuf, 0, disp); ++ print_displacement (scratchbuf, disp); + oappend (scratchbuf); + } + +- if (mod != 0 || (rm & 7) != 6) ++ if (modrm.mod != 0 || modrm.rm != 6) + { + *obufp++ = open_char; + *obufp = '\0'; +- oappend (index16[rm + add]); ++ oappend (index16[modrm.rm]); ++ if (intel_syntax ++ && (disp || modrm.mod != 0 || modrm.rm == 6)) ++ { ++ if ((bfd_signed_vma) disp >= 0) ++ { ++ *obufp++ = '+'; ++ *obufp = '\0'; ++ } ++ else if (modrm.mod != 1) ++ { ++ *obufp++ = '-'; ++ *obufp = '\0'; ++ disp = - (bfd_signed_vma) disp; ++ } ++ ++ print_displacement (scratchbuf, disp); ++ oappend (scratchbuf); ++ } ++ + *obufp++ = close_char; + *obufp = '\0'; + } ++ else if (intel_syntax) ++ { ++ if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS ++ | PREFIX_ES | PREFIX_FS | PREFIX_GS)) ++ ; ++ else ++ { ++ oappend (names_seg[ds_reg - es_reg]); ++ oappend (":"); ++ } ++ print_operand_value (scratchbuf, 1, disp & 0xffff); ++ oappend (scratchbuf); ++ } + } + } + + static void ++OP_E (int bytemode, int sizeflag) ++{ ++ OP_E_extended (bytemode, sizeflag, 0); ++} ++ ++ ++static void + OP_G (int bytemode, int sizeflag) + { + int add = 0; +- USED_REX (REX_EXTX); +- if (rex & REX_EXTX) ++ USED_REX (REX_R); ++ if (rex & REX_R) + add += 8; + switch (bytemode) + { + case b_mode: + USED_REX (0); + if (rex) +- oappend (names8rex[reg + add]); ++ oappend (names8rex[modrm.reg + add]); + else +- oappend (names8[reg + add]); ++ oappend (names8[modrm.reg + add]); + break; + case w_mode: +- oappend (names16[reg + add]); ++ oappend (names16[modrm.reg + add]); + break; + case d_mode: +- oappend (names32[reg + add]); ++ oappend (names32[modrm.reg + add]); + break; + case q_mode: +- oappend (names64[reg + add]); ++ oappend (names64[modrm.reg + add]); + break; + case v_mode: +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) +- oappend (names64[reg + add]); +- else if (sizeflag & DFLAG) +- oappend (names32[reg + add]); ++ case dq_mode: ++ case dqb_mode: ++ case dqd_mode: ++ case dqw_mode: ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ oappend (names64[modrm.reg + add]); ++ else if ((sizeflag & DFLAG) || bytemode != v_mode) ++ oappend (names32[modrm.reg + add]); + else +- oappend (names16[reg + add]); ++ oappend (names16[modrm.reg + add]); + used_prefixes |= (prefixes & PREFIX_DATA); + break; ++ case m_mode: ++ if (address_mode == mode_64bit) ++ oappend (names64[modrm.reg + add]); ++ else ++ oappend (names32[modrm.reg + add]); ++ break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + break; +@@ -3375,7 +7045,7 @@ static void + set_op (bfd_vma op, int riprel) + { + op_index[op_ad] = op_ad; +- if (mode_64bit) ++ if (address_mode == mode_64bit) + { + op_address[op_ad] = op; + op_riprel[op_ad] = riprel; +@@ -3392,19 +7062,15 @@ static void + OP_REG (int code, int sizeflag) + { + const char *s; +- int add = 0; +- USED_REX (REX_EXTZ); +- if (rex & REX_EXTZ) ++ int add; ++ USED_REX (REX_B); ++ if (rex & REX_B) + add = 8; ++ else ++ add = 0; + + switch (code) + { +- case indir_dx_reg: +- if (intel_syntax) +- s = "[dx]"; +- else +- s = "(%dx)"; +- break; + case ax_reg: case cx_reg: case dx_reg: case bx_reg: + case sp_reg: case bp_reg: case si_reg: case di_reg: + s = names16[code - ax_reg + add]; +@@ -3423,7 +7089,7 @@ OP_REG (int code, int sizeflag) + break; + case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg: + case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg: +- if (mode_64bit) ++ if (address_mode == mode_64bit && (sizeflag & DFLAG)) + { + s = names64[code - rAX_reg + add]; + break; +@@ -3432,8 +7098,8 @@ OP_REG (int code, int sizeflag) + /* Fall through. */ + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ USED_REX (REX_W); ++ if (rex & REX_W) + s = names64[code - eAX_reg + add]; + else if (sizeflag & DFLAG) + s = names32[code - eAX_reg + add]; +@@ -3457,7 +7123,7 @@ OP_IMREG (int code, int sizeflag) + { + case indir_dx_reg: + if (intel_syntax) +- s = "[dx]"; ++ s = "dx"; + else + s = "(%dx)"; + break; +@@ -3479,8 +7145,8 @@ OP_IMREG (int code, int sizeflag) + break; + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg: + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg: +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ USED_REX (REX_W); ++ if (rex & REX_W) + s = names64[code - eAX_reg]; + else if (sizeflag & DFLAG) + s = names32[code - eAX_reg]; +@@ -3488,6 +7154,14 @@ OP_IMREG (int code, int sizeflag) + s = names16[code - eAX_reg]; + used_prefixes |= (prefixes & PREFIX_DATA); + break; ++ case z_mode_ax_reg: ++ if ((rex & REX_W) || (sizeflag & DFLAG)) ++ s = *names32; ++ else ++ s = *names16; ++ if (!(rex & REX_W)) ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; + default: + s = INTERNAL_DISASSEMBLER_ERROR; + break; +@@ -3509,15 +7183,15 @@ OP_I (int bytemode, int sizeflag) + mask = 0xff; + break; + case q_mode: +- if (mode_64bit) ++ if (address_mode == mode_64bit) + { + op = get32s (); + break; + } + /* Fall through. */ + case v_mode: +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ USED_REX (REX_W); ++ if (rex & REX_W) + op = get32s (); + else if (sizeflag & DFLAG) + { +@@ -3535,6 +7209,10 @@ OP_I (int bytemode, int sizeflag) + mask = 0xfffff; + op = get16 (); + break; ++ case const_1_mode: ++ if (intel_syntax) ++ oappend ("1"); ++ return; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + return; +@@ -3553,7 +7231,7 @@ OP_I64 (int bytemode, int sizeflag) + bfd_signed_vma op; + bfd_signed_vma mask = -1; + +- if (!mode_64bit) ++ if (address_mode != mode_64bit) + { + OP_I (bytemode, sizeflag); + return; +@@ -3567,8 +7245,8 @@ OP_I64 (int bytemode, int sizeflag) + mask = 0xff; + break; + case v_mode: +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ USED_REX (REX_W); ++ if (rex & REX_W) + op = get64 (); + else if (sizeflag & DFLAG) + { +@@ -3614,8 +7292,8 @@ OP_sI (int bytemode, int sizeflag) + mask = 0xffffffff; + break; + case v_mode: +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ USED_REX (REX_W); ++ if (rex & REX_W) + op = get32s (); + else if (sizeflag & DFLAG) + { +@@ -3652,6 +7330,7 @@ OP_J (int bytemode, int sizeflag) + { + bfd_vma disp; + bfd_vma mask = -1; ++ bfd_vma segment = 0; + + switch (bytemode) + { +@@ -3662,31 +7341,41 @@ OP_J (int bytemode, int sizeflag) + disp -= 0x100; + break; + case v_mode: +- if (sizeflag & DFLAG) ++ if ((sizeflag & DFLAG) || (rex & REX_W)) + disp = get32s (); + else + { + disp = get16 (); +- /* For some reason, a data16 prefix on a jump instruction +- means that the pc is masked to 16 bits after the +- displacement is added! */ ++ if ((disp & 0x8000) != 0) ++ disp -= 0x10000; ++ /* In 16bit mode, address is wrapped around at 64k within ++ the same segment. Otherwise, a data16 prefix on a jump ++ instruction means that the pc is masked to 16 bits after ++ the displacement is added! */ + mask = 0xffff; ++ if ((prefixes & PREFIX_DATA) == 0) ++ segment = ((start_pc + codep - start_codep) ++ & ~((bfd_vma) 0xffff)); + } ++ used_prefixes |= (prefixes & PREFIX_DATA); + break; + default: + oappend (INTERNAL_DISASSEMBLER_ERROR); + return; + } +- disp = (start_pc + codep - start_codep + disp) & mask; ++ disp = ((start_pc + codep - start_codep + disp) & mask) | segment; + set_op (disp, 0); + print_operand_value (scratchbuf, 1, disp); + oappend (scratchbuf); + } + + static void +-OP_SEG (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) ++OP_SEG (int bytemode, int sizeflag) + { +- oappend (names_seg[reg]); ++ if (bytemode == w_mode) ++ oappend (names_seg[modrm.reg]); ++ else ++ OP_E (modrm.mod == 3 ? bytemode : w_mode, sizeflag); + } + + static void +@@ -3706,20 +7395,22 @@ OP_DIR (int dummy ATTRIBUTE_UNUSED, int + } + used_prefixes |= (prefixes & PREFIX_DATA); + if (intel_syntax) +- sprintf (scratchbuf, "0x%x,0x%x", seg, offset); ++ sprintf (scratchbuf, "0x%x:0x%x", seg, offset); + else + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset); + oappend (scratchbuf); + } + + static void +-OP_OFF (int bytemode ATTRIBUTE_UNUSED, int sizeflag) ++OP_OFF (int bytemode, int sizeflag) + { + bfd_vma off; + ++ if (intel_syntax && (sizeflag & SUFFIX_ALWAYS)) ++ intel_operand_size (bytemode, sizeflag); + append_seg (); + +- if ((sizeflag & AFLAG) || mode_64bit) ++ if ((sizeflag & AFLAG) || address_mode == mode_64bit) + off = get32 (); + else + off = get16 (); +@@ -3738,16 +7429,19 @@ OP_OFF (int bytemode ATTRIBUTE_UNUSED, i + } + + static void +-OP_OFF64 (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) ++OP_OFF64 (int bytemode, int sizeflag) + { + bfd_vma off; + +- if (!mode_64bit) ++ if (address_mode != mode_64bit ++ || (prefixes & PREFIX_ADDR)) + { + OP_OFF (bytemode, sizeflag); + return; + } + ++ if (intel_syntax && (sizeflag & SUFFIX_ALWAYS)) ++ intel_operand_size (bytemode, sizeflag); + append_seg (); + + off = get64 (); +@@ -3769,13 +7463,10 @@ static void + ptr_reg (int code, int sizeflag) + { + const char *s; +- if (intel_syntax) +- oappend ("["); +- else +- oappend ("("); + +- USED_REX (REX_MODE64); +- if (rex & REX_MODE64) ++ *obufp++ = open_char; ++ used_prefixes |= (prefixes & PREFIX_ADDR); ++ if (address_mode == mode_64bit) + { + if (!(sizeflag & AFLAG)) + s = names32[code - eAX_reg]; +@@ -3787,15 +7478,30 @@ ptr_reg (int code, int sizeflag) + else + s = names16[code - eAX_reg]; + oappend (s); +- if (intel_syntax) +- oappend ("]"); +- else +- oappend (")"); ++ *obufp++ = close_char; ++ *obufp = 0; + } + + static void + OP_ESreg (int code, int sizeflag) + { ++ if (intel_syntax) ++ { ++ switch (codep[-1]) ++ { ++ case 0x6d: /* insw/insl */ ++ intel_operand_size (z_mode, sizeflag); ++ break; ++ case 0xa5: /* movsw/movsl/movsq */ ++ case 0xa7: /* cmpsw/cmpsl/cmpsq */ ++ case 0xab: /* stosw/stosl */ ++ case 0xaf: /* scasw/scasl */ ++ intel_operand_size (v_mode, sizeflag); ++ break; ++ default: ++ intel_operand_size (b_mode, sizeflag); ++ } ++ } + oappend ("%es:" + intel_syntax); + ptr_reg (code, sizeflag); + } +@@ -3803,6 +7509,22 @@ OP_ESreg (int code, int sizeflag) + static void + OP_DSreg (int code, int sizeflag) + { ++ if (intel_syntax) ++ { ++ switch (codep[-1]) ++ { ++ case 0x6f: /* outsw/outsl */ ++ intel_operand_size (z_mode, sizeflag); ++ break; ++ case 0xa5: /* movsw/movsl/movsq */ ++ case 0xa7: /* cmpsw/cmpsl/cmpsq */ ++ case 0xad: /* lodsw/lodsl/lodsq */ ++ intel_operand_size (v_mode, sizeflag); ++ break; ++ default: ++ intel_operand_size (b_mode, sizeflag); ++ } ++ } + if ((prefixes + & (PREFIX_CS + | PREFIX_DS +@@ -3818,39 +7540,51 @@ OP_DSreg (int code, int sizeflag) + static void + OP_C (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { +- int add = 0; +- USED_REX (REX_EXTX); +- if (rex & REX_EXTX) +- add = 8; +- sprintf (scratchbuf, "%%cr%d", reg + add); ++ int add; ++ if (rex & REX_R) ++ { ++ USED_REX (REX_R); ++ add = 8; ++ } ++ else if (address_mode != mode_64bit && (prefixes & PREFIX_LOCK)) ++ { ++ lock_prefix = NULL; ++ used_prefixes |= PREFIX_LOCK; ++ add = 8; ++ } ++ else ++ add = 0; ++ sprintf (scratchbuf, "%%cr%d", modrm.reg + add); + oappend (scratchbuf + intel_syntax); + } + + static void + OP_D (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { +- int add = 0; +- USED_REX (REX_EXTX); +- if (rex & REX_EXTX) ++ int add; ++ USED_REX (REX_R); ++ if (rex & REX_R) + add = 8; ++ else ++ add = 0; + if (intel_syntax) +- sprintf (scratchbuf, "db%d", reg + add); ++ sprintf (scratchbuf, "db%d", modrm.reg + add); + else +- sprintf (scratchbuf, "%%db%d", reg + add); ++ sprintf (scratchbuf, "%%db%d", modrm.reg + add); + oappend (scratchbuf); + } + + static void + OP_T (int dummy ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { +- sprintf (scratchbuf, "%%tr%d", reg); ++ sprintf (scratchbuf, "%%tr%d", modrm.reg); + oappend (scratchbuf + intel_syntax); + } + + static void +-OP_Rd (int bytemode, int sizeflag) ++OP_R (int bytemode, int sizeflag) + { +- if (mod == 3) ++ if (modrm.mod == 3) + OP_E (bytemode, sizeflag); + else + BadOp (); +@@ -3859,77 +7593,130 @@ OP_Rd (int bytemode, int sizeflag) + static void + OP_MMX (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { +- int add = 0; +- USED_REX (REX_EXTX); +- if (rex & REX_EXTX) +- add = 8; + used_prefixes |= (prefixes & PREFIX_DATA); + if (prefixes & PREFIX_DATA) +- sprintf (scratchbuf, "%%xmm%d", reg + add); ++ { ++ int add; ++ USED_REX (REX_R); ++ if (rex & REX_R) ++ add = 8; ++ else ++ add = 0; ++ sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); ++ } + else +- sprintf (scratchbuf, "%%mm%d", reg + add); ++ sprintf (scratchbuf, "%%mm%d", modrm.reg); + oappend (scratchbuf + intel_syntax); + } + + static void + OP_XMM (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { +- int add = 0; +- USED_REX (REX_EXTX); +- if (rex & REX_EXTX) ++ int add; ++ USED_REX (REX_R); ++ if (rex & REX_R) + add = 8; +- sprintf (scratchbuf, "%%xmm%d", reg + add); ++ else ++ add = 0; ++ sprintf (scratchbuf, "%%xmm%d", modrm.reg + add); + oappend (scratchbuf + intel_syntax); + } + + static void + OP_EM (int bytemode, int sizeflag) + { +- int add = 0; +- if (mod != 3) ++ if (modrm.mod != 3) + { ++ if (intel_syntax && bytemode == v_mode) ++ { ++ bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode; ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ } + OP_E (bytemode, sizeflag); + return; + } +- USED_REX (REX_EXTZ); +- if (rex & REX_EXTZ) +- add = 8; + + /* Skip mod/rm byte. */ + MODRM_CHECK; + codep++; + used_prefixes |= (prefixes & PREFIX_DATA); + if (prefixes & PREFIX_DATA) +- sprintf (scratchbuf, "%%xmm%d", rm + add); ++ { ++ int add; ++ ++ USED_REX (REX_B); ++ if (rex & REX_B) ++ add = 8; ++ else ++ add = 0; ++ sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); ++ } + else +- sprintf (scratchbuf, "%%mm%d", rm + add); ++ sprintf (scratchbuf, "%%mm%d", modrm.rm); ++ oappend (scratchbuf + intel_syntax); ++} ++ ++/* cvt* are the only instructions in sse2 which have ++ both SSE and MMX operands and also have 0x66 prefix ++ in their opcode. 0x66 was originally used to differentiate ++ between SSE and MMX instruction(operands). So we have to handle the ++ cvt* separately using OP_EMC and OP_MXC */ ++static void ++OP_EMC (int bytemode, int sizeflag) ++{ ++ if (modrm.mod != 3) ++ { ++ if (intel_syntax && bytemode == v_mode) ++ { ++ bytemode = (prefixes & PREFIX_DATA) ? x_mode : q_mode; ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ } ++ OP_E (bytemode, sizeflag); ++ return; ++ } ++ ++ /* Skip mod/rm byte. */ ++ MODRM_CHECK; ++ codep++; ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ sprintf (scratchbuf, "%%mm%d", modrm.rm); ++ oappend (scratchbuf + intel_syntax); ++} ++ ++static void ++OP_MXC (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) ++{ ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ sprintf (scratchbuf, "%%mm%d", modrm.reg); + oappend (scratchbuf + intel_syntax); + } + + static void + OP_EX (int bytemode, int sizeflag) + { +- int add = 0; +- if (mod != 3) ++ int add; ++ if (modrm.mod != 3) + { + OP_E (bytemode, sizeflag); + return; + } +- USED_REX (REX_EXTZ); +- if (rex & REX_EXTZ) ++ USED_REX (REX_B); ++ if (rex & REX_B) + add = 8; ++ else ++ add = 0; + + /* Skip mod/rm byte. */ + MODRM_CHECK; + codep++; +- sprintf (scratchbuf, "%%xmm%d", rm + add); ++ sprintf (scratchbuf, "%%xmm%d", modrm.rm + add); + oappend (scratchbuf + intel_syntax); + } + + static void + OP_MS (int bytemode, int sizeflag) + { +- if (mod == 3) ++ if (modrm.mod == 3) + OP_EM (bytemode, sizeflag); + else + BadOp (); +@@ -3938,12 +7725,56 @@ OP_MS (int bytemode, int sizeflag) + static void + OP_XS (int bytemode, int sizeflag) + { +- if (mod == 3) ++ if (modrm.mod == 3) + OP_EX (bytemode, sizeflag); + else + BadOp (); + } + ++static void ++OP_M (int bytemode, int sizeflag) ++{ ++ if (modrm.mod == 3) ++ /* bad bound,lea,lds,les,lfs,lgs,lss,cmpxchg8b,vmptrst modrm */ ++ BadOp (); ++ else ++ OP_E (bytemode, sizeflag); ++} ++ ++static void ++OP_0f07 (int bytemode, int sizeflag) ++{ ++ if (modrm.mod != 3 || modrm.rm != 0) ++ BadOp (); ++ else ++ OP_E (bytemode, sizeflag); ++} ++ ++/* NOP is an alias of "xchg %ax,%ax" in 16bit mode, "xchg %eax,%eax" in ++ 32bit mode and "xchg %rax,%rax" in 64bit mode. */ ++ ++static void ++NOP_Fixup1 (int bytemode, int sizeflag) ++{ ++ if ((prefixes & PREFIX_DATA) != 0 ++ || (rex != 0 ++ && rex != 0x48 ++ && address_mode == mode_64bit)) ++ OP_REG (bytemode, sizeflag); ++ else ++ strcpy (obuf, "nop"); ++} ++ ++static void ++NOP_Fixup2 (int bytemode, int sizeflag) ++{ ++ if ((prefixes & PREFIX_DATA) != 0 ++ || (rex != 0 ++ && rex != 0x48 ++ && address_mode == mode_64bit)) ++ OP_IMREG (bytemode, sizeflag); ++} ++ + static const char *const Suffix3DNow[] = { + /* 00 */ NULL, NULL, NULL, NULL, + /* 04 */ NULL, NULL, NULL, NULL, +@@ -3990,7 +7821,7 @@ static const char *const Suffix3DNow[] = + /* A8 */ NULL, NULL, "pfsubr", NULL, + /* AC */ NULL, NULL, "pfacc", NULL, + /* B0 */ "pfcmpeq", NULL, NULL, NULL, +-/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw", ++/* B4 */ "pfmul", NULL, "pfrcpit2", "pmulhrw", + /* B8 */ NULL, NULL, NULL, "pswapd", + /* BC */ NULL, NULL, NULL, "pavgusb", + /* C0 */ NULL, NULL, NULL, NULL, +@@ -4030,8 +7861,8 @@ OP_3DNowSuffix (int bytemode ATTRIBUTE_U + of the opcode (0x0f0f) and the opcode suffix, we need to do + all the modrm processing first, and don't know until now that + we have a bad opcode. This necessitates some cleaning up. */ +- op1out[0] = '\0'; +- op2out[0] = '\0'; ++ op_out[0][0] = '\0'; ++ op_out[1][0] = '\0'; + BadOp (); + } + } +@@ -4048,90 +7879,540 @@ static const char *simd_cmp_op[] = { + }; + + static void +-OP_SIMD_Suffix (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) ++CMP_Fixup (int bytemode ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) + { + unsigned int cmp_type; + + FETCH_DATA (the_info, codep + 1); +- obufp = obuf + strlen (obuf); + cmp_type = *codep++ & 0xff; + if (cmp_type < 8) + { +- char suffix1 = 'p', suffix2 = 's'; +- used_prefixes |= (prefixes & PREFIX_REPZ); +- if (prefixes & PREFIX_REPZ) +- suffix1 = 's'; ++ char suffix [3]; ++ char *p = obuf + strlen (obuf) - 2; ++ suffix[0] = p[0]; ++ suffix[1] = p[1]; ++ suffix[2] = '\0'; ++ sprintf (p, "%s%s", simd_cmp_op[cmp_type], suffix); ++ } ++ else ++ { ++ /* We have a reserved extension byte. Output it directly. */ ++ scratchbuf[0] = '$'; ++ print_operand_value (scratchbuf + 1, 1, cmp_type); ++ oappend (scratchbuf + intel_syntax); ++ scratchbuf[0] = '\0'; ++ } ++} ++ ++static void ++OP_Mwait (int bytemode ATTRIBUTE_UNUSED, ++ int sizeflag ATTRIBUTE_UNUSED) ++{ ++ /* mwait %eax,%ecx */ ++ if (!intel_syntax) ++ { ++ const char **names = (address_mode == mode_64bit ++ ? names64 : names32); ++ strcpy (op_out[0], names[0]); ++ strcpy (op_out[1], names[1]); ++ two_source_ops = 1; ++ } ++ /* Skip mod/rm byte. */ ++ MODRM_CHECK; ++ codep++; ++} ++ ++static void ++OP_Monitor (int bytemode ATTRIBUTE_UNUSED, ++ int sizeflag ATTRIBUTE_UNUSED) ++{ ++ /* monitor %eax,%ecx,%edx" */ ++ if (!intel_syntax) ++ { ++ const char **op1_names; ++ const char **names = (address_mode == mode_64bit ++ ? names64 : names32); ++ ++ if (!(prefixes & PREFIX_ADDR)) ++ op1_names = (address_mode == mode_16bit ++ ? names16 : names); + else + { +- used_prefixes |= (prefixes & PREFIX_DATA); +- if (prefixes & PREFIX_DATA) +- suffix2 = 'd'; +- else +- { +- used_prefixes |= (prefixes & PREFIX_REPNZ); +- if (prefixes & PREFIX_REPNZ) +- suffix1 = 's', suffix2 = 'd'; +- } ++ /* Remove "addr16/addr32". */ ++ addr_prefix = NULL; ++ op1_names = (address_mode != mode_32bit ++ ? names32 : names16); ++ used_prefixes |= PREFIX_ADDR; + } +- sprintf (scratchbuf, "cmp%s%c%c", +- simd_cmp_op[cmp_type], suffix1, suffix2); +- used_prefixes |= (prefixes & PREFIX_REPZ); +- oappend (scratchbuf); ++ strcpy (op_out[0], op1_names[0]); ++ strcpy (op_out[1], names[1]); ++ strcpy (op_out[2], names[2]); ++ two_source_ops = 1; + } +- else ++ /* Skip mod/rm byte. */ ++ MODRM_CHECK; ++ codep++; ++} ++ ++static void ++BadOp (void) ++{ ++ /* Throw away prefixes and 1st. opcode byte. */ ++ codep = insn_codep + 1; ++ oappend ("(bad)"); ++} ++ ++static void ++REP_Fixup (int bytemode, int sizeflag) ++{ ++ /* The 0xf3 prefix should be displayed as "rep" for ins, outs, movs, ++ lods and stos. */ ++ if (prefixes & PREFIX_REPZ) ++ repz_prefix = "rep "; ++ ++ switch (bytemode) + { +- /* We have a bad extension byte. Clean up. */ +- op1out[0] = '\0'; +- op2out[0] = '\0'; +- BadOp (); ++ case al_reg: ++ case eAX_reg: ++ case indir_dx_reg: ++ OP_IMREG (bytemode, sizeflag); ++ break; ++ case eDI_reg: ++ OP_ESreg (bytemode, sizeflag); ++ break; ++ case eSI_reg: ++ OP_DSreg (bytemode, sizeflag); ++ break; ++ default: ++ abort (); ++ break; + } + } + + static void +-SIMD_Fixup (int extrachar, int sizeflag ATTRIBUTE_UNUSED) ++CMPXCHG8B_Fixup (int bytemode, int sizeflag) + { +- /* Change movlps/movhps to movhlps/movlhps for 2 register operand +- forms of these instructions. */ +- if (mod == 3) ++ USED_REX (REX_W); ++ if (rex & REX_W) + { +- char *p = obuf + strlen (obuf); +- *(p + 1) = '\0'; +- *p = *(p - 1); +- *(p - 1) = *(p - 2); +- *(p - 2) = *(p - 3); +- *(p - 3) = extrachar; ++ /* Change cmpxchg8b to cmpxchg16b. */ ++ char *p = obuf + strlen (obuf) - 2; ++ strcpy (p, "16b"); ++ bytemode = o_mode; + } ++ OP_M (bytemode, sizeflag); ++} ++ ++static void ++XMM_Fixup (int reg, int sizeflag ATTRIBUTE_UNUSED) ++{ ++ sprintf (scratchbuf, "%%xmm%d", reg); ++ oappend (scratchbuf + intel_syntax); + } + + static void +-PNI_Fixup (int extrachar ATTRIBUTE_UNUSED, int sizeflag ATTRIBUTE_UNUSED) ++CRC32_Fixup (int bytemode, int sizeflag) + { +- if (mod == 3 && reg == 1) ++ /* Add proper suffix to "crc32". */ ++ char *p = obuf + strlen (obuf); ++ ++ switch (bytemode) ++ { ++ case b_mode: ++ if (intel_syntax) ++ break; ++ ++ *p++ = 'b'; ++ break; ++ case v_mode: ++ if (intel_syntax) ++ break; ++ ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ *p++ = 'q'; ++ else if (sizeflag & DFLAG) ++ *p++ = 'l'; ++ else ++ *p++ = 'w'; ++ used_prefixes |= (prefixes & PREFIX_DATA); ++ break; ++ default: ++ oappend (INTERNAL_DISASSEMBLER_ERROR); ++ break; ++ } ++ *p = '\0'; ++ ++ if (modrm.mod == 3) + { +- char *p = obuf + strlen (obuf); ++ int add; ++ ++ /* Skip mod/rm byte. */ ++ MODRM_CHECK; ++ codep++; + +- /* Override "sidt". */ +- if (rm) ++ USED_REX (REX_B); ++ add = (rex & REX_B) ? 8 : 0; ++ if (bytemode == b_mode) + { +- /* mwait %eax,%ecx */ +- strcpy (p - 4, "mwait %eax,%ecx"); ++ USED_REX (0); ++ if (rex) ++ oappend (names8rex[modrm.rm + add]); ++ else ++ oappend (names8[modrm.rm + add]); + } + else + { +- /* monitor %eax,%ecx,%edx" */ +- strcpy (p - 4, "monitor %eax,%ecx,%edx"); ++ USED_REX (REX_W); ++ if (rex & REX_W) ++ oappend (names64[modrm.rm + add]); ++ else if ((prefixes & PREFIX_DATA)) ++ oappend (names16[modrm.rm + add]); ++ else ++ oappend (names32[modrm.rm + add]); + } ++ } ++ else ++ OP_E (bytemode, sizeflag); ++} + +- codep++; ++/* Print a DREX argument as either a register or memory operation. */ ++static void ++print_drex_arg (unsigned int reg, int bytemode, int sizeflag) ++{ ++ if (reg == DREX_REG_UNKNOWN) ++ BadOp (); ++ ++ else if (reg != DREX_REG_MEMORY) ++ { ++ sprintf (scratchbuf, "%%xmm%d", reg); ++ oappend (scratchbuf + intel_syntax); + } ++ + else +- OP_E (0, sizeflag); ++ OP_E_extended (bytemode, sizeflag, 1); + } + ++/* SSE5 instructions that have 4 arguments are encoded as: ++ 0f 24 . ++ ++ The byte has 1 bit (0x4) that is combined with 1 bit in ++ the DREX field (0x8) to determine how the arguments are laid out. ++ The destination register must be the same register as one of the ++ inputs, and it is encoded in the DREX byte. No REX prefix is used ++ for these instructions, since the DREX field contains the 3 extension ++ bits provided by the REX prefix. ++ ++ The bytemode argument adds 2 extra bits for passing extra information: ++ DREX_OC1 -- Set the OC1 bit to indicate dest == 1st arg ++ DREX_NO_OC0 -- OC0 in DREX is invalid ++ (but pretend it is set). */ ++ + static void +-BadOp (void) ++OP_DREX4 (int flag_bytemode, int sizeflag) + { +- /* Throw away prefixes and 1st. opcode byte. */ +- codep = insn_codep + 1; +- oappend ("(bad)"); ++ unsigned int drex_byte; ++ unsigned int regs[4]; ++ unsigned int modrm_regmem; ++ unsigned int modrm_reg; ++ unsigned int drex_reg; ++ int bytemode; ++ int rex_save = rex; ++ int rex_used_save = rex_used; ++ int has_sib = 0; ++ int oc1 = (flag_bytemode & DREX_OC1) ? 2 : 0; ++ int oc0; ++ int i; ++ ++ bytemode = flag_bytemode & ~ DREX_MASK; ++ ++ for (i = 0; i < 4; i++) ++ regs[i] = DREX_REG_UNKNOWN; ++ ++ /* Determine if we have a SIB byte in addition to MODRM before the ++ DREX byte. */ ++ if (((sizeflag & AFLAG) || address_mode == mode_64bit) ++ && (modrm.mod != 3) ++ && (modrm.rm == 4)) ++ has_sib = 1; ++ ++ /* Get the DREX byte. */ ++ FETCH_DATA (the_info, codep + 2 + has_sib); ++ drex_byte = codep[has_sib+1]; ++ drex_reg = DREX_XMM (drex_byte); ++ modrm_reg = modrm.reg + ((drex_byte & REX_R) ? 8 : 0); ++ ++ /* Is OC0 legal? If not, hardwire oc0 == 1. */ ++ if (flag_bytemode & DREX_NO_OC0) ++ { ++ oc0 = 1; ++ if (DREX_OC0 (drex_byte)) ++ BadOp (); ++ } ++ else ++ oc0 = DREX_OC0 (drex_byte); ++ ++ if (modrm.mod == 3) ++ { ++ /* regmem == register */ ++ modrm_regmem = modrm.rm + ((drex_byte & REX_B) ? 8 : 0); ++ rex = rex_used = 0; ++ /* skip modrm/drex since we don't call OP_E_extended */ ++ codep += 2; ++ } ++ else ++ { ++ /* regmem == memory, fill in appropriate REX bits */ ++ modrm_regmem = DREX_REG_MEMORY; ++ rex = drex_byte & (REX_B | REX_X | REX_R); ++ if (rex) ++ rex |= REX_OPCODE; ++ rex_used = rex; ++ } ++ ++ /* Based on the OC1/OC0 bits, lay out the arguments in the correct ++ order. */ ++ switch (oc0 + oc1) ++ { ++ default: ++ BadOp (); ++ return; ++ ++ case 0: ++ regs[0] = modrm_regmem; ++ regs[1] = modrm_reg; ++ regs[2] = drex_reg; ++ regs[3] = drex_reg; ++ break; ++ ++ case 1: ++ regs[0] = modrm_reg; ++ regs[1] = modrm_regmem; ++ regs[2] = drex_reg; ++ regs[3] = drex_reg; ++ break; ++ ++ case 2: ++ regs[0] = drex_reg; ++ regs[1] = modrm_regmem; ++ regs[2] = modrm_reg; ++ regs[3] = drex_reg; ++ break; ++ ++ case 3: ++ regs[0] = drex_reg; ++ regs[1] = modrm_reg; ++ regs[2] = modrm_regmem; ++ regs[3] = drex_reg; ++ break; ++ } ++ ++ /* Print out the arguments. */ ++ for (i = 0; i < 4; i++) ++ { ++ int j = (intel_syntax) ? 3 - i : i; ++ if (i > 0) ++ { ++ *obufp++ = ','; ++ *obufp = '\0'; ++ } ++ ++ print_drex_arg (regs[j], bytemode, sizeflag); ++ } ++ ++ rex = rex_save; ++ rex_used = rex_used_save; ++} ++ ++/* SSE5 instructions that have 3 arguments, and are encoded as: ++ 0f 24 (or) ++ 0f 25 ++ ++ The DREX field has 1 bit (0x8) to determine how the arguments are ++ laid out. The destination register is encoded in the DREX byte. ++ No REX prefix is used for these instructions, since the DREX field ++ contains the 3 extension bits provided by the REX prefix. */ ++ ++static void ++OP_DREX3 (int flag_bytemode, int sizeflag) ++{ ++ unsigned int drex_byte; ++ unsigned int regs[3]; ++ unsigned int modrm_regmem; ++ unsigned int modrm_reg; ++ unsigned int drex_reg; ++ int bytemode; ++ int rex_save = rex; ++ int rex_used_save = rex_used; ++ int has_sib = 0; ++ int oc0; ++ int i; ++ ++ bytemode = flag_bytemode & ~ DREX_MASK; ++ ++ for (i = 0; i < 3; i++) ++ regs[i] = DREX_REG_UNKNOWN; ++ ++ /* Determine if we have a SIB byte in addition to MODRM before the ++ DREX byte. */ ++ if (((sizeflag & AFLAG) || address_mode == mode_64bit) ++ && (modrm.mod != 3) ++ && (modrm.rm == 4)) ++ has_sib = 1; ++ ++ /* Get the DREX byte. */ ++ FETCH_DATA (the_info, codep + 2 + has_sib); ++ drex_byte = codep[has_sib+1]; ++ drex_reg = DREX_XMM (drex_byte); ++ modrm_reg = modrm.reg + ((drex_byte & REX_R) ? 8 : 0); ++ ++ /* Is OC0 legal? If not, hardwire oc0 == 0 */ ++ oc0 = DREX_OC0 (drex_byte); ++ if ((flag_bytemode & DREX_NO_OC0) && oc0) ++ BadOp (); ++ ++ if (modrm.mod == 3) ++ { ++ /* regmem == register */ ++ modrm_regmem = modrm.rm + ((drex_byte & REX_B) ? 8 : 0); ++ rex = rex_used = 0; ++ /* skip modrm/drex since we don't call OP_E_extended. */ ++ codep += 2; ++ } ++ else ++ { ++ /* regmem == memory, fill in appropriate REX bits. */ ++ modrm_regmem = DREX_REG_MEMORY; ++ rex = drex_byte & (REX_B | REX_X | REX_R); ++ if (rex) ++ rex |= REX_OPCODE; ++ rex_used = rex; ++ } ++ ++ /* Based on the OC1/OC0 bits, lay out the arguments in the correct ++ order. */ ++ switch (oc0) ++ { ++ default: ++ BadOp (); ++ return; ++ ++ case 0: ++ regs[0] = modrm_regmem; ++ regs[1] = modrm_reg; ++ regs[2] = drex_reg; ++ break; ++ ++ case 1: ++ regs[0] = modrm_reg; ++ regs[1] = modrm_regmem; ++ regs[2] = drex_reg; ++ break; ++ } ++ ++ /* Print out the arguments. */ ++ for (i = 0; i < 3; i++) ++ { ++ int j = (intel_syntax) ? 2 - i : i; ++ if (i > 0) ++ { ++ *obufp++ = ','; ++ *obufp = '\0'; ++ } ++ ++ print_drex_arg (regs[j], bytemode, sizeflag); ++ } ++ ++ rex = rex_save; ++ rex_used = rex_used_save; ++} ++ ++/* Emit a floating point comparison for comp instructions. */ ++ ++static void ++OP_DREX_FCMP (int bytemode ATTRIBUTE_UNUSED, ++ int sizeflag ATTRIBUTE_UNUSED) ++{ ++ unsigned char byte; ++ ++ static const char *const cmp_test[] = { ++ "eq", ++ "lt", ++ "le", ++ "unord", ++ "ne", ++ "nlt", ++ "nle", ++ "ord", ++ "ueq", ++ "ult", ++ "ule", ++ "false", ++ "une", ++ "unlt", ++ "unle", ++ "true" ++ }; ++ ++ FETCH_DATA (the_info, codep + 1); ++ byte = *codep & 0xff; ++ ++ if (byte >= ARRAY_SIZE (cmp_test) ++ || obuf[0] != 'c' ++ || obuf[1] != 'o' ++ || obuf[2] != 'm') ++ { ++ /* The instruction isn't one we know about, so just append the ++ extension byte as a numeric value. */ ++ OP_I (b_mode, 0); ++ } ++ ++ else ++ { ++ sprintf (scratchbuf, "com%s%s", cmp_test[byte], obuf+3); ++ strcpy (obuf, scratchbuf); ++ codep++; ++ } ++} ++ ++/* Emit an integer point comparison for pcom instructions, ++ rewriting the instruction to have the test inside of it. */ ++ ++static void ++OP_DREX_ICMP (int bytemode ATTRIBUTE_UNUSED, ++ int sizeflag ATTRIBUTE_UNUSED) ++{ ++ unsigned char byte; ++ ++ static const char *const cmp_test[] = { ++ "lt", ++ "le", ++ "gt", ++ "ge", ++ "eq", ++ "ne", ++ "false", ++ "true" ++ }; ++ ++ FETCH_DATA (the_info, codep + 1); ++ byte = *codep & 0xff; ++ ++ if (byte >= ARRAY_SIZE (cmp_test) ++ || obuf[0] != 'p' ++ || obuf[1] != 'c' ++ || obuf[2] != 'o' ++ || obuf[3] != 'm') ++ { ++ /* The instruction isn't one we know about, so just print the ++ comparison test byte as a numeric value. */ ++ OP_I (b_mode, 0); ++ } ++ ++ else ++ { ++ sprintf (scratchbuf, "pcom%s%s", cmp_test[byte], obuf+4); ++ strcpy (obuf, scratchbuf); ++ codep++; ++ } + } +--- gdb-6.1/include/opcode/i386.h.orig ++++ gdb-6.1/include/opcode/i386.h +@@ -1,23 +1,23 @@ +-/* opcode/i386.h -- Intel 80386 opcode table ++/* opcode/i386.h -- Intel 80386 opcode macros + Copyright 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +- 2000, 2001 ++ 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 + Free Software Foundation, Inc. + +-This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger. ++ This file is part of GAS, the GNU Assembler, and GDB, the GNU Debugger. + +-This program is free software; you can redistribute it and/or modify +-it under the terms of the GNU General Public License as published by +-the Free Software Foundation; either version 2 of the License, or +-(at your option) any later version. +- +-This program is distributed in the hope that it will be useful, +-but WITHOUT ANY WARRANTY; without even the implied warranty of +-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-GNU General Public License for more details. +- +-You should have received a copy of the GNU General Public License +-along with this program; if not, write to the Free Software +-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 2 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ + + /* The SystemV/386 SVR3.2 assembler, and probably all AT&T derived + ix86 Unix assemblers, generate floating point instructions with +@@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suit + + This happens with all the non-commutative arithmetic floating point + operations with two register operands, where the source register is +- %st, and destination register is %st(i). See FloatDR below. ++ %st, and destination register is %st(i). + + The affected opcode map is dceX, dcfX, deeX, defX. */ + +@@ -48,1542 +48,68 @@ Foundation, Inc., 59 Temple Place - Suit + #define OLDGCC_COMPAT SYSV386_COMPAT + #endif + +-static const template i386_optab[] = { +- +-#define X None +-#define NoSuf (No_bSuf|No_wSuf|No_lSuf|No_sSuf|No_xSuf|No_qSuf) +-#define b_Suf (No_wSuf|No_lSuf|No_sSuf|No_xSuf|No_qSuf) +-#define w_Suf (No_bSuf|No_lSuf|No_sSuf|No_xSuf|No_qSuf) +-#define l_Suf (No_bSuf|No_wSuf|No_sSuf|No_xSuf|No_qSuf) +-#define q_Suf (No_bSuf|No_wSuf|No_sSuf|No_lSuf|No_xSuf) +-#define x_Suf (No_bSuf|No_wSuf|No_sSuf|No_lSuf|No_qSuf) +-#define bw_Suf (No_lSuf|No_sSuf|No_xSuf|No_qSuf) +-#define bl_Suf (No_wSuf|No_sSuf|No_xSuf|No_qSuf) +-#define wl_Suf (No_bSuf|No_sSuf|No_xSuf|No_qSuf) +-#define wlq_Suf (No_bSuf|No_sSuf|No_xSuf) +-#define lq_Suf (No_bSuf|No_wSuf|No_sSuf|No_xSuf) +-#define wq_Suf (No_bSuf|No_lSuf|No_sSuf|No_xSuf) +-#define sl_Suf (No_bSuf|No_wSuf|No_xSuf|No_qSuf) +-#define sldx_Suf (No_bSuf|No_wSuf|No_qSuf) +-#define bwl_Suf (No_sSuf|No_xSuf|No_qSuf) +-#define bwlq_Suf (No_sSuf|No_xSuf) +-#define FP (NoSuf|IgnoreSize) +-#define l_FP (l_Suf|IgnoreSize) +-#define x_FP (x_Suf|IgnoreSize) +-#define sl_FP (sl_Suf|IgnoreSize) +-#if SYSV386_COMPAT +-/* Someone forgot that the FloatR bit reverses the operation when not +- equal to the FloatD bit. ie. Changing only FloatD results in the +- destination being swapped *and* the direction being reversed. */ +-#define FloatDR FloatD +-#else +-#define FloatDR (FloatD|FloatR) +-#endif +- +-/* Move instructions. */ + #define MOV_AX_DISP32 0xa0 +-/* In the 64bit mode the short form mov immediate is redefined to have +- 64bit displacement value. */ +-{ "mov", 2, 0xa0, X, CpuNo64,bwlq_Suf|D|W, { Disp16|Disp32, Acc, 0 } }, +-{ "mov", 2, 0x88, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-/* In the 64bit mode the short form mov immediate is redefined to have +- 64bit displacement value. */ +-{ "mov", 2, 0xb0, X, 0, bwl_Suf|W|ShortForm, { EncImm, Reg8|Reg16|Reg32, 0 } }, +-{ "mov", 2, 0xc6, 0, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0 } }, +-{ "mov", 2, 0xb0, X, Cpu64, q_Suf|W|ShortForm, { Imm64, Reg64, 0 } }, +-/* The segment register moves accept WordReg so that a segment register +- can be copied to a 32 bit register, and vice versa, without using a +- size prefix. When moving to a 32 bit register, the upper 16 bits +- are set to an implementation defined value (on the Pentium Pro, +- the implementation defined value is zero). */ +-{ "mov", 2, 0x8c, X, 0, wl_Suf|Modrm, { SReg2, WordReg|WordMem, 0 } }, +-{ "mov", 2, 0x8c, X, Cpu386, wl_Suf|Modrm, { SReg3, WordReg|WordMem, 0 } }, +-{ "mov", 2, 0x8e, X, 0, wl_Suf|Modrm|IgnoreSize, { WordReg|WordMem, SReg2, 0 } }, +-{ "mov", 2, 0x8e, X, Cpu386, wl_Suf|Modrm|IgnoreSize, { WordReg|WordMem, SReg3, 0 } }, +-/* Move to/from control debug registers. In the 16 or 32bit modes they are 32bit. In the 64bit +- mode they are 64bit.*/ +-{ "mov", 2, 0x0f20, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{ Control, Reg32|InvMem, 0} }, +-{ "mov", 2, 0x0f20, X, Cpu64, q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Control, Reg64|InvMem, 0} }, +-{ "mov", 2, 0x0f21, X, Cpu386|CpuNo64, l_Suf|D|Modrm|IgnoreSize,{ Debug, Reg32|InvMem, 0} }, +-{ "mov", 2, 0x0f21, X, Cpu64, q_Suf|D|Modrm|IgnoreSize|NoRex64,{ Debug, Reg64|InvMem, 0} }, +-{ "mov", 2, 0x0f24, X, Cpu386, l_Suf|D|Modrm|IgnoreSize, { Test, Reg32|InvMem, 0} }, +-{ "movabs",2, 0xa0, X, Cpu64, bwlq_Suf|D|W, { Disp64, Acc, 0 } }, +-{ "movabs",2, 0xb0, X, Cpu64, q_Suf|W|ShortForm, { Imm64, Reg64, 0 } }, +- +-/* Move with sign extend. */ +-/* "movsbl" & "movsbw" must not be unified into "movsb" to avoid +- conflict with the "movs" string move instruction. */ +-{"movsbl", 2, 0x0fbe, X, Cpu386, NoSuf|Modrm, { Reg8|ByteMem, Reg32, 0} }, +-{"movsbw", 2, 0x0fbe, X, Cpu386, NoSuf|Modrm, { Reg8|ByteMem, Reg16, 0} }, +-{"movswl", 2, 0x0fbf, X, Cpu386, NoSuf|Modrm, { Reg16|ShortMem,Reg32, 0} }, +-{"movsbq", 2, 0x0fbe, X, Cpu64, NoSuf|Modrm|Rex64, { Reg8|ByteMem, Reg64, 0} }, +-{"movswq", 2, 0x0fbf, X, Cpu64, NoSuf|Modrm|Rex64, { Reg16|ShortMem,Reg64, 0} }, +-{"movslq", 2, 0x63, X, Cpu64, NoSuf|Modrm|Rex64, { Reg32|WordMem, Reg64, 0} }, +-/* Intel Syntax next 5 insns */ +-{"movsx", 2, 0x0fbe, X, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, WordReg, 0} }, +-{"movsx", 2, 0x0fbf, X, Cpu386, w_Suf|Modrm, { Reg16|ShortMem, Reg32, 0} }, +-{"movsx", 2, 0x0fbe, X, Cpu64, b_Suf|Modrm|Rex64, { Reg8|ByteMem, Reg64, 0} }, +-{"movsx", 2, 0x0fbf, X, Cpu64, w_Suf|Modrm|Rex64, { Reg16|ShortMem, Reg64, 0} }, +-{"movsx", 2, 0x63, X, Cpu64, l_Suf|Modrm|Rex64, { Reg32|WordMem, Reg64, 0} }, +- +-/* Move with zero extend. */ +-{"movzb", 2, 0x0fb6, X, Cpu386, wl_Suf|Modrm, { Reg8|ByteMem, WordReg, 0} }, +-{"movzwl", 2, 0x0fb7, X, Cpu386, NoSuf|Modrm, { Reg16|ShortMem, Reg32, 0} }, +-/* These instructions are not particulary usefull, since the zero extend +- 32->64 is implicit, but we can encode them. */ +-{"movzbq", 2, 0x0fb6, X, Cpu64, NoSuf|Modrm|Rex64, { Reg8|ByteMem, Reg64, 0} }, +-{"movzwq", 2, 0x0fb7, X, Cpu64, NoSuf|Modrm|Rex64, { Reg16|ShortMem, Reg64, 0} }, +-/* Intel Syntax next 4 insns */ +-{"movzx", 2, 0x0fb6, X, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, WordReg, 0} }, +-{"movzx", 2, 0x0fb7, X, Cpu386, w_Suf|Modrm, { Reg16|ShortMem, Reg32, 0} }, +-/* These instructions are not particulary usefull, since the zero extend +- 32->64 is implicit, but we can encode them. */ +-{"movzx", 2, 0x0fb6, X, Cpu386, b_Suf|Modrm|Rex64, { Reg8|ByteMem, Reg64, 0} }, +-{"movzx", 2, 0x0fb7, X, Cpu386, w_Suf|Modrm|Rex64, { Reg16|ShortMem, Reg64, 0} }, +- +-/* Push instructions. */ +-{"push", 1, 0x50, X, CpuNo64, wl_Suf|ShortForm|DefaultSize, { WordReg, 0, 0 } }, +-{"push", 1, 0xff, 6, CpuNo64, wl_Suf|Modrm|DefaultSize, { WordReg|WordMem, 0, 0 } }, +-{"push", 1, 0x6a, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { Imm8S, 0, 0} }, +-{"push", 1, 0x68, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { Imm16|Imm32, 0, 0} }, +-{"push", 1, 0x06, X, 0|CpuNo64, wl_Suf|Seg2ShortForm|DefaultSize, { SReg2, 0, 0 } }, +-{"push", 1, 0x0fa0, X, Cpu386|CpuNo64, wl_Suf|Seg3ShortForm|DefaultSize, { SReg3, 0, 0 } }, +-/* In 64bit mode, the operand size is implicitly 64bit. */ +-{"push", 1, 0x50, X, Cpu64, wq_Suf|ShortForm|DefaultSize|NoRex64, { WordReg, 0, 0 } }, +-{"push", 1, 0xff, 6, Cpu64, wq_Suf|Modrm|DefaultSize|NoRex64, { WordReg|WordMem, 0, 0 } }, +-{"push", 1, 0x6a, X, Cpu186|Cpu64, wq_Suf|DefaultSize|NoRex64, { Imm8S, 0, 0} }, +-{"push", 1, 0x68, X, Cpu186|Cpu64, wq_Suf|DefaultSize|NoRex64, { Imm32S|Imm16, 0, 0} }, +-{"push", 1, 0x06, X, Cpu64, wq_Suf|Seg2ShortForm|DefaultSize|NoRex64, { SReg2, 0, 0 } }, +-{"push", 1, 0x0fa0, X, Cpu386|Cpu64, wq_Suf|Seg3ShortForm|DefaultSize|NoRex64, { SReg3, 0, 0 } }, +- +-{"pusha", 0, 0x60, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { 0, 0, 0 } }, +- +-/* Pop instructions. */ +-{"pop", 1, 0x58, X, CpuNo64, wl_Suf|ShortForm|DefaultSize, { WordReg, 0, 0 } }, +-{"pop", 1, 0x8f, 0, CpuNo64, wl_Suf|Modrm|DefaultSize, { WordReg|WordMem, 0, 0 } }, + #define POP_SEG_SHORT 0x07 +-{"pop", 1, 0x07, X, CpuNo64, wl_Suf|Seg2ShortForm|DefaultSize, { SReg2, 0, 0 } }, +-{"pop", 1, 0x0fa1, X, Cpu386|CpuNo64, wl_Suf|Seg3ShortForm|DefaultSize, { SReg3, 0, 0 } }, +-/* In 64bit mode, the operand size is implicitly 64bit. */ +-{"pop", 1, 0x58, X, Cpu64, wq_Suf|ShortForm|DefaultSize|NoRex64, { WordReg, 0, 0 } }, +-{"pop", 1, 0x8f, 0, Cpu64, wq_Suf|Modrm|DefaultSize|NoRex64, { WordReg|WordMem, 0, 0 } }, +-{"pop", 1, 0x07, X, Cpu64, wq_Suf|Seg2ShortForm|DefaultSize|NoRex64, { SReg2, 0, 0 } }, +-{"pop", 1, 0x0fa1, X, Cpu64, wq_Suf|Seg3ShortForm|DefaultSize|NoRex64, { SReg3, 0, 0 } }, +- +-{"popa", 0, 0x61, X, Cpu186|CpuNo64, wl_Suf|DefaultSize, { 0, 0, 0 } }, +- +-/* Exchange instructions. +- xchg commutes: we allow both operand orders. +- +- In the 64bit code, xchg eax, eax is reused for new nop instruction. +- */ +-{"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { WordReg, Acc, 0 } }, +-{"xchg", 2, 0x90, X, 0, wlq_Suf|ShortForm, { Acc, WordReg, 0 } }, +-{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } }, +-{"xchg", 2, 0x86, X, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, Reg, 0 } }, +- +-/* In/out from ports. */ +-{"in", 2, 0xe4, X, 0, bwl_Suf|W, { Imm8, Acc, 0 } }, +-{"in", 2, 0xec, X, 0, bwl_Suf|W, { InOutPortReg, Acc, 0 } }, +-{"in", 1, 0xe4, X, 0, bwl_Suf|W, { Imm8, 0, 0 } }, +-{"in", 1, 0xec, X, 0, bwl_Suf|W, { InOutPortReg, 0, 0 } }, +-{"out", 2, 0xe6, X, 0, bwl_Suf|W, { Acc, Imm8, 0 } }, +-{"out", 2, 0xee, X, 0, bwl_Suf|W, { Acc, InOutPortReg, 0 } }, +-{"out", 1, 0xe6, X, 0, bwl_Suf|W, { Imm8, 0, 0 } }, +-{"out", 1, 0xee, X, 0, bwl_Suf|W, { InOutPortReg, 0, 0 } }, +- +-/* Load effective address. */ +-{"lea", 2, 0x8d, X, 0, wlq_Suf|Modrm, { WordMem, WordReg, 0 } }, +- +-/* Load segment registers from memory. */ +-{"lds", 2, 0xc5, X, CpuNo64, wlq_Suf|Modrm, { WordMem, WordReg, 0} }, +-{"les", 2, 0xc4, X, CpuNo64, wlq_Suf|Modrm, { WordMem, WordReg, 0} }, +-{"lfs", 2, 0x0fb4, X, Cpu386, wlq_Suf|Modrm, { WordMem, WordReg, 0} }, +-{"lgs", 2, 0x0fb5, X, Cpu386, wlq_Suf|Modrm, { WordMem, WordReg, 0} }, +-{"lss", 2, 0x0fb2, X, Cpu386, wlq_Suf|Modrm, { WordMem, WordReg, 0} }, +- +-/* Flags register instructions. */ +-{"clc", 0, 0xf8, X, 0, NoSuf, { 0, 0, 0} }, +-{"cld", 0, 0xfc, X, 0, NoSuf, { 0, 0, 0} }, +-{"cli", 0, 0xfa, X, 0, NoSuf, { 0, 0, 0} }, +-{"clts", 0, 0x0f06, X, Cpu286, NoSuf, { 0, 0, 0} }, +-{"cmc", 0, 0xf5, X, 0, NoSuf, { 0, 0, 0} }, +-{"lahf", 0, 0x9f, X, CpuNo64,NoSuf, { 0, 0, 0} }, +-{"sahf", 0, 0x9e, X, CpuNo64,NoSuf, { 0, 0, 0} }, +-{"pushf", 0, 0x9c, X, CpuNo64,wlq_Suf|DefaultSize, { 0, 0, 0} }, +-{"pushf", 0, 0x9c, X, Cpu64, wq_Suf|DefaultSize|NoRex64,{ 0, 0, 0} }, +-{"popf", 0, 0x9d, X, CpuNo64,wlq_Suf|DefaultSize, { 0, 0, 0} }, +-{"popf", 0, 0x9d, X, Cpu64, wq_Suf|DefaultSize|NoRex64,{ 0, 0, 0} }, +-{"stc", 0, 0xf9, X, 0, NoSuf, { 0, 0, 0} }, +-{"std", 0, 0xfd, X, 0, NoSuf, { 0, 0, 0} }, +-{"sti", 0, 0xfb, X, 0, NoSuf, { 0, 0, 0} }, +- +-/* Arithmetic. */ +-{"add", 2, 0x00, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"add", 2, 0x83, 0, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"add", 2, 0x04, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"add", 2, 0x80, 0, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"inc", 1, 0x40, X, CpuNo64,wl_Suf|ShortForm, { WordReg, 0, 0} }, +-{"inc", 1, 0xfe, 0, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"sub", 2, 0x28, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"sub", 2, 0x83, 5, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"sub", 2, 0x2c, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"sub", 2, 0x80, 5, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"dec", 1, 0x48, X, CpuNo64, wl_Suf|ShortForm, { WordReg, 0, 0} }, +-{"dec", 1, 0xfe, 1, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"sbb", 2, 0x18, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"sbb", 2, 0x83, 3, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"sbb", 2, 0x1c, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"sbb", 2, 0x80, 3, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"cmp", 2, 0x38, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"cmp", 2, 0x83, 7, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"cmp", 2, 0x3c, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"cmp", 2, 0x80, 7, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"test", 2, 0x84, X, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, Reg, 0} }, +-{"test", 2, 0x84, X, 0, bwlq_Suf|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"test", 2, 0xa8, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"test", 2, 0xf6, 0, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"and", 2, 0x20, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"and", 2, 0x83, 4, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"and", 2, 0x24, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"and", 2, 0x80, 4, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"or", 2, 0x08, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"or", 2, 0x83, 1, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"or", 2, 0x0c, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"or", 2, 0x80, 1, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"xor", 2, 0x30, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"xor", 2, 0x83, 6, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"xor", 2, 0x34, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"xor", 2, 0x80, 6, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-/* clr with 1 operand is really xor with 2 operands. */ +-{"clr", 1, 0x30, X, 0, bwlq_Suf|W|Modrm|regKludge, { Reg, 0, 0 } }, +- +-{"adc", 2, 0x10, X, 0, bwlq_Suf|D|W|Modrm, { Reg, Reg|AnyMem, 0} }, +-{"adc", 2, 0x83, 2, 0, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, 0} }, +-{"adc", 2, 0x14, X, 0, bwlq_Suf|W, { EncImm, Acc, 0} }, +-{"adc", 2, 0x80, 2, 0, bwlq_Suf|W|Modrm, { EncImm, Reg|AnyMem, 0} }, +- +-{"neg", 1, 0xf6, 3, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +-{"not", 1, 0xf6, 2, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"aaa", 0, 0x37, X, 0, NoSuf, { 0, 0, 0} }, +-{"aas", 0, 0x3f, X, 0, NoSuf, { 0, 0, 0} }, +-{"daa", 0, 0x27, X, 0, NoSuf, { 0, 0, 0} }, +-{"das", 0, 0x2f, X, 0, NoSuf, { 0, 0, 0} }, +-{"aad", 0, 0xd50a, X, 0, NoSuf, { 0, 0, 0} }, +-{"aad", 1, 0xd5, X, 0, NoSuf, { Imm8S, 0, 0} }, +-{"aam", 0, 0xd40a, X, 0, NoSuf, { 0, 0, 0} }, +-{"aam", 1, 0xd4, X, 0, NoSuf, { Imm8S, 0, 0} }, +- +-/* Conversion insns. */ +-/* Intel naming */ +-{"cbw", 0, 0x98, X, 0, NoSuf|Size16, { 0, 0, 0} }, +-{"cdqe", 0, 0x98, X, Cpu64, NoSuf|Size64, { 0, 0, 0} }, +-{"cwde", 0, 0x98, X, 0, NoSuf|Size32, { 0, 0, 0} }, +-{"cwd", 0, 0x99, X, 0, NoSuf|Size16, { 0, 0, 0} }, +-{"cdq", 0, 0x99, X, 0, NoSuf|Size32, { 0, 0, 0} }, +-{"cqo", 0, 0x99, X, Cpu64, NoSuf|Size64, { 0, 0, 0} }, +-/* AT&T naming */ +-{"cbtw", 0, 0x98, X, 0, NoSuf|Size16, { 0, 0, 0} }, +-{"cltq", 0, 0x98, X, Cpu64, NoSuf|Size64, { 0, 0, 0} }, +-{"cwtl", 0, 0x98, X, 0, NoSuf|Size32, { 0, 0, 0} }, +-{"cwtd", 0, 0x99, X, 0, NoSuf|Size16, { 0, 0, 0} }, +-{"cltd", 0, 0x99, X, 0, NoSuf|Size32, { 0, 0, 0} }, +-{"cqto", 0, 0x99, X, Cpu64, NoSuf|Size64, { 0, 0, 0} }, +- +-/* Warning! the mul/imul (opcode 0xf6) must only have 1 operand! They are +- expanding 64-bit multiplies, and *cannot* be selected to accomplish +- 'imul %ebx, %eax' (opcode 0x0faf must be used in this case) +- These multiplies can only be selected with single operand forms. */ +-{"mul", 1, 0xf6, 4, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +-{"imul", 1, 0xf6, 5, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +-{"imul", 2, 0x0faf, X, Cpu386, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"imul", 3, 0x6b, X, Cpu186, wlq_Suf|Modrm, { Imm8S, WordReg|WordMem, WordReg} }, +-{"imul", 3, 0x69, X, Cpu186, wlq_Suf|Modrm, { Imm16|Imm32S|Imm32, WordReg|WordMem, WordReg} }, +-/* imul with 2 operands mimics imul with 3 by putting the register in +- both i.rm.reg & i.rm.regmem fields. regKludge enables this +- transformation. */ +-{"imul", 2, 0x6b, X, Cpu186, wlq_Suf|Modrm|regKludge,{ Imm8S, WordReg, 0} }, +-{"imul", 2, 0x69, X, Cpu186, wlq_Suf|Modrm|regKludge,{ Imm16|Imm32S|Imm32, WordReg, 0} }, +- +-{"div", 1, 0xf6, 6, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +-{"div", 2, 0xf6, 6, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, Acc, 0} }, +-{"idiv", 1, 0xf6, 7, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +-{"idiv", 2, 0xf6, 7, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, Acc, 0} }, +- +-{"rol", 2, 0xd0, 0, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"rol", 2, 0xc0, 0, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"rol", 2, 0xd2, 0, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"rol", 1, 0xd0, 0, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"ror", 2, 0xd0, 1, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"ror", 2, 0xc0, 1, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"ror", 2, 0xd2, 1, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"ror", 1, 0xd0, 1, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"rcl", 2, 0xd0, 2, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"rcl", 2, 0xc0, 2, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"rcl", 2, 0xd2, 2, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"rcl", 1, 0xd0, 2, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"rcr", 2, 0xd0, 3, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"rcr", 2, 0xc0, 3, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"rcr", 2, 0xd2, 3, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"rcr", 1, 0xd0, 3, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"sal", 2, 0xd0, 4, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"sal", 2, 0xc0, 4, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"sal", 2, 0xd2, 4, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"sal", 1, 0xd0, 4, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"shl", 2, 0xd0, 4, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"shl", 2, 0xc0, 4, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"shl", 2, 0xd2, 4, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"shl", 1, 0xd0, 4, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"shr", 2, 0xd0, 5, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"shr", 2, 0xc0, 5, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"shr", 2, 0xd2, 5, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"shr", 1, 0xd0, 5, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"sar", 2, 0xd0, 7, 0, bwlq_Suf|W|Modrm, { Imm1, Reg|AnyMem, 0} }, +-{"sar", 2, 0xc0, 7, Cpu186, bwlq_Suf|W|Modrm, { Imm8, Reg|AnyMem, 0} }, +-{"sar", 2, 0xd2, 7, 0, bwlq_Suf|W|Modrm, { ShiftCount, Reg|AnyMem, 0} }, +-{"sar", 1, 0xd0, 7, 0, bwlq_Suf|W|Modrm, { Reg|AnyMem, 0, 0} }, +- +-{"shld", 3, 0x0fa4, X, Cpu386, wlq_Suf|Modrm, { Imm8, WordReg, WordReg|WordMem} }, +-{"shld", 3, 0x0fa5, X, Cpu386, wlq_Suf|Modrm, { ShiftCount, WordReg, WordReg|WordMem} }, +-{"shld", 2, 0x0fa5, X, Cpu386, wlq_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, +- +-{"shrd", 3, 0x0fac, X, Cpu386, wlq_Suf|Modrm, { Imm8, WordReg, WordReg|WordMem} }, +-{"shrd", 3, 0x0fad, X, Cpu386, wlq_Suf|Modrm, { ShiftCount, WordReg, WordReg|WordMem} }, +-{"shrd", 2, 0x0fad, X, Cpu386, wlq_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, +- +-/* Control transfer instructions. */ +-{"call", 1, 0xe8, X, 0, wlq_Suf|JumpDword|DefaultSize, { Disp16|Disp32, 0, 0} }, +-{"call", 1, 0xff, 2, CpuNo64, wl_Suf|Modrm|DefaultSize, { WordReg|WordMem|JumpAbsolute, 0, 0} }, +-{"call", 1, 0xff, 2, Cpu64, wq_Suf|Modrm|DefaultSize|NoRex64,{ WordReg|WordMem|JumpAbsolute, 0, 0} }, +-/* Intel Syntax */ +-{"call", 2, 0x9a, X, CpuNo64,wlq_Suf|JumpInterSegment|DefaultSize, { Imm16, Imm16|Imm32, 0} }, +-/* Intel Syntax */ +-{"call", 1, 0xff, 3, 0, x_Suf|Modrm|DefaultSize, { WordMem, 0, 0} }, +-{"lcall", 2, 0x9a, X, CpuNo64, wl_Suf|JumpInterSegment|DefaultSize, { Imm16, Imm16|Imm32, 0} }, +-{"lcall", 1, 0xff, 3, CpuNo64, wl_Suf|Modrm|DefaultSize, { WordMem|JumpAbsolute, 0, 0} }, +-{"lcall", 1, 0xff, 3, Cpu64, q_Suf|Modrm|DefaultSize|NoRex64,{ WordMem|JumpAbsolute, 0, 0} }, +- + #define JUMP_PC_RELATIVE 0xeb +-{"jmp", 1, 0xeb, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jmp", 1, 0xff, 4, CpuNo64, wl_Suf|Modrm, { WordReg|WordMem|JumpAbsolute, 0, 0} }, +-{"jmp", 1, 0xff, 4, Cpu64, wq_Suf|Modrm|NoRex64, { WordReg|WordMem|JumpAbsolute, 0, 0} }, +-/* Intel Syntax */ +-{"jmp", 2, 0xea, X, CpuNo64,wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} }, +-/* Intel Syntax */ +-{"jmp", 1, 0xff, 5, 0, x_Suf|Modrm, { WordMem, 0, 0} }, +-{"ljmp", 2, 0xea, X, CpuNo64, wl_Suf|JumpInterSegment, { Imm16, Imm16|Imm32, 0} }, +-{"ljmp", 1, 0xff, 5, CpuNo64, wl_Suf|Modrm, { WordMem|JumpAbsolute, 0, 0} }, +-{"ljmp", 1, 0xff, 5, Cpu64, q_Suf|Modrm|NoRex64, { WordMem|JumpAbsolute, 0, 0} }, +- +-{"ret", 0, 0xc3, X, CpuNo64,wlq_Suf|DefaultSize, { 0, 0, 0} }, +-{"ret", 1, 0xc2, X, CpuNo64,wlq_Suf|DefaultSize, { Imm16, 0, 0} }, +-{"ret", 0, 0xc3, X, Cpu64, q_Suf|DefaultSize|NoRex64,{ 0, 0, 0} }, +-{"ret", 1, 0xc2, X, Cpu64, q_Suf|DefaultSize|NoRex64,{ Imm16, 0, 0} }, +-{"lret", 0, 0xcb, X, 0, wlq_Suf|DefaultSize, { 0, 0, 0} }, +-{"lret", 1, 0xca, X, 0, wlq_Suf|DefaultSize, { Imm16, 0, 0} }, +-{"enter", 2, 0xc8, X, Cpu186, wlq_Suf|DefaultSize, { Imm16, Imm8, 0} }, +-{"leave", 0, 0xc9, X, Cpu186, wlq_Suf|DefaultSize, { 0, 0, 0} }, +- +-/* Conditional jumps. */ +-{"jo", 1, 0x70, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jno", 1, 0x71, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jb", 1, 0x72, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jc", 1, 0x72, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnae", 1, 0x72, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnb", 1, 0x73, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnc", 1, 0x73, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jae", 1, 0x73, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"je", 1, 0x74, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jz", 1, 0x74, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jne", 1, 0x75, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnz", 1, 0x75, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jbe", 1, 0x76, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jna", 1, 0x76, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnbe", 1, 0x77, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"ja", 1, 0x77, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"js", 1, 0x78, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jns", 1, 0x79, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jp", 1, 0x7a, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jpe", 1, 0x7a, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnp", 1, 0x7b, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jpo", 1, 0x7b, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jl", 1, 0x7c, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnge", 1, 0x7c, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnl", 1, 0x7d, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jge", 1, 0x7d, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jle", 1, 0x7e, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jng", 1, 0x7e, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jnle", 1, 0x7f, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +-{"jg", 1, 0x7f, X, 0, NoSuf|Jump, { Disp, 0, 0} }, +- +-/* jcxz vs. jecxz is chosen on the basis of the address size prefix. */ +-{"jcxz", 1, 0xe3, X, CpuNo64,NoSuf|JumpByte|Size16, { Disp, 0, 0} }, +-{"jecxz", 1, 0xe3, X, CpuNo64,NoSuf|JumpByte|Size32, { Disp, 0, 0} }, +-{"jecxz", 1, 0x67e3, X, Cpu64,NoSuf|JumpByte|Size32, { Disp, 0, 0} }, +-{"jrcxz", 1, 0xe3, X, Cpu64, NoSuf|JumpByte|Size64|NoRex64, { Disp, 0, 0} }, +- +-/* The loop instructions also use the address size prefix to select +- %cx rather than %ecx for the loop count, so the `w' form of these +- instructions emit an address size prefix rather than a data size +- prefix. */ +-{"loop", 1, 0xe2, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} }, +-{"loop", 1, 0xe2, X, Cpu64, lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} }, +-{"loopz", 1, 0xe1, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} }, +-{"loopz", 1, 0xe1, X, Cpu64, lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} }, +-{"loope", 1, 0xe1, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} }, +-{"loope", 1, 0xe1, X, Cpu64, lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} }, +-{"loopnz", 1, 0xe0, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} }, +-{"loopnz", 1, 0xe0, X, Cpu64, lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} }, +-{"loopne", 1, 0xe0, X, CpuNo64,wl_Suf|JumpByte,{ Disp, 0, 0} }, +-{"loopne", 1, 0xe0, X, Cpu64, lq_Suf|JumpByte|NoRex64,{ Disp, 0, 0} }, +- +-/* Set byte on flag instructions. */ +-{"seto", 1, 0x0f90, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setno", 1, 0x0f91, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setb", 1, 0x0f92, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setc", 1, 0x0f92, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnae", 1, 0x0f92, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnb", 1, 0x0f93, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnc", 1, 0x0f93, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setae", 1, 0x0f93, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"sete", 1, 0x0f94, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setz", 1, 0x0f94, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setne", 1, 0x0f95, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnz", 1, 0x0f95, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setbe", 1, 0x0f96, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setna", 1, 0x0f96, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnbe", 1, 0x0f97, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"seta", 1, 0x0f97, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"sets", 1, 0x0f98, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setns", 1, 0x0f99, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setp", 1, 0x0f9a, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setpe", 1, 0x0f9a, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnp", 1, 0x0f9b, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setpo", 1, 0x0f9b, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setl", 1, 0x0f9c, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnge", 1, 0x0f9c, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnl", 1, 0x0f9d, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setge", 1, 0x0f9d, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setle", 1, 0x0f9e, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setng", 1, 0x0f9e, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setnle", 1, 0x0f9f, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +-{"setg", 1, 0x0f9f, 0, Cpu386, b_Suf|Modrm, { Reg8|ByteMem, 0, 0} }, +- +-/* String manipulation. */ +-{"cmps", 0, 0xa6, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"cmps", 2, 0xa6, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, AnyMem, 0} }, +-{"scmp", 0, 0xa6, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"scmp", 2, 0xa6, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, AnyMem, 0} }, +-{"ins", 0, 0x6c, X, Cpu186, bwl_Suf|W|IsString, { 0, 0, 0} }, +-{"ins", 2, 0x6c, X, Cpu186, bwl_Suf|W|IsString, { InOutPortReg, AnyMem|EsSeg, 0} }, +-{"outs", 0, 0x6e, X, Cpu186, bwl_Suf|W|IsString, { 0, 0, 0} }, +-{"outs", 2, 0x6e, X, Cpu186, bwl_Suf|W|IsString, { AnyMem, InOutPortReg, 0} }, +-{"lods", 0, 0xac, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"lods", 1, 0xac, X, 0, bwlq_Suf|W|IsString, { AnyMem, 0, 0} }, +-{"lods", 2, 0xac, X, 0, bwlq_Suf|W|IsString, { AnyMem, Acc, 0} }, +-{"slod", 0, 0xac, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"slod", 1, 0xac, X, 0, bwlq_Suf|W|IsString, { AnyMem, 0, 0} }, +-{"slod", 2, 0xac, X, 0, bwlq_Suf|W|IsString, { AnyMem, Acc, 0} }, +-{"movs", 0, 0xa4, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"movs", 2, 0xa4, X, 0, bwlq_Suf|W|IsString, { AnyMem, AnyMem|EsSeg, 0} }, +-{"smov", 0, 0xa4, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"smov", 2, 0xa4, X, 0, bwlq_Suf|W|IsString, { AnyMem, AnyMem|EsSeg, 0} }, +-{"scas", 0, 0xae, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"scas", 1, 0xae, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} }, +-{"scas", 2, 0xae, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, Acc, 0} }, +-{"ssca", 0, 0xae, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"ssca", 1, 0xae, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} }, +-{"ssca", 2, 0xae, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, Acc, 0} }, +-{"stos", 0, 0xaa, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"stos", 1, 0xaa, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} }, +-{"stos", 2, 0xaa, X, 0, bwlq_Suf|W|IsString, { Acc, AnyMem|EsSeg, 0} }, +-{"ssto", 0, 0xaa, X, 0, bwlq_Suf|W|IsString, { 0, 0, 0} }, +-{"ssto", 1, 0xaa, X, 0, bwlq_Suf|W|IsString, { AnyMem|EsSeg, 0, 0} }, +-{"ssto", 2, 0xaa, X, 0, bwlq_Suf|W|IsString, { Acc, AnyMem|EsSeg, 0} }, +-{"xlat", 0, 0xd7, X, 0, b_Suf|IsString, { 0, 0, 0} }, +-{"xlat", 1, 0xd7, X, 0, b_Suf|IsString, { AnyMem, 0, 0} }, +- +-/* Bit manipulation. */ +-{"bsf", 2, 0x0fbc, X, Cpu386, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"bsr", 2, 0x0fbd, X, Cpu386, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"bt", 2, 0x0fa3, X, Cpu386, wlq_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, +-{"bt", 2, 0x0fba, 4, Cpu386, wlq_Suf|Modrm, { Imm8, WordReg|WordMem, 0} }, +-{"btc", 2, 0x0fbb, X, Cpu386, wlq_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, +-{"btc", 2, 0x0fba, 7, Cpu386, wlq_Suf|Modrm, { Imm8, WordReg|WordMem, 0} }, +-{"btr", 2, 0x0fb3, X, Cpu386, wlq_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, +-{"btr", 2, 0x0fba, 6, Cpu386, wlq_Suf|Modrm, { Imm8, WordReg|WordMem, 0} }, +-{"bts", 2, 0x0fab, X, Cpu386, wlq_Suf|Modrm, { WordReg, WordReg|WordMem, 0} }, +-{"bts", 2, 0x0fba, 5, Cpu386, wlq_Suf|Modrm, { Imm8, WordReg|WordMem, 0} }, +- +-/* Interrupts & op. sys insns. */ +-/* See gas/config/tc-i386.c for conversion of 'int $3' into the special +- int 3 insn. */ +-#define INT_OPCODE 0xcd ++#define INT_OPCODE 0xcd + #define INT3_OPCODE 0xcc +-{"int", 1, 0xcd, X, 0, NoSuf, { Imm8, 0, 0} }, +-{"int3", 0, 0xcc, X, 0, NoSuf, { 0, 0, 0} }, +-{"into", 0, 0xce, X, 0, NoSuf, { 0, 0, 0} }, +-{"iret", 0, 0xcf, X, 0, wlq_Suf|DefaultSize, { 0, 0, 0} }, +-/* i386sl, i486sl, later 486, and Pentium. */ +-{"rsm", 0, 0x0faa, X, Cpu386, NoSuf, { 0, 0, 0} }, +- +-{"bound", 2, 0x62, X, Cpu186, wlq_Suf|Modrm, { WordReg, WordMem, 0} }, +- +-{"hlt", 0, 0xf4, X, 0, NoSuf, { 0, 0, 0} }, +-/* nop is actually 'xchgl %eax, %eax'. */ +-{"nop", 0, 0x90, X, 0, NoSuf, { 0, 0, 0} }, +- +-/* Protection control. */ +-{"arpl", 2, 0x63, X, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16, Reg16|ShortMem, 0} }, +-{"lar", 2, 0x0f02, X, Cpu286, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"lgdt", 1, 0x0f01, 2, Cpu286, wlq_Suf|Modrm, { WordMem, 0, 0} }, +-{"lidt", 1, 0x0f01, 3, Cpu286, wlq_Suf|Modrm, { WordMem, 0, 0} }, +-{"lldt", 1, 0x0f00, 2, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, +-{"lmsw", 1, 0x0f01, 6, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, +-{"lsl", 2, 0x0f03, X, Cpu286, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"ltr", 1, 0x0f00, 3, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, +- +-{"sgdt", 1, 0x0f01, 0, Cpu286, wlq_Suf|Modrm, { WordMem, 0, 0} }, +-{"sidt", 1, 0x0f01, 1, Cpu286, wlq_Suf|Modrm, { WordMem, 0, 0} }, +-{"sldt", 1, 0x0f00, 0, Cpu286, wlq_Suf|Modrm, { WordReg|InvMem, 0, 0} }, +-{"sldt", 1, 0x0f00, 0, Cpu286, w_Suf|Modrm|IgnoreSize,{ ShortMem, 0, 0} }, +-{"smsw", 1, 0x0f01, 4, Cpu286, wlq_Suf|Modrm, { WordReg|InvMem, 0, 0} }, +-{"smsw", 1, 0x0f01, 4, Cpu286, w_Suf|Modrm|IgnoreSize,{ ShortMem, 0, 0} }, +-{"str", 1, 0x0f00, 1, Cpu286, wlq_Suf|Modrm, { WordReg|InvMem, 0, 0} }, +-{"str", 1, 0x0f00, 1, Cpu286, w_Suf|Modrm|IgnoreSize,{ ShortMem, 0, 0} }, +- +-{"verr", 1, 0x0f00, 4, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, +-{"verw", 1, 0x0f00, 5, Cpu286, w_Suf|Modrm|IgnoreSize,{ Reg16|ShortMem, 0, 0} }, +- +-/* Floating point instructions. */ +- +-/* load */ +-{"fld", 1, 0xd9c0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fld", 1, 0xd9, 0, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fld", 1, 0xd9c0, X, 0, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} }, +-/* Intel Syntax */ +-{"fld", 1, 0xdb, 5, 0, x_FP|Modrm, { LLongMem, 0, 0} }, +-{"fild", 1, 0xdf, 0, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +-/* Intel Syntax */ +-{"fildd", 1, 0xdf, 5, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fildq", 1, 0xdf, 5, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fildll", 1, 0xdf, 5, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fldt", 1, 0xdb, 5, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fbld", 1, 0xdf, 4, 0, FP|Modrm, { LLongMem, 0, 0} }, +- +-/* store (no pop) */ +-{"fst", 1, 0xddd0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fst", 1, 0xd9, 2, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fst", 1, 0xddd0, X, 0, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} }, +-{"fist", 1, 0xdf, 2, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-/* store (with pop) */ +-{"fstp", 1, 0xddd8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fstp", 1, 0xd9, 3, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fstp", 1, 0xddd8, X, 0, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} }, +-/* Intel Syntax */ +-{"fstp", 1, 0xdb, 7, 0, x_FP|Modrm, { LLongMem, 0, 0} }, +-{"fistp", 1, 0xdf, 3, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +-/* Intel Syntax */ +-{"fistpd", 1, 0xdf, 7, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fistpq", 1, 0xdf, 7, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fistpll",1, 0xdf, 7, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fstpt", 1, 0xdb, 7, 0, FP|Modrm, { LLongMem, 0, 0} }, +-{"fbstp", 1, 0xdf, 6, 0, FP|Modrm, { LLongMem, 0, 0} }, +- +-/* exchange %st with %st0 */ +-{"fxch", 1, 0xd9c8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-/* alias for fxch %st(1) */ +-{"fxch", 0, 0xd9c9, X, 0, FP, { 0, 0, 0} }, +- +-/* comparison (without pop) */ +-{"fcom", 1, 0xd8d0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-/* alias for fcom %st(1) */ +-{"fcom", 0, 0xd8d1, X, 0, FP, { 0, 0, 0} }, +-{"fcom", 1, 0xd8, 2, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fcom", 1, 0xd8d0, X, 0, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} }, +-{"ficom", 1, 0xde, 2, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-/* comparison (with pop) */ +-{"fcomp", 1, 0xd8d8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-/* alias for fcomp %st(1) */ +-{"fcomp", 0, 0xd8d9, X, 0, FP, { 0, 0, 0} }, +-{"fcomp", 1, 0xd8, 3, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fcomp", 1, 0xd8d8, X, 0, l_FP|ShortForm|Ugh, { FloatReg, 0, 0} }, +-{"ficomp", 1, 0xde, 3, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +-{"fcompp", 0, 0xded9, X, 0, FP, { 0, 0, 0} }, +- +-/* unordered comparison (with pop) */ +-{"fucom", 1, 0xdde0, X, Cpu286, FP|ShortForm, { FloatReg, 0, 0} }, +-/* alias for fucom %st(1) */ +-{"fucom", 0, 0xdde1, X, Cpu286, FP, { 0, 0, 0} }, +-{"fucomp", 1, 0xdde8, X, Cpu286, FP|ShortForm, { FloatReg, 0, 0} }, +-/* alias for fucomp %st(1) */ +-{"fucomp", 0, 0xdde9, X, Cpu286, FP, { 0, 0, 0} }, +-{"fucompp",0, 0xdae9, X, Cpu286, FP, { 0, 0, 0} }, +- +-{"ftst", 0, 0xd9e4, X, 0, FP, { 0, 0, 0} }, +-{"fxam", 0, 0xd9e5, X, 0, FP, { 0, 0, 0} }, +- +-/* load constants into %st0 */ +-{"fld1", 0, 0xd9e8, X, 0, FP, { 0, 0, 0} }, +-{"fldl2t", 0, 0xd9e9, X, 0, FP, { 0, 0, 0} }, +-{"fldl2e", 0, 0xd9ea, X, 0, FP, { 0, 0, 0} }, +-{"fldpi", 0, 0xd9eb, X, 0, FP, { 0, 0, 0} }, +-{"fldlg2", 0, 0xd9ec, X, 0, FP, { 0, 0, 0} }, +-{"fldln2", 0, 0xd9ed, X, 0, FP, { 0, 0, 0} }, +-{"fldz", 0, 0xd9ee, X, 0, FP, { 0, 0, 0} }, +- +-/* arithmetic */ +- +-/* add */ +-{"fadd", 2, 0xd8c0, X, 0, FP|ShortForm|FloatD, { FloatReg, FloatAcc, 0} }, +-/* alias for fadd %st(i), %st */ +-{"fadd", 1, 0xd8c0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-#if SYSV386_COMPAT +-/* alias for faddp */ +-{"fadd", 0, 0xdec1, X, 0, FP|Ugh, { 0, 0, 0} }, +-#endif +-{"fadd", 1, 0xd8, 0, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fiadd", 1, 0xde, 0, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-{"faddp", 2, 0xdec0, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"faddp", 1, 0xdec0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-/* alias for faddp %st, %st(1) */ +-{"faddp", 0, 0xdec1, X, 0, FP, { 0, 0, 0} }, +-{"faddp", 2, 0xdec0, X, 0, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} }, +- +-/* subtract */ +-{"fsub", 2, 0xd8e0, X, 0, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} }, +-{"fsub", 1, 0xd8e0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-#if SYSV386_COMPAT +-/* alias for fsubp */ +-{"fsub", 0, 0xdee1, X, 0, FP|Ugh, { 0, 0, 0} }, +-#endif +-{"fsub", 1, 0xd8, 4, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fisub", 1, 0xde, 4, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-#if SYSV386_COMPAT +-{"fsubp", 2, 0xdee0, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fsubp", 1, 0xdee0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fsubp", 0, 0xdee1, X, 0, FP, { 0, 0, 0} }, +-#if OLDGCC_COMPAT +-{"fsubp", 2, 0xdee0, X, 0, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} }, +-#endif +-#else +-{"fsubp", 2, 0xdee8, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fsubp", 1, 0xdee8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fsubp", 0, 0xdee9, X, 0, FP, { 0, 0, 0} }, +-#endif +- +-/* subtract reverse */ +-{"fsubr", 2, 0xd8e8, X, 0, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} }, +-{"fsubr", 1, 0xd8e8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-#if SYSV386_COMPAT +-/* alias for fsubrp */ +-{"fsubr", 0, 0xdee9, X, 0, FP|Ugh, { 0, 0, 0} }, +-#endif +-{"fsubr", 1, 0xd8, 5, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fisubr", 1, 0xde, 5, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-#if SYSV386_COMPAT +-{"fsubrp", 2, 0xdee8, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fsubrp", 1, 0xdee8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fsubrp", 0, 0xdee9, X, 0, FP, { 0, 0, 0} }, +-#if OLDGCC_COMPAT +-{"fsubrp", 2, 0xdee8, X, 0, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} }, +-#endif +-#else +-{"fsubrp", 2, 0xdee0, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fsubrp", 1, 0xdee0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fsubrp", 0, 0xdee1, X, 0, FP, { 0, 0, 0} }, +-#endif +- +-/* multiply */ +-{"fmul", 2, 0xd8c8, X, 0, FP|ShortForm|FloatD, { FloatReg, FloatAcc, 0} }, +-{"fmul", 1, 0xd8c8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-#if SYSV386_COMPAT +-/* alias for fmulp */ +-{"fmul", 0, 0xdec9, X, 0, FP|Ugh, { 0, 0, 0} }, +-#endif +-{"fmul", 1, 0xd8, 1, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fimul", 1, 0xde, 1, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-{"fmulp", 2, 0xdec8, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fmulp", 1, 0xdec8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fmulp", 0, 0xdec9, X, 0, FP, { 0, 0, 0} }, +-{"fmulp", 2, 0xdec8, X, 0, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} }, +- +-/* divide */ +-{"fdiv", 2, 0xd8f0, X, 0, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} }, +-{"fdiv", 1, 0xd8f0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-#if SYSV386_COMPAT +-/* alias for fdivp */ +-{"fdiv", 0, 0xdef1, X, 0, FP|Ugh, { 0, 0, 0} }, +-#endif +-{"fdiv", 1, 0xd8, 6, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fidiv", 1, 0xde, 6, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-#if SYSV386_COMPAT +-{"fdivp", 2, 0xdef0, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fdivp", 1, 0xdef0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fdivp", 0, 0xdef1, X, 0, FP, { 0, 0, 0} }, +-#if OLDGCC_COMPAT +-{"fdivp", 2, 0xdef0, X, 0, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} }, +-#endif +-#else +-{"fdivp", 2, 0xdef8, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fdivp", 1, 0xdef8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fdivp", 0, 0xdef9, X, 0, FP, { 0, 0, 0} }, +-#endif +- +-/* divide reverse */ +-{"fdivr", 2, 0xd8f8, X, 0, FP|ShortForm|FloatDR, { FloatReg, FloatAcc, 0} }, +-{"fdivr", 1, 0xd8f8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-#if SYSV386_COMPAT +-/* alias for fdivrp */ +-{"fdivr", 0, 0xdef9, X, 0, FP|Ugh, { 0, 0, 0} }, +-#endif +-{"fdivr", 1, 0xd8, 7, 0, sl_FP|FloatMF|Modrm, { LongMem|LLongMem, 0, 0} }, +-{"fidivr", 1, 0xde, 7, 0, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +- +-#if SYSV386_COMPAT +-{"fdivrp", 2, 0xdef8, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fdivrp", 1, 0xdef8, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fdivrp", 0, 0xdef9, X, 0, FP, { 0, 0, 0} }, +-#if OLDGCC_COMPAT +-{"fdivrp", 2, 0xdef8, X, 0, FP|ShortForm|Ugh, { FloatReg, FloatAcc, 0} }, +-#endif +-#else +-{"fdivrp", 2, 0xdef0, X, 0, FP|ShortForm, { FloatAcc, FloatReg, 0} }, +-{"fdivrp", 1, 0xdef0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fdivrp", 0, 0xdef1, X, 0, FP, { 0, 0, 0} }, +-#endif +- +-{"f2xm1", 0, 0xd9f0, X, 0, FP, { 0, 0, 0} }, +-{"fyl2x", 0, 0xd9f1, X, 0, FP, { 0, 0, 0} }, +-{"fptan", 0, 0xd9f2, X, 0, FP, { 0, 0, 0} }, +-{"fpatan", 0, 0xd9f3, X, 0, FP, { 0, 0, 0} }, +-{"fxtract",0, 0xd9f4, X, 0, FP, { 0, 0, 0} }, +-{"fprem1", 0, 0xd9f5, X, Cpu286, FP, { 0, 0, 0} }, +-{"fdecstp",0, 0xd9f6, X, 0, FP, { 0, 0, 0} }, +-{"fincstp",0, 0xd9f7, X, 0, FP, { 0, 0, 0} }, +-{"fprem", 0, 0xd9f8, X, 0, FP, { 0, 0, 0} }, +-{"fyl2xp1",0, 0xd9f9, X, 0, FP, { 0, 0, 0} }, +-{"fsqrt", 0, 0xd9fa, X, 0, FP, { 0, 0, 0} }, +-{"fsincos",0, 0xd9fb, X, Cpu286, FP, { 0, 0, 0} }, +-{"frndint",0, 0xd9fc, X, 0, FP, { 0, 0, 0} }, +-{"fscale", 0, 0xd9fd, X, 0, FP, { 0, 0, 0} }, +-{"fsin", 0, 0xd9fe, X, Cpu286, FP, { 0, 0, 0} }, +-{"fcos", 0, 0xd9ff, X, Cpu286, FP, { 0, 0, 0} }, +-{"fchs", 0, 0xd9e0, X, 0, FP, { 0, 0, 0} }, +-{"fabs", 0, 0xd9e1, X, 0, FP, { 0, 0, 0} }, +- +-/* processor control */ +-{"fninit", 0, 0xdbe3, X, 0, FP, { 0, 0, 0} }, +-{"finit", 0, 0xdbe3, X, 0, FP|FWait, { 0, 0, 0} }, +-{"fldcw", 1, 0xd9, 5, 0, FP|Modrm, { ShortMem, 0, 0} }, +-{"fnstcw", 1, 0xd9, 7, 0, FP|Modrm, { ShortMem, 0, 0} }, +-{"fstcw", 1, 0xd9, 7, 0, FP|FWait|Modrm, { ShortMem, 0, 0} }, +-{"fnstsw", 1, 0xdfe0, X, 0, FP, { Acc, 0, 0} }, +-{"fnstsw", 1, 0xdd, 7, 0, FP|Modrm, { ShortMem, 0, 0} }, +-{"fnstsw", 0, 0xdfe0, X, 0, FP, { 0, 0, 0} }, +-{"fstsw", 1, 0xdfe0, X, 0, FP|FWait, { Acc, 0, 0} }, +-{"fstsw", 1, 0xdd, 7, 0, FP|FWait|Modrm, { ShortMem, 0, 0} }, +-{"fstsw", 0, 0xdfe0, X, 0, FP|FWait, { 0, 0, 0} }, +-{"fnclex", 0, 0xdbe2, X, 0, FP, { 0, 0, 0} }, +-{"fclex", 0, 0xdbe2, X, 0, FP|FWait, { 0, 0, 0} }, +-/* Short forms of fldenv, fstenv use data size prefix. */ +-{"fnstenv",1, 0xd9, 6, 0, sl_Suf|Modrm, { LLongMem, 0, 0} }, +-{"fstenv", 1, 0xd9, 6, 0, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} }, +-{"fldenv", 1, 0xd9, 4, 0, sl_Suf|Modrm, { LLongMem, 0, 0} }, +-{"fnsave", 1, 0xdd, 6, 0, sl_Suf|Modrm, { LLongMem, 0, 0} }, +-{"fsave", 1, 0xdd, 6, 0, sl_Suf|FWait|Modrm, { LLongMem, 0, 0} }, +-{"frstor", 1, 0xdd, 4, 0, sl_Suf|Modrm, { LLongMem, 0, 0} }, +- +-{"ffree", 1, 0xddc0, X, 0, FP|ShortForm, { FloatReg, 0, 0} }, +-/* P6:free st(i), pop st */ +-{"ffreep", 1, 0xdfc0, X, Cpu686, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fnop", 0, 0xd9d0, X, 0, FP, { 0, 0, 0} }, ++/* The opcode for the fwait instruction, which disassembler treats as a ++ prefix when it can. */ + #define FWAIT_OPCODE 0x9b +-{"fwait", 0, 0x9b, X, 0, FP, { 0, 0, 0} }, +- +-/* Opcode prefixes; we allow them as separate insns too. */ +- + #define ADDR_PREFIX_OPCODE 0x67 +-{"addr16", 0, 0x67, X, Cpu386, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} }, +-{"addr32", 0, 0x67, X, Cpu386, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} }, +-{"aword", 0, 0x67, X, Cpu386, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} }, +-{"adword", 0, 0x67, X, Cpu386, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} }, + #define DATA_PREFIX_OPCODE 0x66 +-{"data16", 0, 0x66, X, Cpu386, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} }, +-{"data32", 0, 0x66, X, Cpu386, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} }, +-{"word", 0, 0x66, X, Cpu386, NoSuf|IsPrefix|Size16|IgnoreSize, { 0, 0, 0} }, +-{"dword", 0, 0x66, X, Cpu386, NoSuf|IsPrefix|Size32|IgnoreSize, { 0, 0, 0} }, + #define LOCK_PREFIX_OPCODE 0xf0 +-{"lock", 0, 0xf0, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"wait", 0, 0x9b, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, + #define CS_PREFIX_OPCODE 0x2e +-{"cs", 0, 0x2e, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, + #define DS_PREFIX_OPCODE 0x3e +-{"ds", 0, 0x3e, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, + #define ES_PREFIX_OPCODE 0x26 +-{"es", 0, 0x26, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, + #define FS_PREFIX_OPCODE 0x64 +-{"fs", 0, 0x64, X, Cpu386, NoSuf|IsPrefix, { 0, 0, 0} }, + #define GS_PREFIX_OPCODE 0x65 +-{"gs", 0, 0x65, X, Cpu386, NoSuf|IsPrefix, { 0, 0, 0} }, + #define SS_PREFIX_OPCODE 0x36 +-{"ss", 0, 0x36, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, + #define REPNE_PREFIX_OPCODE 0xf2 + #define REPE_PREFIX_OPCODE 0xf3 +-{"rep", 0, 0xf3, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"repe", 0, 0xf3, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"repz", 0, 0xf3, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"repne", 0, 0xf2, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"repnz", 0, 0xf2, X, 0, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex", 0, 0x40, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rexz", 0, 0x41, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rexy", 0, 0x42, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rexyz", 0, 0x43, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rexx", 0, 0x44, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rexxz", 0, 0x45, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rexxy", 0, 0x46, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rexxyz", 0, 0x47, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64", 0, 0x48, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64z", 0, 0x49, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64y", 0, 0x4a, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64yz",0, 0x4b, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64x", 0, 0x4c, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64xz",0, 0x4d, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64xy",0, 0x4e, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +-{"rex64xyz",0, 0x4f, X, Cpu64, NoSuf|IsPrefix, { 0, 0, 0} }, +- +-/* 486 extensions. */ +- +-{"bswap", 1, 0x0fc8, X, Cpu486, lq_Suf|ShortForm, { Reg32|Reg64, 0, 0 } }, +-{"xadd", 2, 0x0fc0, X, Cpu486, bwlq_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } }, +-{"cmpxchg", 2, 0x0fb0, X, Cpu486, bwlq_Suf|W|Modrm, { Reg, Reg|AnyMem, 0 } }, +-{"invd", 0, 0x0f08, X, Cpu486, NoSuf, { 0, 0, 0} }, +-{"wbinvd", 0, 0x0f09, X, Cpu486, NoSuf, { 0, 0, 0} }, +-{"invlpg", 1, 0x0f01, 7, Cpu486, NoSuf|Modrm, { AnyMem, 0, 0} }, +- +-/* 586 and late 486 extensions. */ +-{"cpuid", 0, 0x0fa2, X, Cpu486, NoSuf, { 0, 0, 0} }, +- +-/* Pentium extensions. */ +-{"wrmsr", 0, 0x0f30, X, Cpu586, NoSuf, { 0, 0, 0} }, +-{"rdtsc", 0, 0x0f31, X, Cpu586, NoSuf, { 0, 0, 0} }, +-{"rdmsr", 0, 0x0f32, X, Cpu586, NoSuf, { 0, 0, 0} }, +-{"cmpxchg8b",1,0x0fc7, 1, Cpu586, NoSuf|Modrm, { LLongMem, 0, 0} }, +- +-/* Pentium II/Pentium Pro extensions. */ +-{"sysenter",0, 0x0f34, X, Cpu686|CpuNo64, NoSuf, { 0, 0, 0} }, +-{"sysexit", 0, 0x0f35, X, Cpu686|CpuNo64, NoSuf, { 0, 0, 0} }, +-{"fxsave", 1, 0x0fae, 0, Cpu686, FP|Modrm, { LLongMem, 0, 0} }, +-{"fxrstor", 1, 0x0fae, 1, Cpu686, FP|Modrm, { LLongMem, 0, 0} }, +-{"rdpmc", 0, 0x0f33, X, Cpu686, NoSuf, { 0, 0, 0} }, +-/* official undefined instr. */ +-{"ud2", 0, 0x0f0b, X, Cpu686, NoSuf, { 0, 0, 0} }, +-/* alias for ud2 */ +-{"ud2a", 0, 0x0f0b, X, Cpu686, NoSuf, { 0, 0, 0} }, +-/* 2nd. official undefined instr. */ +-{"ud2b", 0, 0x0fb9, X, Cpu686, NoSuf, { 0, 0, 0} }, +- +-{"cmovo", 2, 0x0f40, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovno", 2, 0x0f41, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovb", 2, 0x0f42, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovc", 2, 0x0f42, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnae", 2, 0x0f42, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovae", 2, 0x0f43, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnc", 2, 0x0f43, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnb", 2, 0x0f43, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmove", 2, 0x0f44, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovz", 2, 0x0f44, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovne", 2, 0x0f45, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnz", 2, 0x0f45, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovbe", 2, 0x0f46, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovna", 2, 0x0f46, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmova", 2, 0x0f47, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnbe", 2, 0x0f47, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovs", 2, 0x0f48, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovns", 2, 0x0f49, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovp", 2, 0x0f4a, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnp", 2, 0x0f4b, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovl", 2, 0x0f4c, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnge", 2, 0x0f4c, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovge", 2, 0x0f4d, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnl", 2, 0x0f4d, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovle", 2, 0x0f4e, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovng", 2, 0x0f4e, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovg", 2, 0x0f4f, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +-{"cmovnle", 2, 0x0f4f, X, Cpu686, wlq_Suf|Modrm, { WordReg|WordMem, WordReg, 0} }, +- +-{"fcmovb", 2, 0xdac0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovnae",2, 0xdac0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmove", 2, 0xdac8, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovbe", 2, 0xdad0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovna", 2, 0xdad0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovu", 2, 0xdad8, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovae", 2, 0xdbc0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovnb", 2, 0xdbc0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovne", 2, 0xdbc8, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmova", 2, 0xdbd0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovnbe",2, 0xdbd0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcmovnu", 2, 0xdbd8, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +- +-{"fcomi", 2, 0xdbf0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcomi", 0, 0xdbf1, X, Cpu686, FP|ShortForm, { 0, 0, 0} }, +-{"fcomi", 1, 0xdbf0, X, Cpu686, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fucomi", 2, 0xdbe8, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fucomi", 0, 0xdbe9, X, Cpu686, FP|ShortForm, { 0, 0, 0} }, +-{"fucomi", 1, 0xdbe8, X, Cpu686, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fcomip", 2, 0xdff0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcompi", 2, 0xdff0, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fcompi", 0, 0xdff1, X, Cpu686, FP|ShortForm, { 0, 0, 0} }, +-{"fcompi", 1, 0xdff0, X, Cpu686, FP|ShortForm, { FloatReg, 0, 0} }, +-{"fucomip", 2, 0xdfe8, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fucompi", 2, 0xdfe8, X, Cpu686, FP|ShortForm, { FloatReg, FloatAcc, 0} }, +-{"fucompi", 0, 0xdfe9, X, Cpu686, FP|ShortForm, { 0, 0, 0} }, +-{"fucompi", 1, 0xdfe8, X, Cpu686, FP|ShortForm, { FloatReg, 0, 0} }, +- +-/* Pentium4 extensions. */ +- +-{"movnti", 2, 0x0fc3, X, CpuP4, FP|Modrm, { WordReg, WordMem, 0 } }, +-{"clflush", 1, 0x0fae, 7, CpuP4, FP|Modrm, { ByteMem, 0, 0 } }, +-{"lfence", 0, 0x0fae, 0xe8, CpuP4, FP|ImmExt, { 0, 0, 0 } }, +-{"mfence", 0, 0x0fae, 0xf0, CpuP4, FP|ImmExt, { 0, 0, 0 } }, +-{"pause", 0, 0xf390, X, CpuP4, FP, { 0, 0, 0 } }, +- +-/* MMX/SSE2 instructions. */ +- +-{"emms", 0, 0x0f77, X, CpuMMX, FP, { 0, 0, 0 } }, +-{"movd", 2, 0x0f6e, X, CpuMMX, FP|Modrm, { Reg32|LongMem, RegMMX, 0 } }, +-{"movd", 2, 0x0f7e, X, CpuMMX, FP|Modrm, { RegMMX, Reg32|LongMem, 0 } }, +-{"movd", 2, 0x660f6e,X,CpuSSE2,FP|Modrm, { Reg32|LLongMem, RegXMM, 0 } }, +-{"movd", 2, 0x660f7e,X,CpuSSE2,FP|Modrm, { RegXMM, Reg32|LLongMem, 0 } }, +-/* Real MMX instructions. */ +-{"movd", 2, 0x0f6e, X, CpuMMX, FP|Modrm, { Reg64|LLongMem, RegMMX, 0 } }, +-{"movd", 2, 0x0f7e, X, CpuMMX, FP|Modrm, { RegMMX, Reg64|LLongMem, 0 } }, +-{"movd", 2, 0x660f6e,X,CpuSSE2,FP|Modrm, { Reg64|LLongMem, RegXMM, 0 } }, +-{"movd", 2, 0x660f7e,X,CpuSSE2,FP|Modrm, { RegXMM, Reg64|LLongMem, 0 } }, +-/* In the 64bit mode the short form mov immediate is redefined to have +- 64bit displacement value. */ +-{"movq", 2, 0x0f6f, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"movq", 2, 0x0f7f, X, CpuMMX, FP|Modrm, { RegMMX, RegMMX|LongMem, 0 } }, +-{"movq", 2, 0xf30f7e,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movq", 2, 0x660fd6,X,CpuSSE2,FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +-{"movq", 2, 0x88, X, Cpu64, NoSuf|D|W|Modrm|Size64,{ Reg64, Reg64|AnyMem, 0 } }, +-{"movq", 2, 0xc6, 0, Cpu64, NoSuf|W|Modrm|Size64, { Imm32S, Reg64|WordMem, 0 } }, +-{"movq", 2, 0xb0, X, Cpu64, NoSuf|W|ShortForm|Size64,{ Imm64, Reg64, 0 } }, +-/* Move to/from control debug registers. In the 16 or 32bit modes they are 32bit. In the 64bit +- mode they are 64bit.*/ +-{"movq", 2, 0x0f20, X, Cpu64, NoSuf|D|Modrm|IgnoreSize|NoRex64|Size64,{ Control, Reg64|InvMem, 0} }, +-{"movq", 2, 0x0f21, X, Cpu64, NoSuf|D|Modrm|IgnoreSize|NoRex64|Size64,{ Debug, Reg64|InvMem, 0} }, +-{"packssdw", 2, 0x0f6b, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"packssdw", 2, 0x660f6b,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"packsswb", 2, 0x0f63, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"packsswb", 2, 0x660f63,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"packuswb", 2, 0x0f67, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"packuswb", 2, 0x660f67,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddb", 2, 0x0ffc, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"paddb", 2, 0x660ffc,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddw", 2, 0x0ffd, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"paddw", 2, 0x660ffd,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddd", 2, 0x0ffe, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"paddd", 2, 0x660ffe,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddq", 2, 0x0fd4, X, CpuMMX, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"paddq", 2, 0x660fd4,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddsb", 2, 0x0fec, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"paddsb", 2, 0x660fec,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddsw", 2, 0x0fed, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"paddsw", 2, 0x660fed,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddusb", 2, 0x0fdc, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"paddusb", 2, 0x660fdc,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"paddusw", 2, 0x0fdd, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"paddusw", 2, 0x660fdd,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pand", 2, 0x0fdb, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pand", 2, 0x660fdb,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pandn", 2, 0x0fdf, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pandn", 2, 0x660fdf,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pcmpeqb", 2, 0x0f74, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pcmpeqb", 2, 0x660f74,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pcmpeqw", 2, 0x0f75, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pcmpeqw", 2, 0x660f75,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pcmpeqd", 2, 0x0f76, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pcmpeqd", 2, 0x660f76,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pcmpgtb", 2, 0x0f64, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pcmpgtb", 2, 0x660f64,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pcmpgtw", 2, 0x0f65, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pcmpgtw", 2, 0x660f65,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pcmpgtd", 2, 0x0f66, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pcmpgtd", 2, 0x660f66,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pmaddwd", 2, 0x0ff5, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pmaddwd", 2, 0x660ff5,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pmulhw", 2, 0x0fe5, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pmulhw", 2, 0x660fe5,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pmullw", 2, 0x0fd5, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pmullw", 2, 0x660fd5,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"por", 2, 0x0feb, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"por", 2, 0x660feb,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psllw", 2, 0x0ff1, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psllw", 2, 0x660ff1,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psllw", 2, 0x0f71, 6, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"psllw", 2, 0x660f71,6,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"pslld", 2, 0x0ff2, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pslld", 2, 0x660ff2,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pslld", 2, 0x0f72, 6, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"pslld", 2, 0x660f72,6,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psllq", 2, 0x0ff3, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psllq", 2, 0x660ff3,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psllq", 2, 0x0f73, 6, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"psllq", 2, 0x660f73,6,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psraw", 2, 0x0fe1, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psraw", 2, 0x660fe1,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psraw", 2, 0x0f71, 4, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"psraw", 2, 0x660f71,4,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psrad", 2, 0x0fe2, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psrad", 2, 0x660fe2,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psrad", 2, 0x0f72, 4, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"psrad", 2, 0x660f72,4,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psrlw", 2, 0x0fd1, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psrlw", 2, 0x660fd1,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psrlw", 2, 0x0f71, 2, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"psrlw", 2, 0x660f71,2,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psrld", 2, 0x0fd2, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psrld", 2, 0x660fd2,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psrld", 2, 0x0f72, 2, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"psrld", 2, 0x660f72,2,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psrlq", 2, 0x0fd3, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psrlq", 2, 0x660fd3,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psrlq", 2, 0x0f73, 2, CpuMMX, FP|Modrm, { Imm8, RegMMX, 0 } }, +-{"psrlq", 2, 0x660f73,2,CpuSSE2,FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psubb", 2, 0x0ff8, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psubb", 2, 0x660ff8,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psubw", 2, 0x0ff9, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psubw", 2, 0x660ff9,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psubd", 2, 0x0ffa, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psubd", 2, 0x660ffa,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psubq", 2, 0x0ffb, X, CpuMMX, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"psubq", 2, 0x660ffb,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psubsb", 2, 0x0fe8, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psubsb", 2, 0x660fe8,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psubsw", 2, 0x0fe9, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psubsw", 2, 0x660fe9,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psubusb", 2, 0x0fd8, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psubusb", 2, 0x660fd8,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"psubusw", 2, 0x0fd9, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"psubusw", 2, 0x660fd9,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"punpckhbw",2, 0x0f68, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"punpckhbw",2, 0x660f68,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"punpckhwd",2, 0x0f69, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"punpckhwd",2, 0x660f69,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"punpckhdq",2, 0x0f6a, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"punpckhdq",2, 0x660f6a,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"punpcklbw",2, 0x0f60, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"punpcklbw",2, 0x660f60,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"punpcklwd",2, 0x0f61, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"punpcklwd",2, 0x660f61,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"punpckldq",2, 0x0f62, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"punpckldq",2, 0x660f62,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pxor", 2, 0x0fef, X, CpuMMX, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pxor", 2, 0x660fef,X,CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +- +-/* PIII Katmai New Instructions / SIMD instructions. */ +- +-{"addps", 2, 0x0f58, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"addss", 2, 0xf30f58, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"andnps", 2, 0x0f55, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"andps", 2, 0x0f54, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpeqps", 2, 0x0fc2, 0, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpeqss", 2, 0xf30fc2, 0, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpleps", 2, 0x0fc2, 2, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpless", 2, 0xf30fc2, 2, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpltps", 2, 0x0fc2, 1, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpltss", 2, 0xf30fc2, 1, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpneqps", 2, 0x0fc2, 4, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpneqss", 2, 0xf30fc2, 4, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpnleps", 2, 0x0fc2, 6, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpnless", 2, 0xf30fc2, 6, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpnltps", 2, 0x0fc2, 5, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpnltss", 2, 0xf30fc2, 5, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpordps", 2, 0x0fc2, 7, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpordss", 2, 0xf30fc2, 7, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpunordps",2, 0x0fc2, 3, CpuSSE, FP|Modrm|ImmExt, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpunordss",2, 0xf30fc2, 3, CpuSSE, FP|Modrm|ImmExt, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpps", 3, 0x0fc2, X, CpuSSE, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +-{"cmpss", 3, 0xf30fc2, X, CpuSSE, FP|Modrm, { Imm8, RegXMM|WordMem, RegXMM } }, +-{"comiss", 2, 0x0f2f, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cvtpi2ps", 2, 0x0f2a, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegXMM, 0 } }, +-{"cvtps2pi", 2, 0x0f2d, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegMMX, 0 } }, +-{"cvtsi2ss", 2, 0xf30f2a, X, CpuSSE, lq_Suf|IgnoreSize|Modrm,{ Reg32|Reg64|WordMem|LLongMem, RegXMM, 0 } }, +-{"cvtss2si", 2, 0xf30f2d, X, CpuSSE, lq_Suf|IgnoreSize|Modrm,{ RegXMM|WordMem, Reg32|Reg64, 0 } }, +-{"cvttps2pi", 2, 0x0f2c, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegMMX, 0 } }, +-{"cvttss2si", 2, 0xf30f2c, X, CpuSSE, lq_Suf|IgnoreSize|Modrm, { RegXMM|WordMem, Reg32|Reg64, 0 } }, +-{"divps", 2, 0x0f5e, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"divss", 2, 0xf30f5e, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"ldmxcsr", 1, 0x0fae, 2, CpuSSE, FP|Modrm, { WordMem, 0, 0 } }, +-{"maskmovq", 2, 0x0ff7, X, CpuSSE, FP|Modrm, { RegMMX|InvMem, RegMMX, 0 } }, +-{"maxps", 2, 0x0f5f, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"maxss", 2, 0xf30f5f, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"minps", 2, 0x0f5d, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"minss", 2, 0xf30f5d, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"movaps", 2, 0x0f28, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movaps", 2, 0x0f29, X, CpuSSE, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +-{"movhlps", 2, 0x0f12, X, CpuSSE, FP|Modrm, { RegXMM|InvMem, RegXMM, 0 } }, +-{"movhps", 2, 0x0f16, X, CpuSSE, FP|Modrm, { LLongMem, RegXMM, 0 } }, +-{"movhps", 2, 0x0f17, X, CpuSSE, FP|Modrm, { RegXMM, LLongMem, 0 } }, +-{"movlhps", 2, 0x0f16, X, CpuSSE, FP|Modrm, { RegXMM|InvMem, RegXMM, 0 } }, +-{"movlps", 2, 0x0f12, X, CpuSSE, FP|Modrm, { LLongMem, RegXMM, 0 } }, +-{"movlps", 2, 0x0f13, X, CpuSSE, FP|Modrm, { RegXMM, LLongMem, 0 } }, +-{"movmskps", 2, 0x0f50, X, CpuSSE, lq_Suf|IgnoreSize|Modrm, { RegXMM|InvMem, Reg32|Reg64, 0 } }, +-{"movntps", 2, 0x0f2b, X, CpuSSE, FP|Modrm, { RegXMM, LLongMem, 0 } }, +-{"movntq", 2, 0x0fe7, X, CpuSSE, FP|Modrm, { RegMMX, LLongMem, 0 } }, +-{"movntdq", 2, 0x660fe7, X, CpuSSE2,FP|Modrm, { RegXMM, LLongMem, 0 } }, +-{"movss", 2, 0xf30f10, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"movss", 2, 0xf30f11, X, CpuSSE, FP|Modrm, { RegXMM, RegXMM|WordMem, 0 } }, +-{"movups", 2, 0x0f10, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movups", 2, 0x0f11, X, CpuSSE, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +-{"mulps", 2, 0x0f59, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"mulss", 2, 0xf30f59, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"orps", 2, 0x0f56, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pavgb", 2, 0x0fe0, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"pavgb", 2, 0x660fe0, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pavgw", 2, 0x0fe3, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"pavgw", 2, 0x660fe3, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pextrw", 3, 0x0fc5, X, CpuSSE, lq_Suf|IgnoreSize|Modrm, { Imm8, RegMMX|InvMem, Reg32|Reg64 } }, +-{"pextrw", 3, 0x660fc5, X, CpuSSE2,lq_Suf|IgnoreSize|Modrm, { Imm8, RegXMM|InvMem, Reg32|Reg64 } }, +-{"pinsrw", 3, 0x0fc4, X, CpuSSE, lq_Suf|IgnoreSize|Modrm, { Imm8, Reg32|Reg64|ShortMem, RegMMX } }, +-{"pinsrw", 3, 0x660fc4, X, CpuSSE2, lq_Suf|IgnoreSize|Modrm, { Imm8, Reg32|Reg64|ShortMem, RegXMM } }, +-{"pmaxsw", 2, 0x0fee, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"pmaxsw", 2, 0x660fee, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pmaxub", 2, 0x0fde, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"pmaxub", 2, 0x660fde, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pminsw", 2, 0x0fea, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"pminsw", 2, 0x660fea, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pminub", 2, 0x0fda, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"pminub", 2, 0x660fda, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pmovmskb", 2, 0x0fd7, X, CpuSSE, lq_Suf|IgnoreSize|Modrm, { RegMMX|InvMem, Reg32|Reg64, 0 } }, +-{"pmovmskb", 2, 0x660fd7, X, CpuSSE2,lq_Suf|IgnoreSize|Modrm, { RegXMM|InvMem, Reg32|Reg64, 0 } }, +-{"pmulhuw", 2, 0x0fe4, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"pmulhuw", 2, 0x660fe4, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"prefetchnta", 1, 0x0f18, 0, CpuSSE, FP|Modrm, { LLongMem, 0, 0 } }, +-{"prefetcht0", 1, 0x0f18, 1, CpuSSE, FP|Modrm, { LLongMem, 0, 0 } }, +-{"prefetcht1", 1, 0x0f18, 2, CpuSSE, FP|Modrm, { LLongMem, 0, 0 } }, +-{"prefetcht2", 1, 0x0f18, 3, CpuSSE, FP|Modrm, { LLongMem, 0, 0 } }, +-{"psadbw", 2, 0x0ff6, X, CpuSSE, FP|Modrm, { RegMMX|LLongMem, RegMMX, 0 } }, +-{"psadbw", 2, 0x660ff6, X, CpuSSE2,FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"pshufw", 3, 0x0f70, X, CpuSSE, FP|Modrm, { Imm8, RegMMX|LLongMem, RegMMX } }, +-{"rcpps", 2, 0x0f53, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"rcpss", 2, 0xf30f53, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"rsqrtps", 2, 0x0f52, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"rsqrtss", 2, 0xf30f52, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"sfence", 0, 0x0fae, 0xf8, CpuSSE, FP|ImmExt, { 0, 0, 0 } }, +-{"shufps", 3, 0x0fc6, X, CpuSSE, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +-{"sqrtps", 2, 0x0f51, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"sqrtss", 2, 0xf30f51, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"stmxcsr", 1, 0x0fae, 3, CpuSSE, FP|Modrm, { WordMem, 0, 0 } }, +-{"subps", 2, 0x0f5c, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"subss", 2, 0xf30f5c, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"ucomiss", 2, 0x0f2e, X, CpuSSE, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"unpckhps", 2, 0x0f15, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"unpcklps", 2, 0x0f14, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"xorps", 2, 0x0f57, X, CpuSSE, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +- +-/* SSE-2 instructions. */ +- +-{"addpd", 2, 0x660f58, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"addsd", 2, 0xf20f58, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"andnpd", 2, 0x660f55, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"andpd", 2, 0x660f54, X, CpuSSE2, FP|Modrm, { RegXMM|WordMem, RegXMM, 0 } }, +-{"cmpeqpd", 2, 0x660fc2, 0, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpeqsd", 2, 0xf20fc2, 0, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmplepd", 2, 0x660fc2, 2, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmplesd", 2, 0xf20fc2, 2, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmpltpd", 2, 0x660fc2, 1, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpltsd", 2, 0xf20fc2, 1, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmpneqpd", 2, 0x660fc2, 4, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpneqsd", 2, 0xf20fc2, 4, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmpnlepd", 2, 0x660fc2, 6, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpnlesd", 2, 0xf20fc2, 6, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmpnltpd", 2, 0x660fc2, 5, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpnltsd", 2, 0xf20fc2, 5, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmpordpd", 2, 0x660fc2, 7, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpordsd", 2, 0xf20fc2, 7, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmpunordpd",2, 0x660fc2, 3, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LLongMem, RegXMM, 0 } }, +-{"cmpunordsd",2, 0xf20fc2, 3, CpuSSE2, FP|Modrm|ImmExt,{ RegXMM|LongMem, RegXMM, 0 } }, +-{"cmppd", 3, 0x660fc2, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +-/* Intel mode string compare. */ +-{"cmpsd", 0, 0xa7, X, 0, NoSuf|Size32|IsString, { 0, 0, 0} }, +-{"cmpsd", 2, 0xa7, X, 0, NoSuf|Size32|IsString, { AnyMem, AnyMem|EsSeg, 0} }, +-{"cmpsd", 3, 0xf20fc2, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LongMem, RegXMM } }, +-{"comisd", 2, 0x660f2f, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"cvtpi2pd", 2, 0x660f2a, X, CpuSSE2, FP|Modrm, { RegMMX|LLongMem, RegXMM, 0 } }, +-{"cvtsi2sd", 2, 0xf20f2a, X, CpuSSE2, lq_Suf|IgnoreSize|Modrm,{ Reg32|Reg64|WordMem|LLongMem, RegXMM, 0 } }, +-{"divpd", 2, 0x660f5e, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"divsd", 2, 0xf20f5e, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"maxpd", 2, 0x660f5f, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"maxsd", 2, 0xf20f5f, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"minpd", 2, 0x660f5d, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"minsd", 2, 0xf20f5d, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"movapd", 2, 0x660f28, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movapd", 2, 0x660f29, X, CpuSSE2, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +-{"movhpd", 2, 0x660f16, X, CpuSSE2, FP|Modrm, { LLongMem, RegXMM, 0 } }, +-{"movhpd", 2, 0x660f17, X, CpuSSE2, FP|Modrm, { RegXMM, LLongMem, 0 } }, +-{"movlpd", 2, 0x660f12, X, CpuSSE2, FP|Modrm, { LLongMem, RegXMM, 0 } }, +-{"movlpd", 2, 0x660f13, X, CpuSSE2, FP|Modrm, { RegXMM, LLongMem, 0 } }, +-{"movmskpd", 2, 0x660f50, X, CpuSSE2, lq_Suf|IgnoreSize|Modrm, { RegXMM|InvMem, Reg32|Reg64, 0 } }, +-{"movntpd", 2, 0x660f2b, X, CpuSSE2, FP|Modrm, { RegXMM, LLongMem, 0 } }, +-/* Intel mode string move. */ +-{"movsd", 0, 0xa5, X, 0, NoSuf|Size32|IsString, { 0, 0, 0} }, +-{"movsd", 2, 0xa5, X, 0, NoSuf|Size32|IsString, { AnyMem, AnyMem|EsSeg, 0} }, +-{"movsd", 2, 0xf20f10, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"movsd", 2, 0xf20f11, X, CpuSSE2, FP|Modrm, { RegXMM, RegXMM|LongMem, 0 } }, +-{"movupd", 2, 0x660f10, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movupd", 2, 0x660f11, X, CpuSSE2, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +-{"mulpd", 2, 0x660f59, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"mulsd", 2, 0xf20f59, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"orpd", 2, 0x660f56, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"shufpd", 3, 0x660fc6, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +-{"sqrtpd", 2, 0x660f51, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"sqrtsd", 2, 0xf20f51, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"subpd", 2, 0x660f5c, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"subsd", 2, 0xf20f5c, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"ucomisd", 2, 0x660f2e, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"unpckhpd", 2, 0x660f15, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"unpcklpd", 2, 0x660f14, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"xorpd", 2, 0x660f57, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtdq2pd", 2, 0xf30fe6, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtpd2dq", 2, 0xf20fe6, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtdq2ps", 2, 0x0f5b, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtpd2pi", 2, 0x660f2d, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegMMX, 0 } }, +-{"cvtpd2ps", 2, 0x660f5a, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtps2pd", 2, 0x0f5a, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtps2dq", 2, 0x660f5b, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtsd2si", 2, 0xf20f2d, X, CpuSSE2, lq_Suf|IgnoreSize|Modrm,{ RegXMM|LLongMem, Reg32|Reg64, 0 } }, +-{"cvtsd2ss", 2, 0xf20f5a, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvtss2sd", 2, 0xf30f5a, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvttpd2pi", 2, 0x660f2c, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegMMX, 0 } }, +-{"cvttsd2si", 2, 0xf20f2c, X, CpuSSE2, lq_Suf|IgnoreSize|Modrm,{ RegXMM|WordMem, Reg32|Reg64, 0 } }, +-{"cvttpd2dq", 2, 0x660fe6, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"cvttps2dq", 2, 0xf30f5b, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"maskmovdqu",2, 0x660ff7, X, CpuSSE2, FP|Modrm, { RegXMM|InvMem, RegXMM, 0 } }, +-{"movdqa", 2, 0x660f6f, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movdqa", 2, 0x660f7f, X, CpuSSE2, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +-{"movdqu", 2, 0xf30f6f, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movdqu", 2, 0xf30f7f, X, CpuSSE2, FP|Modrm, { RegXMM, RegXMM|LLongMem, 0 } }, +-{"movdq2q", 2, 0xf20fd6, X, CpuSSE2, FP|Modrm, { RegXMM|InvMem, RegMMX, 0 } }, +-{"movq2dq", 2, 0xf30fd6, X, CpuSSE2, FP|Modrm, { RegMMX|InvMem, RegXMM, 0 } }, +-{"pmuludq", 2, 0x0ff4, X, CpuSSE2, FP|Modrm, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pmuludq", 2, 0x660ff4, X, CpuSSE2, FP|Modrm, { RegXMM|LongMem, RegXMM, 0 } }, +-{"pshufd", 3, 0x660f70, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +-{"pshufhw", 3, 0xf30f70, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +-{"pshuflw", 3, 0xf20f70, X, CpuSSE2, FP|Modrm, { Imm8, RegXMM|LLongMem, RegXMM } }, +-{"pslldq", 2, 0x660f73, 7, CpuSSE2, FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"psrldq", 2, 0x660f73, 3, CpuSSE2, FP|Modrm, { Imm8, RegXMM, 0 } }, +-{"punpckhqdq",2, 0x660f6d, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"punpcklqdq",2, 0x660f6c, X, CpuSSE2, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +- +-/* Prescott New Instructions. */ +- +-{"addsubpd", 2, 0x660fd0, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"addsubps", 2, 0xf20fd0, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"fisttp", 1, 0xdf, 1, CpuPNI, sl_FP|FloatMF|Modrm, { ShortMem|LongMem, 0, 0} }, +-/* Intel Syntax */ +-{"fisttpd", 1, 0xdd, 1, CpuPNI, FP|Modrm, { LLongMem, 0, 0} }, +-{"fisttpq", 1, 0xdd, 1, CpuPNI, FP|Modrm, { LLongMem, 0, 0} }, +-{"fisttpll", 1, 0xdd, 1, CpuPNI, FP|Modrm, { LLongMem, 0, 0} }, +-{"haddpd", 2, 0x660f7c, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"haddps", 2, 0xf20f7c, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"hsubpd", 2, 0x660f7d, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"hsubps", 2, 0xf20f7d, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"lddqu", 2, 0xf20ff0, X, CpuPNI, FP|Modrm, { LLongMem, RegXMM, 0 } }, +-{"monitor", 0, 0x0f01, 0xc8, CpuPNI, FP|ImmExt, { 0, 0, 0} }, +-/* Need to ensure only "monitor %eax,%ecx,%edx" is accepted. */ +-{"monitor", 3, 0x0f01, 0xc8, CpuPNI, FP|ImmExt, { Reg32, Reg32, Reg32} }, +-{"movddup", 2, 0xf20f12, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movshdup", 2, 0xf30f16, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"movsldup", 2, 0xf30f12, X, CpuPNI, FP|Modrm, { RegXMM|LLongMem, RegXMM, 0 } }, +-{"mwait", 0, 0x0f01, 0xc9, CpuPNI, FP|ImmExt, { 0, 0, 0} }, +-/* Need to ensure only "mwait %eax,%ecx" is accepted. */ +-{"mwait", 2, 0x0f01, 0xc9, CpuPNI, FP|ImmExt, { Reg32, Reg32, 0} }, +- +-/* AMD 3DNow! instructions. */ +- +-{"prefetch", 1, 0x0f0d, 0, Cpu3dnow, FP|Modrm, { ByteMem, 0, 0 } }, +-{"prefetchw",1, 0x0f0d, 1, Cpu3dnow, FP|Modrm, { ByteMem, 0, 0 } }, +-{"femms", 0, 0x0f0e, X, Cpu3dnow, FP, { 0, 0, 0 } }, +-{"pavgusb", 2, 0x0f0f, 0xbf, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pf2id", 2, 0x0f0f, 0x1d, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pf2iw", 2, 0x0f0f, 0x1c, Cpu3dnow|Cpu686, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfacc", 2, 0x0f0f, 0xae, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfadd", 2, 0x0f0f, 0x9e, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfcmpeq", 2, 0x0f0f, 0xb0, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfcmpge", 2, 0x0f0f, 0x90, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfcmpgt", 2, 0x0f0f, 0xa0, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfmax", 2, 0x0f0f, 0xa4, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfmin", 2, 0x0f0f, 0x94, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfmul", 2, 0x0f0f, 0xb4, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfnacc", 2, 0x0f0f, 0x8a, Cpu3dnow|Cpu686, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfpnacc", 2, 0x0f0f, 0x8e, Cpu3dnow|Cpu686, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfrcp", 2, 0x0f0f, 0x96, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfrcpit1", 2, 0x0f0f, 0xa6, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfrcpit2", 2, 0x0f0f, 0xb6, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfrsqit1", 2, 0x0f0f, 0xa7, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfrsqrt", 2, 0x0f0f, 0x97, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfsub", 2, 0x0f0f, 0x9a, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pfsubr", 2, 0x0f0f, 0xaa, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pi2fd", 2, 0x0f0f, 0x0d, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pi2fw", 2, 0x0f0f, 0x0c, Cpu3dnow|Cpu686, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pmulhrw", 2, 0x0f0f, 0xb7, Cpu3dnow, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +-{"pswapd", 2, 0x0f0f, 0xbb, Cpu3dnow|Cpu686, FP|Modrm|ImmExt, { RegMMX|LongMem, RegMMX, 0 } }, +- +-/* AMD extensions. */ +-{"syscall", 0, 0x0f05, X, CpuK6, NoSuf, { 0, 0, 0} }, +-{"sysret", 0, 0x0f07, X, CpuK6, lq_Suf|DefaultSize, { 0, 0, 0} }, +-{"swapgs", 0, 0x0f01, 0xf8, Cpu64, NoSuf|ImmExt, { 0, 0, 0} }, +- +-/* sentinel */ +-{NULL, 0, 0, 0, 0, 0, { 0, 0, 0} } +-}; +-#undef X +-#undef NoSuf +-#undef b_Suf +-#undef w_Suf +-#undef l_Suf +-#undef q_Suf +-#undef x_Suf +-#undef bw_Suf +-#undef bl_Suf +-#undef wl_Suf +-#undef wlq_Suf +-#undef sl_Suf +-#undef bwl_Suf +-#undef bwlq_Suf +-#undef FP +-#undef l_FP +-#undef x_FP +-#undef sl_FP +- +-#define MAX_MNEM_SIZE 16 /* for parsing insn mnemonics from input */ +- +- +-/* 386 register table. */ +- +-static const reg_entry i386_regtab[] = { +- /* make %st first as we test for it */ +- {"st", FloatReg|FloatAcc, 0, 0}, +- /* 8 bit regs */ +-#define REGNAM_AL 1 /* Entry in i386_regtab. */ +- {"al", Reg8|Acc, 0, 0}, +- {"cl", Reg8|ShiftCount, 0, 1}, +- {"dl", Reg8, 0, 2}, +- {"bl", Reg8, 0, 3}, +- {"ah", Reg8, 0, 4}, +- {"ch", Reg8, 0, 5}, +- {"dh", Reg8, 0, 6}, +- {"bh", Reg8, 0, 7}, +- {"axl", Reg8|Acc, RegRex64, 0}, /* Must be in the "al + 8" slot. */ +- {"cxl", Reg8, RegRex64, 1}, +- {"dxl", Reg8, RegRex64, 2}, +- {"bxl", Reg8, RegRex64, 3}, +- {"spl", Reg8, RegRex64, 4}, +- {"bpl", Reg8, RegRex64, 5}, +- {"sil", Reg8, RegRex64, 6}, +- {"dil", Reg8, RegRex64, 7}, +- {"r8b", Reg8, RegRex64|RegRex, 0}, +- {"r9b", Reg8, RegRex64|RegRex, 1}, +- {"r10b", Reg8, RegRex64|RegRex, 2}, +- {"r11b", Reg8, RegRex64|RegRex, 3}, +- {"r12b", Reg8, RegRex64|RegRex, 4}, +- {"r13b", Reg8, RegRex64|RegRex, 5}, +- {"r14b", Reg8, RegRex64|RegRex, 6}, +- {"r15b", Reg8, RegRex64|RegRex, 7}, +- /* 16 bit regs */ +-#define REGNAM_AX 25 +- {"ax", Reg16|Acc, 0, 0}, +- {"cx", Reg16, 0, 1}, +- {"dx", Reg16|InOutPortReg, 0, 2}, +- {"bx", Reg16|BaseIndex, 0, 3}, +- {"sp", Reg16, 0, 4}, +- {"bp", Reg16|BaseIndex, 0, 5}, +- {"si", Reg16|BaseIndex, 0, 6}, +- {"di", Reg16|BaseIndex, 0, 7}, +- {"r8w", Reg16, RegRex, 0}, +- {"r9w", Reg16, RegRex, 1}, +- {"r10w", Reg16, RegRex, 2}, +- {"r11w", Reg16, RegRex, 3}, +- {"r12w", Reg16, RegRex, 4}, +- {"r13w", Reg16, RegRex, 5}, +- {"r14w", Reg16, RegRex, 6}, +- {"r15w", Reg16, RegRex, 7}, +- /* 32 bit regs */ +-#define REGNAM_EAX 41 +- {"eax", Reg32|BaseIndex|Acc, 0, 0}, /* Must be in ax + 16 slot */ +- {"ecx", Reg32|BaseIndex, 0, 1}, +- {"edx", Reg32|BaseIndex, 0, 2}, +- {"ebx", Reg32|BaseIndex, 0, 3}, +- {"esp", Reg32, 0, 4}, +- {"ebp", Reg32|BaseIndex, 0, 5}, +- {"esi", Reg32|BaseIndex, 0, 6}, +- {"edi", Reg32|BaseIndex, 0, 7}, +- {"r8d", Reg32|BaseIndex, RegRex, 0}, +- {"r9d", Reg32|BaseIndex, RegRex, 1}, +- {"r10d", Reg32|BaseIndex, RegRex, 2}, +- {"r11d", Reg32|BaseIndex, RegRex, 3}, +- {"r12d", Reg32|BaseIndex, RegRex, 4}, +- {"r13d", Reg32|BaseIndex, RegRex, 5}, +- {"r14d", Reg32|BaseIndex, RegRex, 6}, +- {"r15d", Reg32|BaseIndex, RegRex, 7}, +- {"rax", Reg64|BaseIndex|Acc, 0, 0}, +- {"rcx", Reg64|BaseIndex, 0, 1}, +- {"rdx", Reg64|BaseIndex, 0, 2}, +- {"rbx", Reg64|BaseIndex, 0, 3}, +- {"rsp", Reg64, 0, 4}, +- {"rbp", Reg64|BaseIndex, 0, 5}, +- {"rsi", Reg64|BaseIndex, 0, 6}, +- {"rdi", Reg64|BaseIndex, 0, 7}, +- {"r8", Reg64|BaseIndex, RegRex, 0}, +- {"r9", Reg64|BaseIndex, RegRex, 1}, +- {"r10", Reg64|BaseIndex, RegRex, 2}, +- {"r11", Reg64|BaseIndex, RegRex, 3}, +- {"r12", Reg64|BaseIndex, RegRex, 4}, +- {"r13", Reg64|BaseIndex, RegRex, 5}, +- {"r14", Reg64|BaseIndex, RegRex, 6}, +- {"r15", Reg64|BaseIndex, RegRex, 7}, +- /* segment registers */ +- {"es", SReg2, 0, 0}, +- {"cs", SReg2, 0, 1}, +- {"ss", SReg2, 0, 2}, +- {"ds", SReg2, 0, 3}, +- {"fs", SReg3, 0, 4}, +- {"gs", SReg3, 0, 5}, +- /* control registers */ +- {"cr0", Control, 0, 0}, +- {"cr1", Control, 0, 1}, +- {"cr2", Control, 0, 2}, +- {"cr3", Control, 0, 3}, +- {"cr4", Control, 0, 4}, +- {"cr5", Control, 0, 5}, +- {"cr6", Control, 0, 6}, +- {"cr7", Control, 0, 7}, +- {"cr8", Control, RegRex, 0}, +- {"cr9", Control, RegRex, 1}, +- {"cr10", Control, RegRex, 2}, +- {"cr11", Control, RegRex, 3}, +- {"cr12", Control, RegRex, 4}, +- {"cr13", Control, RegRex, 5}, +- {"cr14", Control, RegRex, 6}, +- {"cr15", Control, RegRex, 7}, +- /* debug registers */ +- {"db0", Debug, 0, 0}, +- {"db1", Debug, 0, 1}, +- {"db2", Debug, 0, 2}, +- {"db3", Debug, 0, 3}, +- {"db4", Debug, 0, 4}, +- {"db5", Debug, 0, 5}, +- {"db6", Debug, 0, 6}, +- {"db7", Debug, 0, 7}, +- {"db8", Debug, RegRex, 0}, +- {"db9", Debug, RegRex, 1}, +- {"db10", Debug, RegRex, 2}, +- {"db11", Debug, RegRex, 3}, +- {"db12", Debug, RegRex, 4}, +- {"db13", Debug, RegRex, 5}, +- {"db14", Debug, RegRex, 6}, +- {"db15", Debug, RegRex, 7}, +- {"dr0", Debug, 0, 0}, +- {"dr1", Debug, 0, 1}, +- {"dr2", Debug, 0, 2}, +- {"dr3", Debug, 0, 3}, +- {"dr4", Debug, 0, 4}, +- {"dr5", Debug, 0, 5}, +- {"dr6", Debug, 0, 6}, +- {"dr7", Debug, 0, 7}, +- {"dr8", Debug, RegRex, 0}, +- {"dr9", Debug, RegRex, 1}, +- {"dr10", Debug, RegRex, 2}, +- {"dr11", Debug, RegRex, 3}, +- {"dr12", Debug, RegRex, 4}, +- {"dr13", Debug, RegRex, 5}, +- {"dr14", Debug, RegRex, 6}, +- {"dr15", Debug, RegRex, 7}, +- /* test registers */ +- {"tr0", Test, 0, 0}, +- {"tr1", Test, 0, 1}, +- {"tr2", Test, 0, 2}, +- {"tr3", Test, 0, 3}, +- {"tr4", Test, 0, 4}, +- {"tr5", Test, 0, 5}, +- {"tr6", Test, 0, 6}, +- {"tr7", Test, 0, 7}, +- /* mmx and simd registers */ +- {"mm0", RegMMX, 0, 0}, +- {"mm1", RegMMX, 0, 1}, +- {"mm2", RegMMX, 0, 2}, +- {"mm3", RegMMX, 0, 3}, +- {"mm4", RegMMX, 0, 4}, +- {"mm5", RegMMX, 0, 5}, +- {"mm6", RegMMX, 0, 6}, +- {"mm7", RegMMX, 0, 7}, +- {"xmm0", RegXMM, 0, 0}, +- {"xmm1", RegXMM, 0, 1}, +- {"xmm2", RegXMM, 0, 2}, +- {"xmm3", RegXMM, 0, 3}, +- {"xmm4", RegXMM, 0, 4}, +- {"xmm5", RegXMM, 0, 5}, +- {"xmm6", RegXMM, 0, 6}, +- {"xmm7", RegXMM, 0, 7}, +- {"xmm8", RegXMM, RegRex, 0}, +- {"xmm9", RegXMM, RegRex, 1}, +- {"xmm10", RegXMM, RegRex, 2}, +- {"xmm11", RegXMM, RegRex, 3}, +- {"xmm12", RegXMM, RegRex, 4}, +- {"xmm13", RegXMM, RegRex, 5}, +- {"xmm14", RegXMM, RegRex, 6}, +- {"xmm15", RegXMM, RegRex, 7}, +- /* no type will make this register rejected for all purposes except +- for addressing. This saves creating one extra type for RIP. */ +- {"rip", BaseIndex, 0, 0} +-}; +- +-static const reg_entry i386_float_regtab[] = { +- {"st(0)", FloatReg|FloatAcc, 0, 0}, +- {"st(1)", FloatReg, 0, 1}, +- {"st(2)", FloatReg, 0, 2}, +- {"st(3)", FloatReg, 0, 3}, +- {"st(4)", FloatReg, 0, 4}, +- {"st(5)", FloatReg, 0, 5}, +- {"st(6)", FloatReg, 0, 6}, +- {"st(7)", FloatReg, 0, 7} +-}; +- +-#define MAX_REG_NAME_SIZE 8 /* for parsing register names from input */ +- +-/* segment stuff */ +-static const seg_entry cs = { "cs", 0x2e }; +-static const seg_entry ds = { "ds", 0x3e }; +-static const seg_entry ss = { "ss", 0x36 }; +-static const seg_entry es = { "es", 0x26 }; +-static const seg_entry fs = { "fs", 0x64 }; +-static const seg_entry gs = { "gs", 0x65 }; + +-/* end of opcode/i386.h */ ++#define TWO_BYTE_OPCODE_ESCAPE 0x0f ++#define NOP_OPCODE (char) 0x90 ++ ++/* register numbers */ ++#define EBP_REG_NUM 5 ++#define ESP_REG_NUM 4 ++ ++/* modrm_byte.regmem for twobyte escape */ ++#define ESCAPE_TO_TWO_BYTE_ADDRESSING ESP_REG_NUM ++/* index_base_byte.index for no index register addressing */ ++#define NO_INDEX_REGISTER ESP_REG_NUM ++/* index_base_byte.base for no base register addressing */ ++#define NO_BASE_REGISTER EBP_REG_NUM ++#define NO_BASE_REGISTER_16 6 ++ ++/* modrm.mode = REGMEM_FIELD_HAS_REG when a register is in there */ ++#define REGMEM_FIELD_HAS_REG 0x3/* always = 0x3 */ ++#define REGMEM_FIELD_HAS_MEM (~REGMEM_FIELD_HAS_REG) ++ ++/* x86-64 extension prefix. */ ++#define REX_OPCODE 0x40 ++ ++/* Indicates 64 bit operand size. */ ++#define REX_W 8 ++/* High extension to reg field of modrm byte. */ ++#define REX_R 4 ++/* High extension to SIB index field. */ ++#define REX_X 2 ++/* High extension to base field of modrm or SIB, or reg field of opcode. */ ++#define REX_B 1 ++ ++/* max operands per insn */ ++#define MAX_OPERANDS 4 ++ ++/* max immediates per insn (lcall, ljmp, insertq, extrq) */ ++#define MAX_IMMEDIATE_OPERANDS 2 ++ ++/* max memory refs per insn (string ops) */ ++#define MAX_MEMORY_OPERANDS 2 ++ ++/* max size of insn mnemonics. */ ++#define MAX_MNEM_SIZE 16 ++ ++/* max size of register name in insn mnemonics. */ ++#define MAX_REG_NAME_SIZE 8 --- crash-4.0-8.12/extensions/snap.c 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/extensions/snap.c 2009-09-04 21:31:44.000000000 -0400 @@ -687,6 +687,15 @@ } } + /* + * Pre-2.6.13 x86_64 /proc/iomem was restricted to 4GB, + * so just accept it. + */ + if ((paddr >= 0x100000000ULL) && + machine_type("X86_64") && + (THIS_KERNEL_VERSION < LINUX(2,6,13))) + ok++; + if (!ok) { if (CRASHDEBUG(1)) console("reject: %llx\n", (ulonglong)paddr); --- crash-4.0-8.12/extensions/snap.mk 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/extensions/snap.mk 2009-09-03 14:06:52.000000000 -0400 @@ -1,23 +1,28 @@ ifeq ($(shell arch), i686) TARGET=X86 TARGET_CFLAGS=-D_FILE_OFFSET_BITS=64 -else ifeq ($(shell arch), ppc64) +endif +ifeq ($(shell arch), ppc64) TARGET=PPC64 TARGET_CFLAGS=-m64 -else ifeq ($(shell arch), ia64) +endif +ifeq ($(shell arch), ia64) TARGET=IA64 TARGET_CFLAGS= -else ifeq ($(shell arch), x86_64) +endif +ifeq ($(shell arch), x86_64) TARGET=X86_64 TARGET_CFLAGS= endif +ifeq ($(shell /bin/ls /usr/include/crash/defs.h 2>/dev/null), /usr/include/crash/defs.h) + INCDIR=/usr/include/crash +endif +ifeq ($(shell /bin/ls ../defs.h 2> /dev/null), ../defs.h) + INCDIR=.. +endif ifeq ($(shell /bin/ls ./defs.h 2> /dev/null), ./defs.h) INCDIR=. -else ifeq ($(shell /bin/ls ../defs.h 2> /dev/null), ../defs.h) - INCDIR=.. -else ifeq ($(shell /bin/ls /usr/include/crash/defs.h 2>/dev/null), /usr/include/crash/defs.h) - INCDIR=/usr/include/crash endif all: snap.so --- crash-4.0-8.12/extensions/sial.mk 2009-09-01 12:01:57.000000000 -0400 +++ crash-4.0.9/extensions/sial.mk 2009-09-08 16:06:53.000000000 -0400 @@ -5,7 +5,11 @@ TARGET_FLAGS = -D$(TARGET) endif -all: sial.so +all: + @if [ -f /usr/bin/flex ] && [ -f /usr/bin/bison ]; then \ + make -f sial.mk sial.so; \ + else \ + echo "sial.so: build failed: requires /usr/bin/flex and /usr/bin/bison"; fi lib-sial: cd libsial && make