Commit bc51c5c989c12b3936b78c5772a3308629a7484c

Authored by bellard
1 parent 50691463

initial x86-64 host support (Gwenole Beauchesne)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@670 c046a42c-6fe2-441c-8c8c-71466251a162
Changelog
... ... @@ -18,6 +18,7 @@ version 0.5.3:
18 18 - generic removable device support
19 19 - support of CD-ROM change
20 20 - multiple network interface support
  21 + - initial x86-64 host support (Gwenole Beauchesne)
21 22  
22 23 version 0.5.2:
23 24  
... ...
Makefile.target
... ... @@ -80,6 +80,11 @@ LDFLAGS+=-Wl,-shared
80 80 endif
81 81 endif
82 82  
  83 +ifeq ($(ARCH),amd64)
  84 +OP_CFLAGS=$(CFLAGS) -falign-functions=0
  85 +LDFLAGS+=-Wl,-T,$(SRC_PATH)/amd64.ld
  86 +endif
  87 +
83 88 ifeq ($(ARCH),ppc)
84 89 OP_CFLAGS=$(CFLAGS)
85 90 LDFLAGS+=-Wl,-T,$(SRC_PATH)/ppc.ld
... ... @@ -174,6 +179,12 @@ endif
174 179 # NOTE: the disassembler code is only needed for debugging
175 180 LIBOBJS+=disas.o
176 181 ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
  182 +USE_I386_DIS=y
  183 +endif
  184 +ifeq ($(findstring amd64, $(TARGET_ARCH) $(ARCH)),amd64)
  185 +USE_I386_DIS=y
  186 +endif
  187 +ifdef USE_I386_DIS
177 188 LIBOBJS+=i386-dis.o
178 189 endif
179 190 ifeq ($(findstring alpha, $(TARGET_ARCH) $(ARCH)),alpha)
... ...
amd64.ld 0 → 100644
  1 +/* Default linker script, for normal executables */
  2 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
  3 +OUTPUT_ARCH(i386:x86-64)
  4 +ENTRY(_start)
  5 +SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
  6 +SECTIONS
  7 +{
  8 + /* Read-only sections, merged into text segment: */
  9 + . = 0x60000000 + SIZEOF_HEADERS;
  10 + .interp : { *(.interp) }
  11 + .hash : { *(.hash) }
  12 + .dynsym : { *(.dynsym) }
  13 + .dynstr : { *(.dynstr) }
  14 + .gnu.version : { *(.gnu.version) }
  15 + .gnu.version_d : { *(.gnu.version_d) }
  16 + .gnu.version_r : { *(.gnu.version_r) }
  17 + .rel.init : { *(.rel.init) }
  18 + .rela.init : { *(.rela.init) }
  19 + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
  20 + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
  21 + .rel.fini : { *(.rel.fini) }
  22 + .rela.fini : { *(.rela.fini) }
  23 + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
  24 + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
  25 + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
  26 + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
  27 + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
  28 + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
  29 + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
  30 + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
  31 + .rel.ctors : { *(.rel.ctors) }
  32 + .rela.ctors : { *(.rela.ctors) }
  33 + .rel.dtors : { *(.rel.dtors) }
  34 + .rela.dtors : { *(.rela.dtors) }
  35 + .rel.got : { *(.rel.got) }
  36 + .rela.got : { *(.rela.got) }
  37 + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
  38 + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
  39 + .rel.plt : { *(.rel.plt) }
  40 + .rela.plt : { *(.rela.plt) }
  41 + .init :
  42 + {
  43 + KEEP (*(.init))
  44 + } =0x90909090
  45 + .plt : { *(.plt) }
  46 + .text :
  47 + {
  48 + *(.text .stub .text.* .gnu.linkonce.t.*)
  49 + /* .gnu.warning sections are handled specially by elf32.em. */
  50 + *(.gnu.warning)
  51 + } =0x90909090
  52 + .fini :
  53 + {
  54 + KEEP (*(.fini))
  55 + } =0x90909090
  56 + PROVIDE (__etext = .);
  57 + PROVIDE (_etext = .);
  58 + PROVIDE (etext = .);
  59 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  60 + .rodata1 : { *(.rodata1) }
  61 + .eh_frame_hdr : { *(.eh_frame_hdr) }
  62 + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  63 + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
  64 + /* Adjust the address for the data segment. We want to adjust up to
  65 + the same address within the page on the next page up. */
  66 + . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
  67 + /* Ensure the __preinit_array_start label is properly aligned. We
  68 + could instead move the label definition inside the section, but
  69 + the linker would then create the section even if it turns out to
  70 + be empty, which isn't pretty. */
  71 + . = ALIGN(64 / 8);
  72 + PROVIDE (__preinit_array_start = .);
  73 + .preinit_array : { *(.preinit_array) }
  74 + PROVIDE (__preinit_array_end = .);
  75 + PROVIDE (__init_array_start = .);
  76 + .init_array : { *(.init_array) }
  77 + PROVIDE (__init_array_end = .);
  78 + PROVIDE (__fini_array_start = .);
  79 + .fini_array : { *(.fini_array) }
  80 + PROVIDE (__fini_array_end = .);
  81 + .data :
  82 + {
  83 + *(.data .data.* .gnu.linkonce.d.*)
  84 + SORT(CONSTRUCTORS)
  85 + }
  86 + .data1 : { *(.data1) }
  87 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  88 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  89 + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  90 + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
  91 + .dynamic : { *(.dynamic) }
  92 + .ctors :
  93 + {
  94 + /* gcc uses crtbegin.o to find the start of
  95 + the constructors, so we make sure it is
  96 + first. Because this is a wildcard, it
  97 + doesn't matter if the user does not
  98 + actually link against crtbegin.o; the
  99 + linker won't look for a file to match a
  100 + wildcard. The wildcard also means that it
  101 + doesn't matter which directory crtbegin.o
  102 + is in. */
  103 + KEEP (*crtbegin.o(.ctors))
  104 + /* We don't want to include the .ctor section from
  105 + from the crtend.o file until after the sorted ctors.
  106 + The .ctor section from the crtend file contains the
  107 + end of ctors marker and it must be last */
  108 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
  109 + KEEP (*(SORT(.ctors.*)))
  110 + KEEP (*(.ctors))
  111 + }
  112 + .dtors :
  113 + {
  114 + KEEP (*crtbegin.o(.dtors))
  115 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
  116 + KEEP (*(SORT(.dtors.*)))
  117 + KEEP (*(.dtors))
  118 + }
  119 + .jcr : { KEEP (*(.jcr)) }
  120 + .got : { *(.got.plt) *(.got) }
  121 + _edata = .;
  122 + PROVIDE (edata = .);
  123 + __bss_start = .;
  124 + .bss :
  125 + {
  126 + *(.dynbss)
  127 + *(.bss .bss.* .gnu.linkonce.b.*)
  128 + *(COMMON)
  129 + /* Align here to ensure that the .bss section occupies space up to
  130 + _end. Align after .bss to ensure correct alignment even if the
  131 + .bss section disappears because there are no input sections. */
  132 + . = ALIGN(64 / 8);
  133 + }
  134 + . = ALIGN(64 / 8);
  135 + _end = .;
  136 + PROVIDE (end = .);
  137 + . = DATA_SEGMENT_END (.);
  138 + /* Stabs debugging sections. */
  139 + .stab 0 : { *(.stab) }
  140 + .stabstr 0 : { *(.stabstr) }
  141 + .stab.excl 0 : { *(.stab.excl) }
  142 + .stab.exclstr 0 : { *(.stab.exclstr) }
  143 + .stab.index 0 : { *(.stab.index) }
  144 + .stab.indexstr 0 : { *(.stab.indexstr) }
  145 + .comment 0 : { *(.comment) }
  146 + /* DWARF debug sections.
  147 + Symbols in the DWARF debugging sections are relative to the beginning
  148 + of the section so we begin them at 0. */
  149 + /* DWARF 1 */
  150 + .debug 0 : { *(.debug) }
  151 + .line 0 : { *(.line) }
  152 + /* GNU DWARF 1 extensions */
  153 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
  154 + .debug_sfnames 0 : { *(.debug_sfnames) }
  155 + /* DWARF 1.1 and DWARF 2 */
  156 + .debug_aranges 0 : { *(.debug_aranges) }
  157 + .debug_pubnames 0 : { *(.debug_pubnames) }
  158 + /* DWARF 2 */
  159 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
  160 + .debug_abbrev 0 : { *(.debug_abbrev) }
  161 + .debug_line 0 : { *(.debug_line) }
  162 + .debug_frame 0 : { *(.debug_frame) }
  163 + .debug_str 0 : { *(.debug_str) }
  164 + .debug_loc 0 : { *(.debug_loc) }
  165 + .debug_macinfo 0 : { *(.debug_macinfo) }
  166 + /* SGI/MIPS DWARF 2 extensions */
  167 + .debug_weaknames 0 : { *(.debug_weaknames) }
  168 + .debug_funcnames 0 : { *(.debug_funcnames) }
  169 + .debug_typenames 0 : { *(.debug_typenames) }
  170 + .debug_varnames 0 : { *(.debug_varnames) }
  171 +}
  172 +/* Default linker script, for normal executables */
  173 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
  174 +OUTPUT_ARCH(i386:x86-64)
  175 +ENTRY(_start)
  176 +SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib64");
  177 +SECTIONS
  178 +{
  179 + /* Read-only sections, merged into text segment: */
  180 + . = 0x60000000 + SIZEOF_HEADERS;
  181 + .interp : { *(.interp) }
  182 + .hash : { *(.hash) }
  183 + .dynsym : { *(.dynsym) }
  184 + .dynstr : { *(.dynstr) }
  185 + .gnu.version : { *(.gnu.version) }
  186 + .gnu.version_d : { *(.gnu.version_d) }
  187 + .gnu.version_r : { *(.gnu.version_r) }
  188 + .rel.init : { *(.rel.init) }
  189 + .rela.init : { *(.rela.init) }
  190 + .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) }
  191 + .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) }
  192 + .rel.fini : { *(.rel.fini) }
  193 + .rela.fini : { *(.rela.fini) }
  194 + .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) }
  195 + .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) }
  196 + .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) }
  197 + .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) }
  198 + .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) }
  199 + .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) }
  200 + .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) }
  201 + .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) }
  202 + .rel.ctors : { *(.rel.ctors) }
  203 + .rela.ctors : { *(.rela.ctors) }
  204 + .rel.dtors : { *(.rel.dtors) }
  205 + .rela.dtors : { *(.rela.dtors) }
  206 + .rel.got : { *(.rel.got) }
  207 + .rela.got : { *(.rela.got) }
  208 + .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
  209 + .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
  210 + .rel.plt : { *(.rel.plt) }
  211 + .rela.plt : { *(.rela.plt) }
  212 + .init :
  213 + {
  214 + KEEP (*(.init))
  215 + } =0x90909090
  216 + .plt : { *(.plt) }
  217 + .text :
  218 + {
  219 + *(.text .stub .text.* .gnu.linkonce.t.*)
  220 + /* .gnu.warning sections are handled specially by elf32.em. */
  221 + *(.gnu.warning)
  222 + } =0x90909090
  223 + .fini :
  224 + {
  225 + KEEP (*(.fini))
  226 + } =0x90909090
  227 + PROVIDE (__etext = .);
  228 + PROVIDE (_etext = .);
  229 + PROVIDE (etext = .);
  230 + .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  231 + .rodata1 : { *(.rodata1) }
  232 + .eh_frame_hdr : { *(.eh_frame_hdr) }
  233 + .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  234 + .gcc_except_table : ONLY_IF_RO { *(.gcc_except_table) }
  235 + /* Adjust the address for the data segment. We want to adjust up to
  236 + the same address within the page on the next page up. */
  237 + . = ALIGN (0x100000) - ((0x100000 - .) & (0x100000 - 1)); . = DATA_SEGMENT_ALIGN (0x100000, 0x1000);
  238 + /* Ensure the __preinit_array_start label is properly aligned. We
  239 + could instead move the label definition inside the section, but
  240 + the linker would then create the section even if it turns out to
  241 + be empty, which isn't pretty. */
  242 + . = ALIGN(64 / 8);
  243 + PROVIDE (__preinit_array_start = .);
  244 + .preinit_array : { *(.preinit_array) }
  245 + PROVIDE (__preinit_array_end = .);
  246 + PROVIDE (__init_array_start = .);
  247 + .init_array : { *(.init_array) }
  248 + PROVIDE (__init_array_end = .);
  249 + PROVIDE (__fini_array_start = .);
  250 + .fini_array : { *(.fini_array) }
  251 + PROVIDE (__fini_array_end = .);
  252 + .data :
  253 + {
  254 + *(.data .data.* .gnu.linkonce.d.*)
  255 + SORT(CONSTRUCTORS)
  256 + }
  257 + .data1 : { *(.data1) }
  258 + .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  259 + .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  260 + .eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  261 + .gcc_except_table : ONLY_IF_RW { *(.gcc_except_table) }
  262 + .dynamic : { *(.dynamic) }
  263 + .ctors :
  264 + {
  265 + /* gcc uses crtbegin.o to find the start of
  266 + the constructors, so we make sure it is
  267 + first. Because this is a wildcard, it
  268 + doesn't matter if the user does not
  269 + actually link against crtbegin.o; the
  270 + linker won't look for a file to match a
  271 + wildcard. The wildcard also means that it
  272 + doesn't matter which directory crtbegin.o
  273 + is in. */
  274 + KEEP (*crtbegin.o(.ctors))
  275 + /* We don't want to include the .ctor section from
  276 + from the crtend.o file until after the sorted ctors.
  277 + The .ctor section from the crtend file contains the
  278 + end of ctors marker and it must be last */
  279 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors))
  280 + KEEP (*(SORT(.ctors.*)))
  281 + KEEP (*(.ctors))
  282 + }
  283 + .dtors :
  284 + {
  285 + KEEP (*crtbegin.o(.dtors))
  286 + KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors))
  287 + KEEP (*(SORT(.dtors.*)))
  288 + KEEP (*(.dtors))
  289 + }
  290 + .jcr : { KEEP (*(.jcr)) }
  291 + .got : { *(.got.plt) *(.got) }
  292 + _edata = .;
  293 + PROVIDE (edata = .);
  294 + __bss_start = .;
  295 + .bss :
  296 + {
  297 + *(.dynbss)
  298 + *(.bss .bss.* .gnu.linkonce.b.*)
  299 + *(COMMON)
  300 + /* Align here to ensure that the .bss section occupies space up to
  301 + _end. Align after .bss to ensure correct alignment even if the
  302 + .bss section disappears because there are no input sections. */
  303 + . = ALIGN(64 / 8);
  304 + }
  305 + . = ALIGN(64 / 8);
  306 + _end = .;
  307 + PROVIDE (end = .);
  308 + . = DATA_SEGMENT_END (.);
  309 + /* Stabs debugging sections. */
  310 + .stab 0 : { *(.stab) }
  311 + .stabstr 0 : { *(.stabstr) }
  312 + .stab.excl 0 : { *(.stab.excl) }
  313 + .stab.exclstr 0 : { *(.stab.exclstr) }
  314 + .stab.index 0 : { *(.stab.index) }
  315 + .stab.indexstr 0 : { *(.stab.indexstr) }
  316 + .comment 0 : { *(.comment) }
  317 + /* DWARF debug sections.
  318 + Symbols in the DWARF debugging sections are relative to the beginning
  319 + of the section so we begin them at 0. */
  320 + /* DWARF 1 */
  321 + .debug 0 : { *(.debug) }
  322 + .line 0 : { *(.line) }
  323 + /* GNU DWARF 1 extensions */
  324 + .debug_srcinfo 0 : { *(.debug_srcinfo) }
  325 + .debug_sfnames 0 : { *(.debug_sfnames) }
  326 + /* DWARF 1.1 and DWARF 2 */
  327 + .debug_aranges 0 : { *(.debug_aranges) }
  328 + .debug_pubnames 0 : { *(.debug_pubnames) }
  329 + /* DWARF 2 */
  330 + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
  331 + .debug_abbrev 0 : { *(.debug_abbrev) }
  332 + .debug_line 0 : { *(.debug_line) }
  333 + .debug_frame 0 : { *(.debug_frame) }
  334 + .debug_str 0 : { *(.debug_str) }
  335 + .debug_loc 0 : { *(.debug_loc) }
  336 + .debug_macinfo 0 : { *(.debug_macinfo) }
  337 + /* SGI/MIPS DWARF 2 extensions */
  338 + .debug_weaknames 0 : { *(.debug_weaknames) }
  339 + .debug_funcnames 0 : { *(.debug_funcnames) }
  340 + .debug_typenames 0 : { *(.debug_typenames) }
  341 + .debug_varnames 0 : { *(.debug_varnames) }
  342 +}
... ...
... ... @@ -43,7 +43,7 @@
43 43  
44 44 #endif /* !HAVE_BYTESWAP_H */
45 45  
46   -#if defined(__alpha__) || defined (__ia64__)
  46 +#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
47 47 #define HOST_LONG_BITS 64
48 48 #else
49 49 #define HOST_LONG_BITS 32
... ...
configure
... ... @@ -59,6 +59,9 @@ case "$cpu" in
59 59 m68k)
60 60 cpu="m68k"
61 61 ;;
  62 + x86_64|amd64)
  63 + cpu="amd64"
  64 + ;;
62 65 *)
63 66 cpu="unknown"
64 67 ;;
... ... @@ -253,6 +256,9 @@ echo "LDFLAGS=$LDFLAGS" >> $config_mak
253 256 if test "$cpu" = "i386" ; then
254 257 echo "ARCH=i386" >> $config_mak
255 258 echo "#define HOST_I386 1" >> $config_h
  259 +elif test "$cpu" = "amd64" ; then
  260 + echo "ARCH=amd64" >> $config_mak
  261 + echo "#define HOST_AMD64 1" >> $config_h
256 262 elif test "$cpu" = "armv4l" ; then
257 263 echo "ARCH=arm" >> $config_mak
258 264 echo "#define HOST_ARM 1" >> $config_h
... ...
cpu-exec.c
... ... @@ -785,6 +785,21 @@ int cpu_signal_handler(int host_signum, struct siginfo *info,
785 785 &uc->uc_sigmask, puc);
786 786 }
787 787  
  788 +#elif defined(__x86_64__)
  789 +
  790 +int cpu_signal_handler(int host_signum, struct siginfo *info,
  791 + void *puc)
  792 +{
  793 + struct ucontext *uc = puc;
  794 + unsigned long pc;
  795 +
  796 + pc = uc->uc_mcontext.gregs[REG_RIP];
  797 + return handle_cpu_signal(pc, (unsigned long)info->si_addr,
  798 + uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ?
  799 + (uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0,
  800 + &uc->uc_sigmask, puc);
  801 +}
  802 +
788 803 #elif defined(__powerpc)
789 804  
790 805 int cpu_signal_handler(int host_signum, struct siginfo *info,
... ...
dis-asm.h
... ... @@ -16,7 +16,9 @@
16 16 #define PARAMS(x) x
17 17 typedef void *PTR;
18 18 typedef uint64_t bfd_vma;
  19 +typedef int64_t bfd_signed_vma;
19 20 typedef uint8_t bfd_byte;
  21 +#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x)
20 22  
21 23 enum bfd_flavour {
22 24 bfd_target_unknown_flavour,
... ... @@ -105,6 +107,9 @@ enum bfd_architecture
105 107 bfd_arch_i386, /* Intel 386 */
106 108 #define bfd_mach_i386_i386 0
107 109 #define bfd_mach_i386_i8086 1
  110 +#define bfd_mach_i386_i386_intel_syntax 2
  111 +#define bfd_mach_x86_64 3
  112 +#define bfd_mach_x86_64_intel_syntax 4
108 113 bfd_arch_we32k, /* AT&T WE32xxx */
109 114 bfd_arch_tahoe, /* CCI/Harris Tahoe */
110 115 bfd_arch_i860, /* Intel 860 */
... ...
... ... @@ -140,9 +140,12 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags)
140 140 #else
141 141 disasm_info.endian = BFD_ENDIAN_LITTLE;
142 142 #endif
143   -#ifdef __i386__
  143 +#if defined(__i386__)
144 144 disasm_info.mach = bfd_mach_i386_i386;
145 145 print_insn = print_insn_i386;
  146 +#elif defined(__x86_64__)
  147 + disasm_info.mach = bfd_mach_x86_64;
  148 + print_insn = print_insn_i386;
146 149 #elif defined(__powerpc__)
147 150 print_insn = print_insn_ppc;
148 151 #elif defined(__alpha__)
... ...
dyngen-exec.h
... ... @@ -68,6 +68,14 @@ extern int printf(const char *, ...);
68 68 #define AREG2 "esi"
69 69 #define AREG3 "edi"
70 70 #endif
  71 +#ifdef __x86_64__
  72 +#define AREG0 "rbp"
  73 +#define AREG1 "rbx"
  74 +#define AREG2 "r12"
  75 +#define AREG3 "r13"
  76 +#define AREG4 "r14"
  77 +#define AREG5 "r15"
  78 +#endif
71 79 #ifdef __powerpc__
72 80 #define AREG0 "r27"
73 81 #define AREG1 "r24"
... ... @@ -188,6 +196,9 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
188 196 #ifdef __i386__
189 197 #define EXIT_TB() asm volatile ("ret")
190 198 #endif
  199 +#ifdef __x86_64__
  200 +#define EXIT_TB() asm volatile ("ret")
  201 +#endif
191 202 #ifdef __powerpc__
192 203 #define EXIT_TB() asm volatile ("blr")
193 204 #endif
... ...
dyngen.c
... ... @@ -37,6 +37,13 @@
37 37 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
38 38 #undef ELF_USES_RELOCA
39 39  
  40 +#elif defined(HOST_AMD64)
  41 +
  42 +#define ELF_CLASS ELFCLASS64
  43 +#define ELF_ARCH EM_X86_64
  44 +#define elf_check_arch(x) ((x) == EM_X86_64)
  45 +#define ELF_USES_RELOCA
  46 +
40 47 #elif defined(HOST_PPC)
41 48  
42 49 #define ELF_CLASS ELFCLASS32
... ... @@ -446,6 +453,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
446 453 start_offset = offset;
447 454 switch(ELF_ARCH) {
448 455 case EM_386:
  456 + case EM_X86_64:
449 457 {
450 458 int len;
451 459 len = p_end - p_start;
... ... @@ -766,6 +774,41 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
766 774 }
767 775 }
768 776 }
  777 +#elif defined(HOST_AMD64)
  778 + {
  779 + char name[256];
  780 + int type;
  781 + int addend;
  782 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  783 + if (rel->r_offset >= start_offset &&
  784 + rel->r_offset < start_offset + copy_size) {
  785 + sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
  786 + if (strstart(sym_name, "__op_param", &p)) {
  787 + snprintf(name, sizeof(name), "param%s", p);
  788 + } else {
  789 + snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
  790 + }
  791 + type = ELF32_R_TYPE(rel->r_info);
  792 + addend = rel->r_addend;
  793 + switch(type) {
  794 + case R_X86_64_32:
  795 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (uint32_t)%s + %d;\n",
  796 + rel->r_offset - start_offset, name, addend);
  797 + break;
  798 + case R_X86_64_32S:
  799 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = (int32_t)%s + %d;\n",
  800 + rel->r_offset - start_offset, name, addend);
  801 + break;
  802 + case R_X86_64_PC32:
  803 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %d) = %s - (long)(gen_code_ptr + %d) + %d;\n",
  804 + rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
  805 + break;
  806 + default:
  807 + error("unsupported AMD64 relocation (%d)", type);
  808 + }
  809 + }
  810 + }
  811 + }
769 812 #elif defined(HOST_PPC)
770 813 {
771 814 char name[256];
... ...
dyngen.h
... ... @@ -27,6 +27,12 @@ static inline void flush_icache_range(unsigned long start, unsigned long stop)
27 27 }
28 28 #endif
29 29  
  30 +#ifdef __x86_64__
  31 +static inline void flush_icache_range(unsigned long start, unsigned long stop)
  32 +{
  33 +}
  34 +#endif
  35 +
30 36 #ifdef __s390__
31 37 static inline void flush_icache_range(unsigned long start, unsigned long stop)
32 38 {
... ...
exec-all.h
... ... @@ -400,6 +400,20 @@ static inline int testandset (int *p)
400 400 }
401 401 #endif
402 402  
  403 +#ifdef __x86_64__
  404 +static inline int testandset (int *p)
  405 +{
  406 + char ret;
  407 + int readval;
  408 +
  409 + __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
  410 + : "=q" (ret), "=m" (*p), "=a" (readval)
  411 + : "r" (1), "m" (*p), "a" (0)
  412 + : "memory");
  413 + return ret;
  414 +}
  415 +#endif
  416 +
403 417 #ifdef __s390__
404 418 static inline int testandset (int *p)
405 419 {
... ...
i386-dis.c
1 1 /* Print i386 instructions for GDB, the GNU debugger.
2   - Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
  2 + Copyright 1988, 1989, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
  3 + 2001
3 4 Free Software Foundation, Inc.
4 5  
5 6 This file is part of GDB.
... ... @@ -22,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22 23 * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
23 24 * July 1988
24 25 * modified by John Hassey (hassey@dg-rtp.dg.com)
  26 + * x86-64 support added by Jan Hubicka (jh@suse.cz)
25 27 */
26 28  
27 29 /*
... ... @@ -29,33 +31,132 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 31 * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
30 32 * Programmers Manual. Usually, there is a capital letter, followed
31 33 * by a small letter. The capital letter tell the addressing mode,
32   - * and the small letter tells about the operand size. Refer to
  34 + * and the small letter tells about the operand size. Refer to
33 35 * the Intel manual for details.
34 36 */
35 37  
36 38 #include <stdlib.h>
37   -#include <setjmp.h>
38   -
39 39 #include "dis-asm.h"
40 40  
41 41 #define MAXLEN 20
42 42  
  43 +#include <setjmp.h>
  44 +
  45 +#ifndef UNIXWARE_COMPAT
  46 +/* Set non-zero for broken, compatible instructions. Set to zero for
  47 + non-broken opcodes. */
  48 +#define UNIXWARE_COMPAT 1
  49 +#endif
  50 +
43 51 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
  52 +static void ckprefix PARAMS ((void));
  53 +static const char *prefix_name PARAMS ((int, int));
  54 +static int print_insn PARAMS ((bfd_vma, disassemble_info *));
  55 +static void dofloat PARAMS ((int));
  56 +static void OP_ST PARAMS ((int, int));
  57 +static void OP_STi PARAMS ((int, int));
  58 +static int putop PARAMS ((const char *, int));
  59 +static void oappend PARAMS ((const char *));
  60 +static void append_seg PARAMS ((void));
  61 +static void OP_indirE PARAMS ((int, int));
  62 +static void print_operand_value PARAMS ((char *, int, bfd_vma));
  63 +static void OP_E PARAMS ((int, int));
  64 +static void OP_G PARAMS ((int, int));
  65 +static bfd_vma get64 PARAMS ((void));
  66 +static bfd_signed_vma get32 PARAMS ((void));
  67 +static bfd_signed_vma get32s PARAMS ((void));
  68 +static int get16 PARAMS ((void));
  69 +static void set_op PARAMS ((bfd_vma, int));
  70 +static void OP_REG PARAMS ((int, int));
  71 +static void OP_IMREG PARAMS ((int, int));
  72 +static void OP_I PARAMS ((int, int));
  73 +static void OP_I64 PARAMS ((int, int));
  74 +static void OP_sI PARAMS ((int, int));
  75 +static void OP_J PARAMS ((int, int));
  76 +static void OP_SEG PARAMS ((int, int));
  77 +static void OP_DIR PARAMS ((int, int));
  78 +static void OP_OFF PARAMS ((int, int));
  79 +static void OP_OFF64 PARAMS ((int, int));
  80 +static void ptr_reg PARAMS ((int, int));
  81 +static void OP_ESreg PARAMS ((int, int));
  82 +static void OP_DSreg PARAMS ((int, int));
  83 +static void OP_C PARAMS ((int, int));
  84 +static void OP_D PARAMS ((int, int));
  85 +static void OP_T PARAMS ((int, int));
  86 +static void OP_Rd PARAMS ((int, int));
  87 +static void OP_MMX PARAMS ((int, int));
  88 +static void OP_XMM PARAMS ((int, int));
  89 +static void OP_EM PARAMS ((int, int));
  90 +static void OP_EX PARAMS ((int, int));
  91 +static void OP_MS PARAMS ((int, int));
  92 +static void OP_XS PARAMS ((int, int));
  93 +static void OP_3DNowSuffix PARAMS ((int, int));
  94 +static void OP_SIMD_Suffix PARAMS ((int, int));
  95 +static void SIMD_Fixup PARAMS ((int, int));
  96 +static void BadOp PARAMS ((void));
44 97  
45   -struct dis_private
46   -{
  98 +struct dis_private {
47 99 /* Points to first byte not fetched. */
48 100 bfd_byte *max_fetched;
49 101 bfd_byte the_buffer[MAXLEN];
50 102 bfd_vma insn_start;
  103 + int orig_sizeflag;
51 104 jmp_buf bailout;
52 105 };
53 106  
  107 +/* The opcode for the fwait instruction, which we treat as a prefix
  108 + when we can. */
  109 +#define FWAIT_OPCODE (0x9b)
  110 +
  111 +/* Set to 1 for 64bit mode disassembly. */
  112 +static int mode_64bit;
  113 +
  114 +/* Flags for the prefixes for the current instruction. See below. */
  115 +static int prefixes;
  116 +
  117 +/* REX prefix the current instruction. See below. */
  118 +static int rex;
  119 +/* Bits of REX we've already used. */
  120 +static int rex_used;
  121 +#define REX_MODE64 8
  122 +#define REX_EXTX 4
  123 +#define REX_EXTY 2
  124 +#define REX_EXTZ 1
  125 +/* Mark parts used in the REX prefix. When we are testing for
  126 + empty prefix (for 8bit register REX extension), just mask it
  127 + out. Otherwise test for REX bit is excuse for existence of REX
  128 + only in case value is nonzero. */
  129 +#define USED_REX(value) \
  130 + { \
  131 + if (value) \
  132 + rex_used |= (rex & value) ? (value) | 0x40 : 0; \
  133 + else \
  134 + rex_used |= 0x40; \
  135 + }
  136 +
  137 +/* Flags for prefixes which we somehow handled when printing the
  138 + current instruction. */
  139 +static int used_prefixes;
  140 +
  141 +/* Flags stored in PREFIXES. */
  142 +#define PREFIX_REPZ 1
  143 +#define PREFIX_REPNZ 2
  144 +#define PREFIX_LOCK 4
  145 +#define PREFIX_CS 8
  146 +#define PREFIX_SS 0x10
  147 +#define PREFIX_DS 0x20
  148 +#define PREFIX_ES 0x40
  149 +#define PREFIX_FS 0x80
  150 +#define PREFIX_GS 0x100
  151 +#define PREFIX_DATA 0x200
  152 +#define PREFIX_ADDR 0x400
  153 +#define PREFIX_FWAIT 0x800
  154 +
54 155 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
55 156 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
56 157 on error. */
57 158 #define FETCH_DATA(info, addr) \
58   - ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
  159 + ((addr) <= ((struct dis_private *) (info->private_data))->max_fetched \
59 160 ? 1 : fetch_data ((info), (addr)))
60 161  
61 162 static int
... ... @@ -64,7 +165,7 @@ fetch_data (info, addr)
64 165 bfd_byte *addr;
65 166 {
66 167 int status;
67   - struct dis_private *priv = (struct dis_private *)info->private_data;
  168 + struct dis_private *priv = (struct dis_private *) info->private_data;
68 169 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
69 170  
70 171 status = (*info->read_memory_func) (start,
... ... @@ -73,7 +174,12 @@ fetch_data (info, addr)
73 174 info);
74 175 if (status != 0)
75 176 {
76   - (*info->memory_error_func) (status, start, info);
  177 + /* If we did manage to read at least one byte, then
  178 + print_insn_i386 will do something sensible. Otherwise, print
  179 + an error. We do that here because this is where we know
  180 + STATUS. */
  181 + if (priv->max_fetched == priv->the_buffer)
  182 + (*info->memory_error_func) (status, start, info);
77 183 longjmp (priv->bailout, 1);
78 184 }
79 185 else
... ... @@ -81,61 +187,95 @@ fetch_data (info, addr)
81 187 return 1;
82 188 }
83 189  
  190 +#define XX NULL, 0
  191 +
84 192 #define Eb OP_E, b_mode
85   -#define indirEb OP_indirE, b_mode
86   -#define Gb OP_G, b_mode
87 193 #define Ev OP_E, v_mode
  194 +#define Ed OP_E, d_mode
  195 +#define indirEb OP_indirE, b_mode
88 196 #define indirEv OP_indirE, v_mode
89 197 #define Ew OP_E, w_mode
90 198 #define Ma OP_E, v_mode
91   -#define M OP_E, 0
92   -#define Mp OP_E, 0 /* ? */
  199 +#define M OP_E, 0 /* lea, lgdt, etc. */
  200 +#define Mp OP_E, 0 /* 32 or 48 bit memory operand for LDS, LES etc */
  201 +#define Gb OP_G, b_mode
93 202 #define Gv OP_G, v_mode
  203 +#define Gd OP_G, d_mode
94 204 #define Gw OP_G, w_mode
95   -#define Rw OP_rm, w_mode
96   -#define Rd OP_rm, d_mode
  205 +#define Rd OP_Rd, d_mode
  206 +#define Rm OP_Rd, m_mode
97 207 #define Ib OP_I, b_mode
98 208 #define sIb OP_sI, b_mode /* sign extened byte */
99 209 #define Iv OP_I, v_mode
  210 +#define Iq OP_I, q_mode
  211 +#define Iv64 OP_I64, v_mode
100 212 #define Iw OP_I, w_mode
101 213 #define Jb OP_J, b_mode
102 214 #define Jv OP_J, v_mode
103   -#if 0
104   -#define ONE OP_ONE, 0
105   -#endif
106   -#define Cd OP_C, d_mode
107   -#define Dd OP_D, d_mode
  215 +#define Cm OP_C, m_mode
  216 +#define Dm OP_D, m_mode
108 217 #define Td OP_T, d_mode
109 218  
110   -#define eAX OP_REG, eAX_reg
111   -#define eBX OP_REG, eBX_reg
112   -#define eCX OP_REG, eCX_reg
113   -#define eDX OP_REG, eDX_reg
114   -#define eSP OP_REG, eSP_reg
115   -#define eBP OP_REG, eBP_reg
116   -#define eSI OP_REG, eSI_reg
117   -#define eDI OP_REG, eDI_reg
118   -#define AL OP_REG, al_reg
119   -#define CL OP_REG, cl_reg
120   -#define DL OP_REG, dl_reg
121   -#define BL OP_REG, bl_reg
122   -#define AH OP_REG, ah_reg
123   -#define CH OP_REG, ch_reg
124   -#define DH OP_REG, dh_reg
125   -#define BH OP_REG, bh_reg
126   -#define AX OP_REG, ax_reg
127   -#define DX OP_REG, dx_reg
128   -#define indirDX OP_REG, indir_dx_reg
  219 +#define RMeAX OP_REG, eAX_reg
  220 +#define RMeBX OP_REG, eBX_reg
  221 +#define RMeCX OP_REG, eCX_reg
  222 +#define RMeDX OP_REG, eDX_reg
  223 +#define RMeSP OP_REG, eSP_reg
  224 +#define RMeBP OP_REG, eBP_reg
  225 +#define RMeSI OP_REG, eSI_reg
  226 +#define RMeDI OP_REG, eDI_reg
  227 +#define RMrAX OP_REG, rAX_reg
  228 +#define RMrBX OP_REG, rBX_reg
  229 +#define RMrCX OP_REG, rCX_reg
  230 +#define RMrDX OP_REG, rDX_reg
  231 +#define RMrSP OP_REG, rSP_reg
  232 +#define RMrBP OP_REG, rBP_reg
  233 +#define RMrSI OP_REG, rSI_reg
  234 +#define RMrDI OP_REG, rDI_reg
  235 +#define RMAL OP_REG, al_reg
  236 +#define RMAL OP_REG, al_reg
  237 +#define RMCL OP_REG, cl_reg
  238 +#define RMDL OP_REG, dl_reg
  239 +#define RMBL OP_REG, bl_reg
  240 +#define RMAH OP_REG, ah_reg
  241 +#define RMCH OP_REG, ch_reg
  242 +#define RMDH OP_REG, dh_reg
  243 +#define RMBH OP_REG, bh_reg
  244 +#define RMAX OP_REG, ax_reg
  245 +#define RMDX OP_REG, dx_reg
  246 +
  247 +#define eAX OP_IMREG, eAX_reg
  248 +#define eBX OP_IMREG, eBX_reg
  249 +#define eCX OP_IMREG, eCX_reg
  250 +#define eDX OP_IMREG, eDX_reg
  251 +#define eSP OP_IMREG, eSP_reg
  252 +#define eBP OP_IMREG, eBP_reg
  253 +#define eSI OP_IMREG, eSI_reg
  254 +#define eDI OP_IMREG, eDI_reg
  255 +#define AL OP_IMREG, al_reg
  256 +#define AL OP_IMREG, al_reg
  257 +#define CL OP_IMREG, cl_reg
  258 +#define DL OP_IMREG, dl_reg
  259 +#define BL OP_IMREG, bl_reg
  260 +#define AH OP_IMREG, ah_reg
  261 +#define CH OP_IMREG, ch_reg
  262 +#define DH OP_IMREG, dh_reg
  263 +#define BH OP_IMREG, bh_reg
  264 +#define AX OP_IMREG, ax_reg
  265 +#define DX OP_IMREG, dx_reg
  266 +#define indirDX OP_IMREG, indir_dx_reg
129 267  
130 268 #define Sw OP_SEG, w_mode
131   -#define Ap OP_DIR, lptr
132   -#define Av OP_DIR, v_mode
  269 +#define Ap OP_DIR, 0
133 270 #define Ob OP_OFF, b_mode
  271 +#define Ob64 OP_OFF64, b_mode
134 272 #define Ov OP_OFF, v_mode
135   -#define Xb OP_DSSI, b_mode
136   -#define Xv OP_DSSI, v_mode
137   -#define Yb OP_ESDI, b_mode
138   -#define Yv OP_ESDI, v_mode
  273 +#define Ov64 OP_OFF64, v_mode
  274 +#define Xb OP_DSreg, eSI_reg
  275 +#define Xv OP_DSreg, eSI_reg
  276 +#define Yb OP_ESreg, eDI_reg
  277 +#define Yv OP_ESreg, eDI_reg
  278 +#define DSBX OP_DSreg, eBX_reg
139 279  
140 280 #define es OP_REG, es_reg
141 281 #define ss OP_REG, ss_reg
... ... @@ -145,48 +285,32 @@ fetch_data (info, addr)
145 285 #define gs OP_REG, gs_reg
146 286  
147 287 #define MX OP_MMX, 0
  288 +#define XM OP_XMM, 0
148 289 #define EM OP_EM, v_mode
149   -#define MS OP_MS, b_mode
150   -
151   -typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag));
152   -
153   -static int OP_E PARAMS ((int, int, int));
154   -static int OP_G PARAMS ((int, int, int));
155   -static int OP_I PARAMS ((int, int, int));
156   -static int OP_indirE PARAMS ((int, int, int));
157   -static int OP_sI PARAMS ((int, int, int));
158   -static int OP_REG PARAMS ((int, int, int));
159   -static int OP_J PARAMS ((int, int, int));
160   -static int OP_DIR PARAMS ((int, int, int));
161   -static int OP_OFF PARAMS ((int, int, int));
162   -static int OP_ESDI PARAMS ((int, int, int));
163   -static int OP_DSSI PARAMS ((int, int, int));
164   -static int OP_SEG PARAMS ((int, int, int));
165   -static int OP_C PARAMS ((int, int, int));
166   -static int OP_D PARAMS ((int, int, int));
167   -static int OP_T PARAMS ((int, int, int));
168   -static int OP_rm PARAMS ((int, int, int));
169   -static int OP_ST PARAMS ((int, int, int));
170   -static int OP_STi PARAMS ((int, int, int));
171   -#if 0
172   -static int OP_ONE PARAMS ((int, int, int));
173   -#endif
174   -static int OP_MMX PARAMS ((int, int, int));
175   -static int OP_EM PARAMS ((int, int, int));
176   -static int OP_MS PARAMS ((int, int, int));
177   -
178   -static void append_prefix PARAMS ((void));
179   -static void set_op PARAMS ((int op));
180   -static void putop PARAMS ((char *template, int aflag, int dflag));
181   -static void dofloat PARAMS ((int aflag, int dflag));
182   -static int get16 PARAMS ((void));
183   -static int get32 PARAMS ((void));
184   -static void ckprefix PARAMS ((void));
  290 +#define EX OP_EX, v_mode
  291 +#define MS OP_MS, v_mode
  292 +#define XS OP_XS, v_mode
  293 +#define None OP_E, 0
  294 +#define OPSUF OP_3DNowSuffix, 0
  295 +#define OPSIMD OP_SIMD_Suffix, 0
  296 +
  297 +#define cond_jump_flag NULL, cond_jump_mode
  298 +#define loop_jcxz_flag NULL, loop_jcxz_mode
  299 +
  300 +/* bits in sizeflag */
  301 +#define SUFFIX_ALWAYS 4
  302 +#define AFLAG 2
  303 +#define DFLAG 1
185 304  
186   -#define b_mode 1
187   -#define v_mode 2
188   -#define w_mode 3
189   -#define d_mode 4
  305 +#define b_mode 1 /* byte operand */
  306 +#define v_mode 2 /* operand size depends on prefixes */
  307 +#define w_mode 3 /* word operand */
  308 +#define d_mode 4 /* double word operand */
  309 +#define q_mode 5 /* quad word operand */
  310 +#define x_mode 6
  311 +#define m_mode 7 /* d_mode in 32bit, q_mode in 64bit mode. */
  312 +#define cond_jump_mode 8
  313 +#define loop_jcxz_mode 9
190 314  
191 315 #define es_reg 100
192 316 #define cs_reg 101
... ... @@ -194,16 +318,15 @@ static void ckprefix PARAMS ((void));
194 318 #define ds_reg 103
195 319 #define fs_reg 104
196 320 #define gs_reg 105
197   -#define eAX_reg 107
198   -#define eCX_reg 108
199   -#define eDX_reg 109
200   -#define eBX_reg 110
201   -#define eSP_reg 111
202   -#define eBP_reg 112
203   -#define eSI_reg 113
204   -#define eDI_reg 114
205 321  
206   -#define lptr 115
  322 +#define eAX_reg 108
  323 +#define eCX_reg 109
  324 +#define eDX_reg 110
  325 +#define eBX_reg 111
  326 +#define eSP_reg 112
  327 +#define eBP_reg 113
  328 +#define eSI_reg 114
  329 +#define eDI_reg 115
207 330  
208 331 #define al_reg 116
209 332 #define cl_reg 117
... ... @@ -223,34 +346,82 @@ static void ckprefix PARAMS ((void));
223 346 #define si_reg 130
224 347 #define di_reg 131
225 348  
  349 +#define rAX_reg 132
  350 +#define rCX_reg 133
  351 +#define rDX_reg 134
  352 +#define rBX_reg 135
  353 +#define rSP_reg 136
  354 +#define rBP_reg 137
  355 +#define rSI_reg 138
  356 +#define rDI_reg 139
  357 +
226 358 #define indir_dx_reg 150
227 359  
228   -#define GRP1b NULL, NULL, 0
229   -#define GRP1S NULL, NULL, 1
230   -#define GRP1Ss NULL, NULL, 2
231   -#define GRP2b NULL, NULL, 3
232   -#define GRP2S NULL, NULL, 4
233   -#define GRP2b_one NULL, NULL, 5
234   -#define GRP2S_one NULL, NULL, 6
235   -#define GRP2b_cl NULL, NULL, 7
236   -#define GRP2S_cl NULL, NULL, 8
237   -#define GRP3b NULL, NULL, 9
238   -#define GRP3S NULL, NULL, 10
239   -#define GRP4 NULL, NULL, 11
240   -#define GRP5 NULL, NULL, 12
241   -#define GRP6 NULL, NULL, 13
242   -#define GRP7 NULL, NULL, 14
243   -#define GRP8 NULL, NULL, 15
244   -#define GRP9 NULL, NULL, 16
245   -#define GRP10 NULL, NULL, 17
246   -#define GRP11 NULL, NULL, 18
247   -#define GRP12 NULL, NULL, 19
248   -
249   -#define FLOATCODE 50
250   -#define FLOAT NULL, NULL, FLOATCODE
  360 +#define FLOATCODE 1
  361 +#define USE_GROUPS 2
  362 +#define USE_PREFIX_USER_TABLE 3
  363 +#define X86_64_SPECIAL 4
  364 +
  365 +#define FLOAT NULL, NULL, FLOATCODE, NULL, 0, NULL, 0
  366 +
  367 +#define GRP1b NULL, NULL, USE_GROUPS, NULL, 0, NULL, 0
  368 +#define GRP1S NULL, NULL, USE_GROUPS, NULL, 1, NULL, 0
  369 +#define GRP1Ss NULL, NULL, USE_GROUPS, NULL, 2, NULL, 0
  370 +#define GRP2b NULL, NULL, USE_GROUPS, NULL, 3, NULL, 0
  371 +#define GRP2S NULL, NULL, USE_GROUPS, NULL, 4, NULL, 0
  372 +#define GRP2b_one NULL, NULL, USE_GROUPS, NULL, 5, NULL, 0
  373 +#define GRP2S_one NULL, NULL, USE_GROUPS, NULL, 6, NULL, 0
  374 +#define GRP2b_cl NULL, NULL, USE_GROUPS, NULL, 7, NULL, 0
  375 +#define GRP2S_cl NULL, NULL, USE_GROUPS, NULL, 8, NULL, 0
  376 +#define GRP3b NULL, NULL, USE_GROUPS, NULL, 9, NULL, 0
  377 +#define GRP3S NULL, NULL, USE_GROUPS, NULL, 10, NULL, 0
  378 +#define GRP4 NULL, NULL, USE_GROUPS, NULL, 11, NULL, 0
  379 +#define GRP5 NULL, NULL, USE_GROUPS, NULL, 12, NULL, 0
  380 +#define GRP6 NULL, NULL, USE_GROUPS, NULL, 13, NULL, 0
  381 +#define GRP7 NULL, NULL, USE_GROUPS, NULL, 14, NULL, 0
  382 +#define GRP8 NULL, NULL, USE_GROUPS, NULL, 15, NULL, 0
  383 +#define GRP9 NULL, NULL, USE_GROUPS, NULL, 16, NULL, 0
  384 +#define GRP10 NULL, NULL, USE_GROUPS, NULL, 17, NULL, 0
  385 +#define GRP11 NULL, NULL, USE_GROUPS, NULL, 18, NULL, 0
  386 +#define GRP12 NULL, NULL, USE_GROUPS, NULL, 19, NULL, 0
  387 +#define GRP13 NULL, NULL, USE_GROUPS, NULL, 20, NULL, 0
  388 +#define GRP14 NULL, NULL, USE_GROUPS, NULL, 21, NULL, 0
  389 +#define GRPAMD NULL, NULL, USE_GROUPS, NULL, 22, NULL, 0
  390 +
  391 +#define PREGRP0 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 0, NULL, 0
  392 +#define PREGRP1 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 1, NULL, 0
  393 +#define PREGRP2 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 2, NULL, 0
  394 +#define PREGRP3 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 3, NULL, 0
  395 +#define PREGRP4 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 4, NULL, 0
  396 +#define PREGRP5 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 5, NULL, 0
  397 +#define PREGRP6 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 6, NULL, 0
  398 +#define PREGRP7 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 7, NULL, 0
  399 +#define PREGRP8 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 8, NULL, 0
  400 +#define PREGRP9 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 9, NULL, 0
  401 +#define PREGRP10 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 10, NULL, 0
  402 +#define PREGRP11 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 11, NULL, 0
  403 +#define PREGRP12 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 12, NULL, 0
  404 +#define PREGRP13 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 13, NULL, 0
  405 +#define PREGRP14 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 14, NULL, 0
  406 +#define PREGRP15 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 15, NULL, 0
  407 +#define PREGRP16 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 16, NULL, 0
  408 +#define PREGRP17 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 17, NULL, 0
  409 +#define PREGRP18 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 18, NULL, 0
  410 +#define PREGRP19 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 19, NULL, 0
  411 +#define PREGRP20 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 20, NULL, 0
  412 +#define PREGRP21 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 21, NULL, 0
  413 +#define PREGRP22 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 22, NULL, 0
  414 +#define PREGRP23 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 23, NULL, 0
  415 +#define PREGRP24 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 24, NULL, 0
  416 +#define PREGRP25 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 25, NULL, 0
  417 +#define PREGRP26 NULL, NULL, USE_PREFIX_USER_TABLE, NULL, 26, NULL, 0
  418 +
  419 +#define X86_64_0 NULL, NULL, X86_64_SPECIAL, NULL, 0, NULL, 0
  420 +
  421 +typedef void (*op_rtn) PARAMS ((int bytemode, int sizeflag));
251 422  
252 423 struct dis386 {
253   - char *name;
  424 + const char *name;
254 425 op_rtn op1;
255 426 int bytemode1;
256 427 op_rtn op2;
... ... @@ -259,250 +430,281 @@ struct dis386 {
259 430 int bytemode3;
260 431 };
261 432  
262   -static struct dis386 dis386[] = {
  433 +/* Upper case letters in the instruction names here are macros.
  434 + 'A' => print 'b' if no register operands or suffix_always is true
  435 + 'B' => print 'b' if suffix_always is true
  436 + 'E' => print 'e' if 32-bit form of jcxz
  437 + 'F' => print 'w' or 'l' depending on address size prefix (loop insns)
  438 + 'H' => print ",pt" or ",pn" branch hint
  439 + 'L' => print 'l' if suffix_always is true
  440 + 'N' => print 'n' if instruction has no wait "prefix"
  441 + 'O' => print 'd', or 'o'
  442 + 'P' => print 'w', 'l' or 'q' if instruction has an operand size prefix,
  443 + . or suffix_always is true. print 'q' if rex prefix is present.
  444 + 'Q' => print 'w', 'l' or 'q' if no register operands or suffix_always
  445 + . is true
  446 + 'R' => print 'w', 'l' or 'q' ("wd" or "dq" in intel mode)
  447 + 'S' => print 'w', 'l' or 'q' if suffix_always is true
  448 + 'T' => print 'q' in 64bit mode and behave as 'P' otherwise
  449 + 'U' => print 'q' in 64bit mode and behave as 'Q' otherwise
  450 + 'X' => print 's', 'd' depending on data16 prefix (for XMM)
  451 + 'W' => print 'b' or 'w' ("w" or "de" in intel mode)
  452 + 'Y' => 'q' if instruction has an REX 64bit overwrite prefix
  453 +
  454 + Many of the above letters print nothing in Intel mode. See "putop"
  455 + for the details.
  456 +
  457 + Braces '{' and '}', and vertical bars '|', indicate alternative
  458 + mnemonic strings for AT&T, Intel, X86_64 AT&T, and X86_64 Intel
  459 + modes. In cases where there are only two alternatives, the X86_64
  460 + instruction is reserved, and "(bad)" is printed.
  461 +*/
  462 +
  463 +static const struct dis386 dis386[] = {
263 464 /* 00 */
264   - { "addb", Eb, Gb },
265   - { "addS", Ev, Gv },
266   - { "addb", Gb, Eb },
267   - { "addS", Gv, Ev },
268   - { "addb", AL, Ib },
269   - { "addS", eAX, Iv },
270   - { "pushS", es },
271   - { "popS", es },
  465 + { "addB", Eb, Gb, XX },
  466 + { "addS", Ev, Gv, XX },
  467 + { "addB", Gb, Eb, XX },
  468 + { "addS", Gv, Ev, XX },
  469 + { "addB", AL, Ib, XX },
  470 + { "addS", eAX, Iv, XX },
  471 + { "push{T|}", es, XX, XX },
  472 + { "pop{T|}", es, XX, XX },
272 473 /* 08 */
273   - { "orb", Eb, Gb },
274   - { "orS", Ev, Gv },
275   - { "orb", Gb, Eb },
276   - { "orS", Gv, Ev },
277   - { "orb", AL, Ib },
278   - { "orS", eAX, Iv },
279   - { "pushS", cs },
280   - { "(bad)" }, /* 0x0f extended opcode escape */
  474 + { "orB", Eb, Gb, XX },
  475 + { "orS", Ev, Gv, XX },
  476 + { "orB", Gb, Eb, XX },
  477 + { "orS", Gv, Ev, XX },
  478 + { "orB", AL, Ib, XX },
  479 + { "orS", eAX, Iv, XX },
  480 + { "push{T|}", cs, XX, XX },
  481 + { "(bad)", XX, XX, XX }, /* 0x0f extended opcode escape */
281 482 /* 10 */
282   - { "adcb", Eb, Gb },
283   - { "adcS", Ev, Gv },
284   - { "adcb", Gb, Eb },
285   - { "adcS", Gv, Ev },
286   - { "adcb", AL, Ib },
287   - { "adcS", eAX, Iv },
288   - { "pushS", ss },
289   - { "popS", ss },
  483 + { "adcB", Eb, Gb, XX },
  484 + { "adcS", Ev, Gv, XX },
  485 + { "adcB", Gb, Eb, XX },
  486 + { "adcS", Gv, Ev, XX },
  487 + { "adcB", AL, Ib, XX },
  488 + { "adcS", eAX, Iv, XX },
  489 + { "push{T|}", ss, XX, XX },
  490 + { "popT|}", ss, XX, XX },
290 491 /* 18 */
291   - { "sbbb", Eb, Gb },
292   - { "sbbS", Ev, Gv },
293   - { "sbbb", Gb, Eb },
294   - { "sbbS", Gv, Ev },
295   - { "sbbb", AL, Ib },
296   - { "sbbS", eAX, Iv },
297   - { "pushS", ds },
298   - { "popS", ds },
  492 + { "sbbB", Eb, Gb, XX },
  493 + { "sbbS", Ev, Gv, XX },
  494 + { "sbbB", Gb, Eb, XX },
  495 + { "sbbS", Gv, Ev, XX },
  496 + { "sbbB", AL, Ib, XX },
  497 + { "sbbS", eAX, Iv, XX },
  498 + { "push{T|}", ds, XX, XX },
  499 + { "pop{T|}", ds, XX, XX },
299 500 /* 20 */
300   - { "andb", Eb, Gb },
301   - { "andS", Ev, Gv },
302   - { "andb", Gb, Eb },
303   - { "andS", Gv, Ev },
304   - { "andb", AL, Ib },
305   - { "andS", eAX, Iv },
306   - { "(bad)" }, /* SEG ES prefix */
307   - { "daa" },
  501 + { "andB", Eb, Gb, XX },
  502 + { "andS", Ev, Gv, XX },
  503 + { "andB", Gb, Eb, XX },
  504 + { "andS", Gv, Ev, XX },
  505 + { "andB", AL, Ib, XX },
  506 + { "andS", eAX, Iv, XX },
  507 + { "(bad)", XX, XX, XX }, /* SEG ES prefix */
  508 + { "daa{|}", XX, XX, XX },
308 509 /* 28 */
309   - { "subb", Eb, Gb },
310   - { "subS", Ev, Gv },
311   - { "subb", Gb, Eb },
312   - { "subS", Gv, Ev },
313   - { "subb", AL, Ib },
314   - { "subS", eAX, Iv },
315   - { "(bad)" }, /* SEG CS prefix */
316   - { "das" },
  510 + { "subB", Eb, Gb, XX },
  511 + { "subS", Ev, Gv, XX },
  512 + { "subB", Gb, Eb, XX },
  513 + { "subS", Gv, Ev, XX },
  514 + { "subB", AL, Ib, XX },
  515 + { "subS", eAX, Iv, XX },
  516 + { "(bad)", XX, XX, XX }, /* SEG CS prefix */
  517 + { "das{|}", XX, XX, XX },
317 518 /* 30 */
318   - { "xorb", Eb, Gb },
319   - { "xorS", Ev, Gv },
320   - { "xorb", Gb, Eb },
321   - { "xorS", Gv, Ev },
322   - { "xorb", AL, Ib },
323   - { "xorS", eAX, Iv },
324   - { "(bad)" }, /* SEG SS prefix */
325   - { "aaa" },
  519 + { "xorB", Eb, Gb, XX },
  520 + { "xorS", Ev, Gv, XX },
  521 + { "xorB", Gb, Eb, XX },
  522 + { "xorS", Gv, Ev, XX },
  523 + { "xorB", AL, Ib, XX },
  524 + { "xorS", eAX, Iv, XX },
  525 + { "(bad)", XX, XX, XX }, /* SEG SS prefix */
  526 + { "aaa{|}", XX, XX, XX },
326 527 /* 38 */
327   - { "cmpb", Eb, Gb },
328   - { "cmpS", Ev, Gv },
329   - { "cmpb", Gb, Eb },
330   - { "cmpS", Gv, Ev },
331   - { "cmpb", AL, Ib },
332   - { "cmpS", eAX, Iv },
333   - { "(bad)" }, /* SEG DS prefix */
334   - { "aas" },
  528 + { "cmpB", Eb, Gb, XX },
  529 + { "cmpS", Ev, Gv, XX },
  530 + { "cmpB", Gb, Eb, XX },
  531 + { "cmpS", Gv, Ev, XX },
  532 + { "cmpB", AL, Ib, XX },
  533 + { "cmpS", eAX, Iv, XX },
  534 + { "(bad)", XX, XX, XX }, /* SEG DS prefix */
  535 + { "aas{|}", XX, XX, XX },
335 536 /* 40 */
336   - { "incS", eAX },
337   - { "incS", eCX },
338   - { "incS", eDX },
339   - { "incS", eBX },
340   - { "incS", eSP },
341   - { "incS", eBP },
342   - { "incS", eSI },
343   - { "incS", eDI },
  537 + { "inc{S|}", RMeAX, XX, XX },
  538 + { "inc{S|}", RMeCX, XX, XX },
  539 + { "inc{S|}", RMeDX, XX, XX },
  540 + { "inc{S|}", RMeBX, XX, XX },
  541 + { "inc{S|}", RMeSP, XX, XX },
  542 + { "inc{S|}", RMeBP, XX, XX },
  543 + { "inc{S|}", RMeSI, XX, XX },
  544 + { "inc{S|}", RMeDI, XX, XX },
344 545 /* 48 */
345   - { "decS", eAX },
346   - { "decS", eCX },
347   - { "decS", eDX },
348   - { "decS", eBX },
349   - { "decS", eSP },
350   - { "decS", eBP },
351   - { "decS", eSI },
352   - { "decS", eDI },
  546 + { "dec{S|}", RMeAX, XX, XX },
  547 + { "dec{S|}", RMeCX, XX, XX },
  548 + { "dec{S|}", RMeDX, XX, XX },
  549 + { "dec{S|}", RMeBX, XX, XX },
  550 + { "dec{S|}", RMeSP, XX, XX },
  551 + { "dec{S|}", RMeBP, XX, XX },
  552 + { "dec{S|}", RMeSI, XX, XX },
  553 + { "dec{S|}", RMeDI, XX, XX },
353 554 /* 50 */
354   - { "pushS", eAX },
355   - { "pushS", eCX },
356   - { "pushS", eDX },
357   - { "pushS", eBX },
358   - { "pushS", eSP },
359   - { "pushS", eBP },
360   - { "pushS", eSI },
361   - { "pushS", eDI },
  555 + { "pushS", RMrAX, XX, XX },
  556 + { "pushS", RMrCX, XX, XX },
  557 + { "pushS", RMrDX, XX, XX },
  558 + { "pushS", RMrBX, XX, XX },
  559 + { "pushS", RMrSP, XX, XX },
  560 + { "pushS", RMrBP, XX, XX },
  561 + { "pushS", RMrSI, XX, XX },
  562 + { "pushS", RMrDI, XX, XX },
362 563 /* 58 */
363   - { "popS", eAX },
364   - { "popS", eCX },
365   - { "popS", eDX },
366   - { "popS", eBX },
367   - { "popS", eSP },
368   - { "popS", eBP },
369   - { "popS", eSI },
370   - { "popS", eDI },
  564 + { "popS", RMrAX, XX, XX },
  565 + { "popS", RMrCX, XX, XX },
  566 + { "popS", RMrDX, XX, XX },
  567 + { "popS", RMrBX, XX, XX },
  568 + { "popS", RMrSP, XX, XX },
  569 + { "popS", RMrBP, XX, XX },
  570 + { "popS", RMrSI, XX, XX },
  571 + { "popS", RMrDI, XX, XX },
371 572 /* 60 */
372   - { "pusha" },
373   - { "popa" },
374   - { "boundS", Gv, Ma },
375   - { "arpl", Ew, Gw },
376   - { "(bad)" }, /* seg fs */
377   - { "(bad)" }, /* seg gs */
378   - { "(bad)" }, /* op size prefix */
379   - { "(bad)" }, /* adr size prefix */
  573 + { "pusha{P|}", XX, XX, XX },
  574 + { "popa{P|}", XX, XX, XX },
  575 + { "bound{S|}", Gv, Ma, XX },
  576 + { X86_64_0 },
  577 + { "(bad)", XX, XX, XX }, /* seg fs */
  578 + { "(bad)", XX, XX, XX }, /* seg gs */
  579 + { "(bad)", XX, XX, XX }, /* op size prefix */
  580 + { "(bad)", XX, XX, XX }, /* adr size prefix */
380 581 /* 68 */
381   - { "pushS", Iv }, /* 386 book wrong */
382   - { "imulS", Gv, Ev, Iv },
383   - { "pushS", sIb }, /* push of byte really pushes 2 or 4 bytes */
384   - { "imulS", Gv, Ev, Ib },
385   - { "insb", Yb, indirDX },
386   - { "insS", Yv, indirDX },
387   - { "outsb", indirDX, Xb },
388   - { "outsS", indirDX, Xv },
  582 + { "pushT", Iq, XX, XX },
  583 + { "imulS", Gv, Ev, Iv },
  584 + { "pushT", sIb, XX, XX },
  585 + { "imulS", Gv, Ev, sIb },
  586 + { "ins{b||b|}", Yb, indirDX, XX },
  587 + { "ins{R||R|}", Yv, indirDX, XX },
  588 + { "outs{b||b|}", indirDX, Xb, XX },
  589 + { "outs{R||R|}", indirDX, Xv, XX },
389 590 /* 70 */
390   - { "jo", Jb },
391   - { "jno", Jb },
392   - { "jb", Jb },
393   - { "jae", Jb },
394   - { "je", Jb },
395   - { "jne", Jb },
396   - { "jbe", Jb },
397   - { "ja", Jb },
  591 + { "joH", Jb, XX, cond_jump_flag },
  592 + { "jnoH", Jb, XX, cond_jump_flag },
  593 + { "jbH", Jb, XX, cond_jump_flag },
  594 + { "jaeH", Jb, XX, cond_jump_flag },
  595 + { "jeH", Jb, XX, cond_jump_flag },
  596 + { "jneH", Jb, XX, cond_jump_flag },
  597 + { "jbeH", Jb, XX, cond_jump_flag },
  598 + { "jaH", Jb, XX, cond_jump_flag },
398 599 /* 78 */
399   - { "js", Jb },
400   - { "jns", Jb },
401   - { "jp", Jb },
402   - { "jnp", Jb },
403   - { "jl", Jb },
404   - { "jnl", Jb },
405   - { "jle", Jb },
406   - { "jg", Jb },
  600 + { "jsH", Jb, XX, cond_jump_flag },
  601 + { "jnsH", Jb, XX, cond_jump_flag },
  602 + { "jpH", Jb, XX, cond_jump_flag },
  603 + { "jnpH", Jb, XX, cond_jump_flag },
  604 + { "jlH", Jb, XX, cond_jump_flag },
  605 + { "jgeH", Jb, XX, cond_jump_flag },
  606 + { "jleH", Jb, XX, cond_jump_flag },
  607 + { "jgH", Jb, XX, cond_jump_flag },
407 608 /* 80 */
408 609 { GRP1b },
409 610 { GRP1S },
410   - { "(bad)" },
  611 + { "(bad)", XX, XX, XX },
411 612 { GRP1Ss },
412   - { "testb", Eb, Gb },
413   - { "testS", Ev, Gv },
414   - { "xchgb", Eb, Gb },
415   - { "xchgS", Ev, Gv },
  613 + { "testB", Eb, Gb, XX },
  614 + { "testS", Ev, Gv, XX },
  615 + { "xchgB", Eb, Gb, XX },
  616 + { "xchgS", Ev, Gv, XX },
416 617 /* 88 */
417   - { "movb", Eb, Gb },
418   - { "movS", Ev, Gv },
419   - { "movb", Gb, Eb },
420   - { "movS", Gv, Ev },
421   - { "movS", Ev, Sw },
422   - { "leaS", Gv, M },
423   - { "movS", Sw, Ev },
424   - { "popS", Ev },
  618 + { "movB", Eb, Gb, XX },
  619 + { "movS", Ev, Gv, XX },
  620 + { "movB", Gb, Eb, XX },
  621 + { "movS", Gv, Ev, XX },
  622 + { "movQ", Ev, Sw, XX },
  623 + { "leaS", Gv, M, XX },
  624 + { "movQ", Sw, Ev, XX },
  625 + { "popU", Ev, XX, XX },
425 626 /* 90 */
426   - { "nop" },
427   - { "xchgS", eCX, eAX },
428   - { "xchgS", eDX, eAX },
429   - { "xchgS", eBX, eAX },
430   - { "xchgS", eSP, eAX },
431   - { "xchgS", eBP, eAX },
432   - { "xchgS", eSI, eAX },
433   - { "xchgS", eDI, eAX },
  627 + { "nop", XX, XX, XX },
  628 + /* FIXME: NOP with REPz prefix is called PAUSE. */
  629 + { "xchgS", RMeCX, eAX, XX },
  630 + { "xchgS", RMeDX, eAX, XX },
  631 + { "xchgS", RMeBX, eAX, XX },
  632 + { "xchgS", RMeSP, eAX, XX },
  633 + { "xchgS", RMeBP, eAX, XX },
  634 + { "xchgS", RMeSI, eAX, XX },
  635 + { "xchgS", RMeDI, eAX, XX },
434 636 /* 98 */
435   - { "cWtS" },
436   - { "cStd" },
437   - { "lcall", Ap },
438   - { "(bad)" }, /* fwait */
439   - { "pushf" },
440   - { "popf" },
441   - { "sahf" },
442   - { "lahf" },
  637 + { "cW{tR||tR|}", XX, XX, XX },
  638 + { "cR{tO||tO|}", XX, XX, XX },
  639 + { "lcall{T|}", Ap, XX, XX },
  640 + { "(bad)", XX, XX, XX }, /* fwait */
  641 + { "pushfT", XX, XX, XX },
  642 + { "popfT", XX, XX, XX },
  643 + { "sahf{|}", XX, XX, XX },
  644 + { "lahf{|}", XX, XX, XX },
443 645 /* a0 */
444   - { "movb", AL, Ob },
445   - { "movS", eAX, Ov },
446   - { "movb", Ob, AL },
447   - { "movS", Ov, eAX },
448   - { "movsb", Yb, Xb },
449   - { "movsS", Yv, Xv },
450   - { "cmpsb", Yb, Xb },
451   - { "cmpsS", Yv, Xv },
  646 + { "movB", AL, Ob64, XX },
  647 + { "movS", eAX, Ov64, XX },
  648 + { "movB", Ob64, AL, XX },
  649 + { "movS", Ov64, eAX, XX },
  650 + { "movs{b||b|}", Yb, Xb, XX },
  651 + { "movs{R||R|}", Yv, Xv, XX },
  652 + { "cmps{b||b|}", Xb, Yb, XX },
  653 + { "cmps{R||R|}", Xv, Yv, XX },
452 654 /* a8 */
453   - { "testb", AL, Ib },
454   - { "testS", eAX, Iv },
455   - { "stosb", Yb, AL },
456   - { "stosS", Yv, eAX },
457   - { "lodsb", AL, Xb },
458   - { "lodsS", eAX, Xv },
459   - { "scasb", AL, Yb },
460   - { "scasS", eAX, Yv },
  655 + { "testB", AL, Ib, XX },
  656 + { "testS", eAX, Iv, XX },
  657 + { "stosB", Yb, AL, XX },
  658 + { "stosS", Yv, eAX, XX },
  659 + { "lodsB", AL, Xb, XX },
  660 + { "lodsS", eAX, Xv, XX },
  661 + { "scasB", AL, Yb, XX },
  662 + { "scasS", eAX, Yv, XX },
461 663 /* b0 */
462   - { "movb", AL, Ib },
463   - { "movb", CL, Ib },
464   - { "movb", DL, Ib },
465   - { "movb", BL, Ib },
466   - { "movb", AH, Ib },
467   - { "movb", CH, Ib },
468   - { "movb", DH, Ib },
469   - { "movb", BH, Ib },
  664 + { "movB", RMAL, Ib, XX },
  665 + { "movB", RMCL, Ib, XX },
  666 + { "movB", RMDL, Ib, XX },
  667 + { "movB", RMBL, Ib, XX },
  668 + { "movB", RMAH, Ib, XX },
  669 + { "movB", RMCH, Ib, XX },
  670 + { "movB", RMDH, Ib, XX },
  671 + { "movB", RMBH, Ib, XX },
470 672 /* b8 */
471   - { "movS", eAX, Iv },
472   - { "movS", eCX, Iv },
473   - { "movS", eDX, Iv },
474   - { "movS", eBX, Iv },
475   - { "movS", eSP, Iv },
476   - { "movS", eBP, Iv },
477   - { "movS", eSI, Iv },
478   - { "movS", eDI, Iv },
  673 + { "movS", RMeAX, Iv64, XX },
  674 + { "movS", RMeCX, Iv64, XX },
  675 + { "movS", RMeDX, Iv64, XX },
  676 + { "movS", RMeBX, Iv64, XX },
  677 + { "movS", RMeSP, Iv64, XX },
  678 + { "movS", RMeBP, Iv64, XX },
  679 + { "movS", RMeSI, Iv64, XX },
  680 + { "movS", RMeDI, Iv64, XX },
479 681 /* c0 */
480 682 { GRP2b },
481 683 { GRP2S },
482   - { "ret", Iw },
483   - { "ret" },
484   - { "lesS", Gv, Mp },
485   - { "ldsS", Gv, Mp },
486   - { "movb", Eb, Ib },
487   - { "movS", Ev, Iv },
  684 + { "retT", Iw, XX, XX },
  685 + { "retT", XX, XX, XX },
  686 + { "les{S|}", Gv, Mp, XX },
  687 + { "ldsS", Gv, Mp, XX },
  688 + { "movA", Eb, Ib, XX },
  689 + { "movQ", Ev, Iv, XX },
488 690 /* c8 */
489   - { "enter", Iw, Ib },
490   - { "leave" },
491   - { "lret", Iw },
492   - { "lret" },
493   - { "int3" },
494   - { "int", Ib },
495   - { "into" },
496   - { "iret" },
  691 + { "enterT", Iw, Ib, XX },
  692 + { "leaveT", XX, XX, XX },
  693 + { "lretP", Iw, XX, XX },
  694 + { "lretP", XX, XX, XX },
  695 + { "int3", XX, XX, XX },
  696 + { "int", Ib, XX, XX },
  697 + { "into{|}", XX, XX, XX },
  698 + { "iretP", XX, XX, XX },
497 699 /* d0 */
498 700 { GRP2b_one },
499 701 { GRP2S_one },
500 702 { GRP2b_cl },
501 703 { GRP2S_cl },
502   - { "aam", Ib },
503   - { "aad", Ib },
504   - { "(bad)" },
505   - { "xlat" },
  704 + { "aam{|}", sIb, XX, XX },
  705 + { "aad{|}", sIb, XX, XX },
  706 + { "(bad)", XX, XX, XX },
  707 + { "xlat", DSBX, XX, XX },
506 708 /* d8 */
507 709 { FLOAT },
508 710 { FLOAT },
... ... @@ -513,581 +715,974 @@ static struct dis386 dis386[] = {
513 715 { FLOAT },
514 716 { FLOAT },
515 717 /* e0 */
516   - { "loopne", Jb },
517   - { "loope", Jb },
518   - { "loop", Jb },
519   - { "jCcxz", Jb },
520   - { "inb", AL, Ib },
521   - { "inS", eAX, Ib },
522   - { "outb", Ib, AL },
523   - { "outS", Ib, eAX },
  718 + { "loopneFH", Jb, XX, loop_jcxz_flag },
  719 + { "loopeFH", Jb, XX, loop_jcxz_flag },
  720 + { "loopFH", Jb, XX, loop_jcxz_flag },
  721 + { "jEcxzH", Jb, XX, loop_jcxz_flag },
  722 + { "inB", AL, Ib, XX },
  723 + { "inS", eAX, Ib, XX },
  724 + { "outB", Ib, AL, XX },
  725 + { "outS", Ib, eAX, XX },
524 726 /* e8 */
525   - { "call", Av },
526   - { "jmp", Jv },
527   - { "ljmp", Ap },
528   - { "jmp", Jb },
529   - { "inb", AL, indirDX },
530   - { "inS", eAX, indirDX },
531   - { "outb", indirDX, AL },
532   - { "outS", indirDX, eAX },
  727 + { "callT", Jv, XX, XX },
  728 + { "jmpT", Jv, XX, XX },
  729 + { "ljmp{T|}", Ap, XX, XX },
  730 + { "jmp", Jb, XX, XX },
  731 + { "inB", AL, indirDX, XX },
  732 + { "inS", eAX, indirDX, XX },
  733 + { "outB", indirDX, AL, XX },
  734 + { "outS", indirDX, eAX, XX },
533 735 /* f0 */
534   - { "(bad)" }, /* lock prefix */
535   - { "(bad)" },
536   - { "(bad)" }, /* repne */
537   - { "(bad)" }, /* repz */
538   - { "hlt" },
539   - { "cmc" },
  736 + { "(bad)", XX, XX, XX }, /* lock prefix */
  737 + { "(bad)", XX, XX, XX },
  738 + { "(bad)", XX, XX, XX }, /* repne */
  739 + { "(bad)", XX, XX, XX }, /* repz */
  740 + { "hlt", XX, XX, XX },
  741 + { "cmc", XX, XX, XX },
540 742 { GRP3b },
541 743 { GRP3S },
542 744 /* f8 */
543   - { "clc" },
544   - { "stc" },
545   - { "cli" },
546   - { "sti" },
547   - { "cld" },
548   - { "std" },
  745 + { "clc", XX, XX, XX },
  746 + { "stc", XX, XX, XX },
  747 + { "cli", XX, XX, XX },
  748 + { "sti", XX, XX, XX },
  749 + { "cld", XX, XX, XX },
  750 + { "std", XX, XX, XX },
549 751 { GRP4 },
550 752 { GRP5 },
551 753 };
552 754  
553   -static struct dis386 dis386_twobyte[] = {
  755 +static const struct dis386 dis386_twobyte[] = {
554 756 /* 00 */
555 757 { GRP6 },
556 758 { GRP7 },
557   - { "larS", Gv, Ew },
558   - { "lslS", Gv, Ew },
559   - { "(bad)" },
560   - { "(bad)" },
561   - { "clts" },
562   - { "(bad)" },
  759 + { "larS", Gv, Ew, XX },
  760 + { "lslS", Gv, Ew, XX },
  761 + { "(bad)", XX, XX, XX },
  762 + { "syscall", XX, XX, XX },
  763 + { "clts", XX, XX, XX },
  764 + { "sysretP", XX, XX, XX },
563 765 /* 08 */
564   - { "invd" },
565   - { "wbinvd" },
566   - { "(bad)" }, { "ud2a" },
567   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  766 + { "invd", XX, XX, XX },
  767 + { "wbinvd", XX, XX, XX },
  768 + { "(bad)", XX, XX, XX },
  769 + { "ud2a", XX, XX, XX },
  770 + { "(bad)", XX, XX, XX },
  771 + { GRPAMD },
  772 + { "femms", XX, XX, XX },
  773 + { "", MX, EM, OPSUF }, /* See OP_3DNowSuffix. */
568 774 /* 10 */
569   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
570   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  775 + { PREGRP8 },
  776 + { PREGRP9 },
  777 + { "movlpX", XM, EX, SIMD_Fixup, 'h' }, /* really only 2 operands */
  778 + { "movlpX", EX, XM, SIMD_Fixup, 'h' },
  779 + { "unpcklpX", XM, EX, XX },
  780 + { "unpckhpX", XM, EX, XX },
  781 + { "movhpX", XM, EX, SIMD_Fixup, 'l' },
  782 + { "movhpX", EX, XM, SIMD_Fixup, 'l' },
571 783 /* 18 */
572   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
573   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  784 + { GRP14 },
  785 + { "(bad)", XX, XX, XX },
  786 + { "(bad)", XX, XX, XX },
  787 + { "(bad)", XX, XX, XX },
  788 + { "(bad)", XX, XX, XX },
  789 + { "(bad)", XX, XX, XX },
  790 + { "(bad)", XX, XX, XX },
  791 + { "(bad)", XX, XX, XX },
574 792 /* 20 */
575   - /* these are all backward in appendix A of the intel book */
576   - { "movl", Rd, Cd },
577   - { "movl", Rd, Dd },
578   - { "movl", Cd, Rd },
579   - { "movl", Dd, Rd },
580   - { "movl", Rd, Td },
581   - { "(bad)" },
582   - { "movl", Td, Rd },
583   - { "(bad)" },
  793 + { "movL", Rm, Cm, XX },
  794 + { "movL", Rm, Dm, XX },
  795 + { "movL", Cm, Rm, XX },
  796 + { "movL", Dm, Rm, XX },
  797 + { "movL", Rd, Td, XX },
  798 + { "(bad)", XX, XX, XX },
  799 + { "movL", Td, Rd, XX },
  800 + { "(bad)", XX, XX, XX },
584 801 /* 28 */
585   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
586   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  802 + { "movapX", XM, EX, XX },
  803 + { "movapX", EX, XM, XX },
  804 + { PREGRP2 },
  805 + { "movntpX", Ev, XM, XX },
  806 + { PREGRP4 },
  807 + { PREGRP3 },
  808 + { "ucomisX", XM,EX, XX },
  809 + { "comisX", XM,EX, XX },
587 810 /* 30 */
588   - { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
589   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  811 + { "wrmsr", XX, XX, XX },
  812 + { "rdtsc", XX, XX, XX },
  813 + { "rdmsr", XX, XX, XX },
  814 + { "rdpmc", XX, XX, XX },
  815 + { "sysenter", XX, XX, XX },
  816 + { "sysexit", XX, XX, XX },
  817 + { "(bad)", XX, XX, XX },
  818 + { "(bad)", XX, XX, XX },
590 819 /* 38 */
591   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
592   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  820 + { "(bad)", XX, XX, XX },
  821 + { "(bad)", XX, XX, XX },
  822 + { "(bad)", XX, XX, XX },
  823 + { "(bad)", XX, XX, XX },
  824 + { "(bad)", XX, XX, XX },
  825 + { "(bad)", XX, XX, XX },
  826 + { "(bad)", XX, XX, XX },
  827 + { "(bad)", XX, XX, XX },
593 828 /* 40 */
594   - { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
595   - { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
  829 + { "cmovo", Gv, Ev, XX },
  830 + { "cmovno", Gv, Ev, XX },
  831 + { "cmovb", Gv, Ev, XX },
  832 + { "cmovae", Gv, Ev, XX },
  833 + { "cmove", Gv, Ev, XX },
  834 + { "cmovne", Gv, Ev, XX },
  835 + { "cmovbe", Gv, Ev, XX },
  836 + { "cmova", Gv, Ev, XX },
596 837 /* 48 */
597   - { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
598   - { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
  838 + { "cmovs", Gv, Ev, XX },
  839 + { "cmovns", Gv, Ev, XX },
  840 + { "cmovp", Gv, Ev, XX },
  841 + { "cmovnp", Gv, Ev, XX },
  842 + { "cmovl", Gv, Ev, XX },
  843 + { "cmovge", Gv, Ev, XX },
  844 + { "cmovle", Gv, Ev, XX },
  845 + { "cmovg", Gv, Ev, XX },
599 846 /* 50 */
600   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
601   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  847 + { "movmskpX", Gd, XS, XX },
  848 + { PREGRP13 },
  849 + { PREGRP12 },
  850 + { PREGRP11 },
  851 + { "andpX", XM, EX, XX },
  852 + { "andnpX", XM, EX, XX },
  853 + { "orpX", XM, EX, XX },
  854 + { "xorpX", XM, EX, XX },
602 855 /* 58 */
603   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
604   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  856 + { PREGRP0 },
  857 + { PREGRP10 },
  858 + { PREGRP17 },
  859 + { PREGRP16 },
  860 + { PREGRP14 },
  861 + { PREGRP7 },
  862 + { PREGRP5 },
  863 + { PREGRP6 },
605 864 /* 60 */
606   - { "punpcklbw", MX, EM },
607   - { "punpcklwd", MX, EM },
608   - { "punpckldq", MX, EM },
609   - { "packsswb", MX, EM },
610   - { "pcmpgtb", MX, EM },
611   - { "pcmpgtw", MX, EM },
612   - { "pcmpgtd", MX, EM },
613   - { "packuswb", MX, EM },
  865 + { "punpcklbw", MX, EM, XX },
  866 + { "punpcklwd", MX, EM, XX },
  867 + { "punpckldq", MX, EM, XX },
  868 + { "packsswb", MX, EM, XX },
  869 + { "pcmpgtb", MX, EM, XX },
  870 + { "pcmpgtw", MX, EM, XX },
  871 + { "pcmpgtd", MX, EM, XX },
  872 + { "packuswb", MX, EM, XX },
614 873 /* 68 */
615   - { "punpckhbw", MX, EM },
616   - { "punpckhwd", MX, EM },
617   - { "punpckhdq", MX, EM },
618   - { "packssdw", MX, EM },
619   - { "(bad)" }, { "(bad)" },
620   - { "movd", MX, Ev },
621   - { "movq", MX, EM },
  874 + { "punpckhbw", MX, EM, XX },
  875 + { "punpckhwd", MX, EM, XX },
  876 + { "punpckhdq", MX, EM, XX },
  877 + { "packssdw", MX, EM, XX },
  878 + { PREGRP26 },
  879 + { PREGRP24 },
  880 + { "movd", MX, Ed, XX },
  881 + { PREGRP19 },
622 882 /* 70 */
623   - { "(bad)" },
  883 + { PREGRP22 },
624 884 { GRP10 },
625 885 { GRP11 },
626 886 { GRP12 },
627   - { "pcmpeqb", MX, EM },
628   - { "pcmpeqw", MX, EM },
629   - { "pcmpeqd", MX, EM },
630   - { "emms" },
  887 + { "pcmpeqb", MX, EM, XX },
  888 + { "pcmpeqw", MX, EM, XX },
  889 + { "pcmpeqd", MX, EM, XX },
  890 + { "emms", XX, XX, XX },
631 891 /* 78 */
632   - { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
633   - { "(bad)" }, { "(bad)" },
634   - { "movd", Ev, MX },
635   - { "movq", EM, MX },
  892 + { "(bad)", XX, XX, XX },
  893 + { "(bad)", XX, XX, XX },
  894 + { "(bad)", XX, XX, XX },
  895 + { "(bad)", XX, XX, XX },
  896 + { "(bad)", XX, XX, XX },
  897 + { "(bad)", XX, XX, XX },
  898 + { PREGRP23 },
  899 + { PREGRP20 },
636 900 /* 80 */
637   - { "jo", Jv },
638   - { "jno", Jv },
639   - { "jb", Jv },
640   - { "jae", Jv },
641   - { "je", Jv },
642   - { "jne", Jv },
643   - { "jbe", Jv },
644   - { "ja", Jv },
  901 + { "joH", Jv, XX, cond_jump_flag },
  902 + { "jnoH", Jv, XX, cond_jump_flag },
  903 + { "jbH", Jv, XX, cond_jump_flag },
  904 + { "jaeH", Jv, XX, cond_jump_flag },
  905 + { "jeH", Jv, XX, cond_jump_flag },
  906 + { "jneH", Jv, XX, cond_jump_flag },
  907 + { "jbeH", Jv, XX, cond_jump_flag },
  908 + { "jaH", Jv, XX, cond_jump_flag },
645 909 /* 88 */
646   - { "js", Jv },
647   - { "jns", Jv },
648   - { "jp", Jv },
649   - { "jnp", Jv },
650   - { "jl", Jv },
651   - { "jge", Jv },
652   - { "jle", Jv },
653   - { "jg", Jv },
  910 + { "jsH", Jv, XX, cond_jump_flag },
  911 + { "jnsH", Jv, XX, cond_jump_flag },
  912 + { "jpH", Jv, XX, cond_jump_flag },
  913 + { "jnpH", Jv, XX, cond_jump_flag },
  914 + { "jlH", Jv, XX, cond_jump_flag },
  915 + { "jgeH", Jv, XX, cond_jump_flag },
  916 + { "jleH", Jv, XX, cond_jump_flag },
  917 + { "jgH", Jv, XX, cond_jump_flag },
654 918 /* 90 */
655   - { "seto", Eb },
656   - { "setno", Eb },
657   - { "setb", Eb },
658   - { "setae", Eb },
659   - { "sete", Eb },
660   - { "setne", Eb },
661   - { "setbe", Eb },
662   - { "seta", Eb },
  919 + { "seto", Eb, XX, XX },
  920 + { "setno", Eb, XX, XX },
  921 + { "setb", Eb, XX, XX },
  922 + { "setae", Eb, XX, XX },
  923 + { "sete", Eb, XX, XX },
  924 + { "setne", Eb, XX, XX },
  925 + { "setbe", Eb, XX, XX },
  926 + { "seta", Eb, XX, XX },
663 927 /* 98 */
664   - { "sets", Eb },
665   - { "setns", Eb },
666   - { "setp", Eb },
667   - { "setnp", Eb },
668   - { "setl", Eb },
669   - { "setge", Eb },
670   - { "setle", Eb },
671   - { "setg", Eb },
  928 + { "sets", Eb, XX, XX },
  929 + { "setns", Eb, XX, XX },
  930 + { "setp", Eb, XX, XX },
  931 + { "setnp", Eb, XX, XX },
  932 + { "setl", Eb, XX, XX },
  933 + { "setge", Eb, XX, XX },
  934 + { "setle", Eb, XX, XX },
  935 + { "setg", Eb, XX, XX },
672 936 /* a0 */
673   - { "pushS", fs },
674   - { "popS", fs },
675   - { "cpuid" },
676   - { "btS", Ev, Gv },
677   - { "shldS", Ev, Gv, Ib },
678   - { "shldS", Ev, Gv, CL },
679   - { "(bad)" },
680   - { "(bad)" },
  937 + { "pushT", fs, XX, XX },
  938 + { "popT", fs, XX, XX },
  939 + { "cpuid", XX, XX, XX },
  940 + { "btS", Ev, Gv, XX },
  941 + { "shldS", Ev, Gv, Ib },
  942 + { "shldS", Ev, Gv, CL },
  943 + { "(bad)", XX, XX, XX },
  944 + { "(bad)", XX, XX, XX },
681 945 /* a8 */
682   - { "pushS", gs },
683   - { "popS", gs },
684   - { "rsm" },
685   - { "btsS", Ev, Gv },
686   - { "shrdS", Ev, Gv, Ib },
687   - { "shrdS", Ev, Gv, CL },
688   - { "(bad)" },
689   - { "imulS", Gv, Ev },
  946 + { "pushT", gs, XX, XX },
  947 + { "popT", gs, XX, XX },
  948 + { "rsm", XX, XX, XX },
  949 + { "btsS", Ev, Gv, XX },
  950 + { "shrdS", Ev, Gv, Ib },
  951 + { "shrdS", Ev, Gv, CL },
  952 + { GRP13 },
  953 + { "imulS", Gv, Ev, XX },
690 954 /* b0 */
691   - { "cmpxchgb", Eb, Gb },
692   - { "cmpxchgS", Ev, Gv },
693   - { "lssS", Gv, Mp }, /* 386 lists only Mp */
694   - { "btrS", Ev, Gv },
695   - { "lfsS", Gv, Mp }, /* 386 lists only Mp */
696   - { "lgsS", Gv, Mp }, /* 386 lists only Mp */
697   - { "movzbS", Gv, Eb },
698   - { "movzwS", Gv, Ew },
  955 + { "cmpxchgB", Eb, Gb, XX },
  956 + { "cmpxchgS", Ev, Gv, XX },
  957 + { "lssS", Gv, Mp, XX },
  958 + { "btrS", Ev, Gv, XX },
  959 + { "lfsS", Gv, Mp, XX },
  960 + { "lgsS", Gv, Mp, XX },
  961 + { "movz{bR|x|bR|x}", Gv, Eb, XX },
  962 + { "movz{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movzww ! */
699 963 /* b8 */
700   - { "ud2b" },
701   - { "(bad)" },
  964 + { "(bad)", XX, XX, XX },
  965 + { "ud2b", XX, XX, XX },
702 966 { GRP8 },
703   - { "btcS", Ev, Gv },
704   - { "bsfS", Gv, Ev },
705   - { "bsrS", Gv, Ev },
706   - { "movsbS", Gv, Eb },
707   - { "movswS", Gv, Ew },
  967 + { "btcS", Ev, Gv, XX },
  968 + { "bsfS", Gv, Ev, XX },
  969 + { "bsrS", Gv, Ev, XX },
  970 + { "movs{bR|x|bR|x}", Gv, Eb, XX },
  971 + { "movs{wR|x|wR|x}", Gv, Ew, XX }, /* yes, there really is movsww ! */
708 972 /* c0 */
709   - { "xaddb", Eb, Gb },
710   - { "xaddS", Ev, Gv },
711   - { "(bad)" },
712   - { "(bad)" },
713   - { "(bad)" },
714   - { "(bad)" },
715   - { "(bad)" },
716   - { GRP9 },
  973 + { "xaddB", Eb, Gb, XX },
  974 + { "xaddS", Ev, Gv, XX },
  975 + { PREGRP1 },
  976 + { "movntiS", Ev, Gv, XX },
  977 + { "pinsrw", MX, Ed, Ib },
  978 + { "pextrw", Gd, MS, Ib },
  979 + { "shufpX", XM, EX, Ib },
  980 + { GRP9 },
717 981 /* c8 */
718   - { "bswap", eAX },
719   - { "bswap", eCX },
720   - { "bswap", eDX },
721   - { "bswap", eBX },
722   - { "bswap", eSP },
723   - { "bswap", eBP },
724   - { "bswap", eSI },
725   - { "bswap", eDI },
  982 + { "bswap", RMeAX, XX, XX },
  983 + { "bswap", RMeCX, XX, XX },
  984 + { "bswap", RMeDX, XX, XX },
  985 + { "bswap", RMeBX, XX, XX },
  986 + { "bswap", RMeSP, XX, XX },
  987 + { "bswap", RMeBP, XX, XX },
  988 + { "bswap", RMeSI, XX, XX },
  989 + { "bswap", RMeDI, XX, XX },
726 990 /* d0 */
727   - { "(bad)" },
728   - { "psrlw", MX, EM },
729   - { "psrld", MX, EM },
730   - { "psrlq", MX, EM },
731   - { "(bad)" },
732   - { "pmullw", MX, EM },
733   - { "(bad)" }, { "(bad)" },
  991 + { "(bad)", XX, XX, XX },
  992 + { "psrlw", MX, EM, XX },
  993 + { "psrld", MX, EM, XX },
  994 + { "psrlq", MX, EM, XX },
  995 + { "paddq", MX, EM, XX },
  996 + { "pmullw", MX, EM, XX },
  997 + { PREGRP21 },
  998 + { "pmovmskb", Gd, MS, XX },
734 999 /* d8 */
735   - { "psubusb", MX, EM },
736   - { "psubusw", MX, EM },
737   - { "(bad)" },
738   - { "pand", MX, EM },
739   - { "paddusb", MX, EM },
740   - { "paddusw", MX, EM },
741   - { "(bad)" },
742   - { "pandn", MX, EM },
  1000 + { "psubusb", MX, EM, XX },
  1001 + { "psubusw", MX, EM, XX },
  1002 + { "pminub", MX, EM, XX },
  1003 + { "pand", MX, EM, XX },
  1004 + { "paddusb", MX, EM, XX },
  1005 + { "paddusw", MX, EM, XX },
  1006 + { "pmaxub", MX, EM, XX },
  1007 + { "pandn", MX, EM, XX },
743 1008 /* e0 */
744   - { "(bad)" },
745   - { "psraw", MX, EM },
746   - { "psrad", MX, EM },
747   - { "(bad)" },
748   - { "(bad)" },
749   - { "pmulhw", MX, EM },
750   - { "(bad)" }, { "(bad)" },
  1009 + { "pavgb", MX, EM, XX },
  1010 + { "psraw", MX, EM, XX },
  1011 + { "psrad", MX, EM, XX },
  1012 + { "pavgw", MX, EM, XX },
  1013 + { "pmulhuw", MX, EM, XX },
  1014 + { "pmulhw", MX, EM, XX },
  1015 + { PREGRP15 },
  1016 + { PREGRP25 },
751 1017 /* e8 */
752   - { "psubsb", MX, EM },
753   - { "psubsw", MX, EM },
754   - { "(bad)" },
755   - { "por", MX, EM },
756   - { "paddsb", MX, EM },
757   - { "paddsw", MX, EM },
758   - { "(bad)" },
759   - { "pxor", MX, EM },
  1018 + { "psubsb", MX, EM, XX },
  1019 + { "psubsw", MX, EM, XX },
  1020 + { "pminsw", MX, EM, XX },
  1021 + { "por", MX, EM, XX },
  1022 + { "paddsb", MX, EM, XX },
  1023 + { "paddsw", MX, EM, XX },
  1024 + { "pmaxsw", MX, EM, XX },
  1025 + { "pxor", MX, EM, XX },
760 1026 /* f0 */
761   - { "(bad)" },
762   - { "psllw", MX, EM },
763   - { "pslld", MX, EM },
764   - { "psllq", MX, EM },
765   - { "(bad)" },
766   - { "pmaddwd", MX, EM },
767   - { "(bad)" }, { "(bad)" },
  1027 + { "(bad)", XX, XX, XX },
  1028 + { "psllw", MX, EM, XX },
  1029 + { "pslld", MX, EM, XX },
  1030 + { "psllq", MX, EM, XX },
  1031 + { "pmuludq", MX, EM, XX },
  1032 + { "pmaddwd", MX, EM, XX },
  1033 + { "psadbw", MX, EM, XX },
  1034 + { PREGRP18 },
768 1035 /* f8 */
769   - { "psubb", MX, EM },
770   - { "psubw", MX, EM },
771   - { "psubd", MX, EM },
772   - { "(bad)" },
773   - { "paddb", MX, EM },
774   - { "paddw", MX, EM },
775   - { "paddd", MX, EM },
776   - { "(bad)" }
  1036 + { "psubb", MX, EM, XX },
  1037 + { "psubw", MX, EM, XX },
  1038 + { "psubd", MX, EM, XX },
  1039 + { "psubq", MX, EM, XX },
  1040 + { "paddb", MX, EM, XX },
  1041 + { "paddw", MX, EM, XX },
  1042 + { "paddd", MX, EM, XX },
  1043 + { "(bad)", XX, XX, XX }
777 1044 };
778 1045  
779 1046 static const unsigned char onebyte_has_modrm[256] = {
780   - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
781   - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
782   - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
783   - 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
784   - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
785   - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
786   - 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
787   - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
788   - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
789   - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
790   - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
791   - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
792   - 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
793   - 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
794   - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
795   - 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
  1047 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
  1048 + /* ------------------------------- */
  1049 + /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
  1050 + /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
  1051 + /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
  1052 + /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
  1053 + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
  1054 + /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
  1055 + /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
  1056 + /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
  1057 + /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
  1058 + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
  1059 + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
  1060 + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
  1061 + /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
  1062 + /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
  1063 + /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
  1064 + /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1 /* f0 */
  1065 + /* ------------------------------- */
  1066 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
796 1067 };
797 1068  
798 1069 static const unsigned char twobyte_has_modrm[256] = {
799   - /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
800   - /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
801   - /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
  1070 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
  1071 + /* ------------------------------- */
  1072 + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
  1073 + /* 10 */ 1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0, /* 1f */
  1074 + /* 20 */ 1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1, /* 2f */
802 1075 /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
803 1076 /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
804   - /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
805   - /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
806   - /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
  1077 + /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
  1078 + /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
  1079 + /* 70 */ 1,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
807 1080 /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
808 1081 /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
809   - /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
  1082 + /* a0 */ 0,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1, /* af */
810 1083 /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
811 1084 /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
812   - /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
813   - /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
814   - /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
  1085 + /* d0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
  1086 + /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
  1087 + /* f0 */ 0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0 /* ff */
  1088 + /* ------------------------------- */
  1089 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
  1090 +};
  1091 +
  1092 +static const unsigned char twobyte_uses_SSE_prefix[256] = {
  1093 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
  1094 + /* ------------------------------- */
  1095 + /* 00 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
  1096 + /* 10 */ 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
  1097 + /* 20 */ 0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0, /* 2f */
  1098 + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
  1099 + /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 4f */
  1100 + /* 50 */ 0,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* 5f */
  1101 + /* 60 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1, /* 6f */
  1102 + /* 70 */ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, /* 7f */
  1103 + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
  1104 + /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 9f */
  1105 + /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* af */
  1106 + /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* bf */
  1107 + /* c0 */ 0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0, /* cf */
  1108 + /* d0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* df */
  1109 + /* e0 */ 0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0, /* ef */
  1110 + /* f0 */ 0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0 /* ff */
  1111 + /* ------------------------------- */
  1112 + /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
815 1113 };
816 1114  
817 1115 static char obuf[100];
818 1116 static char *obufp;
819 1117 static char scratchbuf[100];
820 1118 static unsigned char *start_codep;
  1119 +static unsigned char *insn_codep;
821 1120 static unsigned char *codep;
822 1121 static disassemble_info *the_info;
823 1122 static int mod;
824 1123 static int rm;
825 1124 static int reg;
826   -static void oappend PARAMS ((char *s));
  1125 +static unsigned char need_modrm;
  1126 +
  1127 +/* If we are accessing mod/rm/reg without need_modrm set, then the
  1128 + values are stale. Hitting this abort likely indicates that you
  1129 + need to update onebyte_has_modrm or twobyte_has_modrm. */
  1130 +#define MODRM_CHECK if (!need_modrm) abort ()
  1131 +
  1132 +static const char **names64;
  1133 +static const char **names32;
  1134 +static const char **names16;
  1135 +static const char **names8;
  1136 +static const char **names8rex;
  1137 +static const char **names_seg;
  1138 +static const char **index16;
  1139 +
  1140 +static const char *intel_names64[] = {
  1141 + "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
  1142 + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
  1143 +};
  1144 +static const char *intel_names32[] = {
  1145 + "eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi",
  1146 + "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d"
  1147 +};
  1148 +static const char *intel_names16[] = {
  1149 + "ax", "cx", "dx", "bx", "sp", "bp", "si", "di",
  1150 + "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
  1151 +};
  1152 +static const char *intel_names8[] = {
  1153 + "al", "cl", "dl", "bl", "ah", "ch", "dh", "bh",
  1154 +};
  1155 +static const char *intel_names8rex[] = {
  1156 + "al", "cl", "dl", "bl", "spl", "bpl", "sil", "dil",
  1157 + "r8b", "r9b", "r10b", "r11b", "r12b", "r13b", "r14b", "r15b"
  1158 +};
  1159 +static const char *intel_names_seg[] = {
  1160 + "es", "cs", "ss", "ds", "fs", "gs", "?", "?",
  1161 +};
  1162 +static const char *intel_index16[] = {
  1163 + "bx+si", "bx+di", "bp+si", "bp+di", "si", "di", "bp", "bx"
  1164 +};
827 1165  
828   -static char *names32[]={
829   - "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
  1166 +static const char *att_names64[] = {
  1167 + "%rax", "%rcx", "%rdx", "%rbx", "%rsp", "%rbp", "%rsi", "%rdi",
  1168 + "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
  1169 +};
  1170 +static const char *att_names32[] = {
  1171 + "%eax", "%ecx", "%edx", "%ebx", "%esp", "%ebp", "%esi", "%edi",
  1172 + "%r8d", "%r9d", "%r10d", "%r11d", "%r12d", "%r13d", "%r14d", "%r15d"
830 1173 };
831   -static char *names16[] = {
832   - "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
  1174 +static const char *att_names16[] = {
  1175 + "%ax", "%cx", "%dx", "%bx", "%sp", "%bp", "%si", "%di",
  1176 + "%r8w", "%r9w", "%r10w", "%r11w", "%r12w", "%r13w", "%r14w", "%r15w"
833 1177 };
834   -static char *names8[] = {
835   - "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
  1178 +static const char *att_names8[] = {
  1179 + "%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
836 1180 };
837   -static char *names_seg[] = {
838   - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
  1181 +static const char *att_names8rex[] = {
  1182 + "%al", "%cl", "%dl", "%bl", "%spl", "%bpl", "%sil", "%dil",
  1183 + "%r8b", "%r9b", "%r10b", "%r11b", "%r12b", "%r13b", "%r14b", "%r15b"
839 1184 };
840   -static char *index16[] = {
841   - "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
  1185 +static const char *att_names_seg[] = {
  1186 + "%es", "%cs", "%ss", "%ds", "%fs", "%gs", "%?", "%?",
  1187 +};
  1188 +static const char *att_index16[] = {
  1189 + "%bx,%si", "%bx,%di", "%bp,%si", "%bp,%di", "%si", "%di", "%bp", "%bx"
842 1190 };
843 1191  
844   -static struct dis386 grps[][8] = {
  1192 +static const struct dis386 grps[][8] = {
845 1193 /* GRP1b */
846 1194 {
847   - { "addb", Eb, Ib },
848   - { "orb", Eb, Ib },
849   - { "adcb", Eb, Ib },
850   - { "sbbb", Eb, Ib },
851   - { "andb", Eb, Ib },
852   - { "subb", Eb, Ib },
853   - { "xorb", Eb, Ib },
854   - { "cmpb", Eb, Ib }
  1195 + { "addA", Eb, Ib, XX },
  1196 + { "orA", Eb, Ib, XX },
  1197 + { "adcA", Eb, Ib, XX },
  1198 + { "sbbA", Eb, Ib, XX },
  1199 + { "andA", Eb, Ib, XX },
  1200 + { "subA", Eb, Ib, XX },
  1201 + { "xorA", Eb, Ib, XX },
  1202 + { "cmpA", Eb, Ib, XX }
855 1203 },
856 1204 /* GRP1S */
857 1205 {
858   - { "addS", Ev, Iv },
859   - { "orS", Ev, Iv },
860   - { "adcS", Ev, Iv },
861   - { "sbbS", Ev, Iv },
862   - { "andS", Ev, Iv },
863   - { "subS", Ev, Iv },
864   - { "xorS", Ev, Iv },
865   - { "cmpS", Ev, Iv }
  1206 + { "addQ", Ev, Iv, XX },
  1207 + { "orQ", Ev, Iv, XX },
  1208 + { "adcQ", Ev, Iv, XX },
  1209 + { "sbbQ", Ev, Iv, XX },
  1210 + { "andQ", Ev, Iv, XX },
  1211 + { "subQ", Ev, Iv, XX },
  1212 + { "xorQ", Ev, Iv, XX },
  1213 + { "cmpQ", Ev, Iv, XX }
866 1214 },
867 1215 /* GRP1Ss */
868 1216 {
869   - { "addS", Ev, sIb },
870   - { "orS", Ev, sIb },
871   - { "adcS", Ev, sIb },
872   - { "sbbS", Ev, sIb },
873   - { "andS", Ev, sIb },
874   - { "subS", Ev, sIb },
875   - { "xorS", Ev, sIb },
876   - { "cmpS", Ev, sIb }
  1217 + { "addQ", Ev, sIb, XX },
  1218 + { "orQ", Ev, sIb, XX },
  1219 + { "adcQ", Ev, sIb, XX },
  1220 + { "sbbQ", Ev, sIb, XX },
  1221 + { "andQ", Ev, sIb, XX },
  1222 + { "subQ", Ev, sIb, XX },
  1223 + { "xorQ", Ev, sIb, XX },
  1224 + { "cmpQ", Ev, sIb, XX }
877 1225 },
878 1226 /* GRP2b */
879 1227 {
880   - { "rolb", Eb, Ib },
881   - { "rorb", Eb, Ib },
882   - { "rclb", Eb, Ib },
883   - { "rcrb", Eb, Ib },
884   - { "shlb", Eb, Ib },
885   - { "shrb", Eb, Ib },
886   - { "(bad)" },
887   - { "sarb", Eb, Ib },
  1228 + { "rolA", Eb, Ib, XX },
  1229 + { "rorA", Eb, Ib, XX },
  1230 + { "rclA", Eb, Ib, XX },
  1231 + { "rcrA", Eb, Ib, XX },
  1232 + { "shlA", Eb, Ib, XX },
  1233 + { "shrA", Eb, Ib, XX },
  1234 + { "(bad)", XX, XX, XX },
  1235 + { "sarA", Eb, Ib, XX },
888 1236 },
889 1237 /* GRP2S */
890 1238 {
891   - { "rolS", Ev, Ib },
892   - { "rorS", Ev, Ib },
893   - { "rclS", Ev, Ib },
894   - { "rcrS", Ev, Ib },
895   - { "shlS", Ev, Ib },
896   - { "shrS", Ev, Ib },
897   - { "(bad)" },
898   - { "sarS", Ev, Ib },
  1239 + { "rolQ", Ev, Ib, XX },
  1240 + { "rorQ", Ev, Ib, XX },
  1241 + { "rclQ", Ev, Ib, XX },
  1242 + { "rcrQ", Ev, Ib, XX },
  1243 + { "shlQ", Ev, Ib, XX },
  1244 + { "shrQ", Ev, Ib, XX },
  1245 + { "(bad)", XX, XX, XX },
  1246 + { "sarQ", Ev, Ib, XX },
899 1247 },
900 1248 /* GRP2b_one */
901 1249 {
902   - { "rolb", Eb },
903   - { "rorb", Eb },
904   - { "rclb", Eb },
905   - { "rcrb", Eb },
906   - { "shlb", Eb },
907   - { "shrb", Eb },
908   - { "(bad)" },
909   - { "sarb", Eb },
  1250 + { "rolA", Eb, XX, XX },
  1251 + { "rorA", Eb, XX, XX },
  1252 + { "rclA", Eb, XX, XX },
  1253 + { "rcrA", Eb, XX, XX },
  1254 + { "shlA", Eb, XX, XX },
  1255 + { "shrA", Eb, XX, XX },
  1256 + { "(bad)", XX, XX, XX },
  1257 + { "sarA", Eb, XX, XX },
910 1258 },
911 1259 /* GRP2S_one */
912 1260 {
913   - { "rolS", Ev },
914   - { "rorS", Ev },
915   - { "rclS", Ev },
916   - { "rcrS", Ev },
917   - { "shlS", Ev },
918   - { "shrS", Ev },
919   - { "(bad)" },
920   - { "sarS", Ev },
  1261 + { "rolQ", Ev, XX, XX },
  1262 + { "rorQ", Ev, XX, XX },
  1263 + { "rclQ", Ev, XX, XX },
  1264 + { "rcrQ", Ev, XX, XX },
  1265 + { "shlQ", Ev, XX, XX },
  1266 + { "shrQ", Ev, XX, XX },
  1267 + { "(bad)", XX, XX, XX},
  1268 + { "sarQ", Ev, XX, XX },
921 1269 },
922 1270 /* GRP2b_cl */
923 1271 {
924   - { "rolb", Eb, CL },
925   - { "rorb", Eb, CL },
926   - { "rclb", Eb, CL },
927   - { "rcrb", Eb, CL },
928   - { "shlb", Eb, CL },
929   - { "shrb", Eb, CL },
930   - { "(bad)" },
931   - { "sarb", Eb, CL },
  1272 + { "rolA", Eb, CL, XX },
  1273 + { "rorA", Eb, CL, XX },
  1274 + { "rclA", Eb, CL, XX },
  1275 + { "rcrA", Eb, CL, XX },
  1276 + { "shlA", Eb, CL, XX },
  1277 + { "shrA", Eb, CL, XX },
  1278 + { "(bad)", XX, XX, XX },
  1279 + { "sarA", Eb, CL, XX },
932 1280 },
933 1281 /* GRP2S_cl */
934 1282 {
935   - { "rolS", Ev, CL },
936   - { "rorS", Ev, CL },
937   - { "rclS", Ev, CL },
938   - { "rcrS", Ev, CL },
939   - { "shlS", Ev, CL },
940   - { "shrS", Ev, CL },
941   - { "(bad)" },
942   - { "sarS", Ev, CL }
  1283 + { "rolQ", Ev, CL, XX },
  1284 + { "rorQ", Ev, CL, XX },
  1285 + { "rclQ", Ev, CL, XX },
  1286 + { "rcrQ", Ev, CL, XX },
  1287 + { "shlQ", Ev, CL, XX },
  1288 + { "shrQ", Ev, CL, XX },
  1289 + { "(bad)", XX, XX, XX },
  1290 + { "sarQ", Ev, CL, XX }
943 1291 },
944 1292 /* GRP3b */
945 1293 {
946   - { "testb", Eb, Ib },
947   - { "(bad)", Eb },
948   - { "notb", Eb },
949   - { "negb", Eb },
950   - { "mulb", AL, Eb },
951   - { "imulb", AL, Eb },
952   - { "divb", AL, Eb },
953   - { "idivb", AL, Eb }
  1294 + { "testA", Eb, Ib, XX },
  1295 + { "(bad)", Eb, XX, XX },
  1296 + { "notA", Eb, XX, XX },
  1297 + { "negA", Eb, XX, XX },
  1298 + { "mulA", Eb, XX, XX }, /* Don't print the implicit %al register, */
  1299 + { "imulA", Eb, XX, XX }, /* to distinguish these opcodes from other */
  1300 + { "divA", Eb, XX, XX }, /* mul/imul opcodes. Do the same for div */
  1301 + { "idivA", Eb, XX, XX } /* and idiv for consistency. */
954 1302 },
955 1303 /* GRP3S */
956 1304 {
957   - { "testS", Ev, Iv },
958   - { "(bad)" },
959   - { "notS", Ev },
960   - { "negS", Ev },
961   - { "mulS", eAX, Ev },
962   - { "imulS", eAX, Ev },
963   - { "divS", eAX, Ev },
964   - { "idivS", eAX, Ev },
  1305 + { "testQ", Ev, Iv, XX },
  1306 + { "(bad)", XX, XX, XX },
  1307 + { "notQ", Ev, XX, XX },
  1308 + { "negQ", Ev, XX, XX },
  1309 + { "mulQ", Ev, XX, XX }, /* Don't print the implicit register. */
  1310 + { "imulQ", Ev, XX, XX },
  1311 + { "divQ", Ev, XX, XX },
  1312 + { "idivQ", Ev, XX, XX },
965 1313 },
966 1314 /* GRP4 */
967 1315 {
968   - { "incb", Eb },
969   - { "decb", Eb },
970   - { "(bad)" },
971   - { "(bad)" },
972   - { "(bad)" },
973   - { "(bad)" },
974   - { "(bad)" },
975   - { "(bad)" },
  1316 + { "incA", Eb, XX, XX },
  1317 + { "decA", Eb, XX, XX },
  1318 + { "(bad)", XX, XX, XX },
  1319 + { "(bad)", XX, XX, XX },
  1320 + { "(bad)", XX, XX, XX },
  1321 + { "(bad)", XX, XX, XX },
  1322 + { "(bad)", XX, XX, XX },
  1323 + { "(bad)", XX, XX, XX },
976 1324 },
977 1325 /* GRP5 */
978 1326 {
979   - { "incS", Ev },
980   - { "decS", Ev },
981   - { "call", indirEv },
982   - { "lcall", indirEv },
983   - { "jmp", indirEv },
984   - { "ljmp", indirEv },
985   - { "pushS", Ev },
986   - { "(bad)" },
  1327 + { "incQ", Ev, XX, XX },
  1328 + { "decQ", Ev, XX, XX },
  1329 + { "callT", indirEv, XX, XX },
  1330 + { "lcallT", indirEv, XX, XX },
  1331 + { "jmpT", indirEv, XX, XX },
  1332 + { "ljmpT", indirEv, XX, XX },
  1333 + { "pushU", Ev, XX, XX },
  1334 + { "(bad)", XX, XX, XX },
987 1335 },
988 1336 /* GRP6 */
989 1337 {
990   - { "sldt", Ew },
991   - { "str", Ew },
992   - { "lldt", Ew },
993   - { "ltr", Ew },
994   - { "verr", Ew },
995   - { "verw", Ew },
996   - { "(bad)" },
997   - { "(bad)" }
  1338 + { "sldtQ", Ev, XX, XX },
  1339 + { "strQ", Ev, XX, XX },
  1340 + { "lldt", Ew, XX, XX },
  1341 + { "ltr", Ew, XX, XX },
  1342 + { "verr", Ew, XX, XX },
  1343 + { "verw", Ew, XX, XX },
  1344 + { "(bad)", XX, XX, XX },
  1345 + { "(bad)", XX, XX, XX }
998 1346 },
999 1347 /* GRP7 */
1000 1348 {
1001   - { "sgdt", Ew },
1002   - { "sidt", Ew },
1003   - { "lgdt", Ew },
1004   - { "lidt", Ew },
1005   - { "smsw", Ew },
1006   - { "(bad)" },
1007   - { "lmsw", Ew },
1008   - { "invlpg", Ew },
  1349 + { "sgdtQ", M, XX, XX },
  1350 + { "sidtQ", M, XX, XX },
  1351 + { "lgdtQ", M, XX, XX },
  1352 + { "lidtQ", M, XX, XX },
  1353 + { "smswQ", Ev, XX, XX },
  1354 + { "(bad)", XX, XX, XX },
  1355 + { "lmsw", Ew, XX, XX },
  1356 + { "invlpg", Ew, XX, XX },
1009 1357 },
1010 1358 /* GRP8 */
1011 1359 {
1012   - { "(bad)" },
1013   - { "(bad)" },
1014   - { "(bad)" },
1015   - { "(bad)" },
1016   - { "btS", Ev, Ib },
1017   - { "btsS", Ev, Ib },
1018   - { "btrS", Ev, Ib },
1019   - { "btcS", Ev, Ib },
  1360 + { "(bad)", XX, XX, XX },
  1361 + { "(bad)", XX, XX, XX },
  1362 + { "(bad)", XX, XX, XX },
  1363 + { "(bad)", XX, XX, XX },
  1364 + { "btQ", Ev, Ib, XX },
  1365 + { "btsQ", Ev, Ib, XX },
  1366 + { "btrQ", Ev, Ib, XX },
  1367 + { "btcQ", Ev, Ib, XX },
1020 1368 },
1021 1369 /* GRP9 */
1022 1370 {
1023   - { "(bad)" },
1024   - { "cmpxchg8b", Ev },
1025   - { "(bad)" },
1026   - { "(bad)" },
1027   - { "(bad)" },
1028   - { "(bad)" },
1029   - { "(bad)" },
1030   - { "(bad)" },
  1371 + { "(bad)", XX, XX, XX },
  1372 + { "cmpxchg8b", Ev, XX, XX },
  1373 + { "(bad)", XX, XX, XX },
  1374 + { "(bad)", XX, XX, XX },
  1375 + { "(bad)", XX, XX, XX },
  1376 + { "(bad)", XX, XX, XX },
  1377 + { "(bad)", XX, XX, XX },
  1378 + { "(bad)", XX, XX, XX },
1031 1379 },
1032 1380 /* GRP10 */
1033 1381 {
1034   - { "(bad)" },
1035   - { "(bad)" },
1036   - { "psrlw", MS, Ib },
1037   - { "(bad)" },
1038   - { "psraw", MS, Ib },
1039   - { "(bad)" },
1040   - { "psllw", MS, Ib },
1041   - { "(bad)" },
  1382 + { "(bad)", XX, XX, XX },
  1383 + { "(bad)", XX, XX, XX },
  1384 + { "psrlw", MS, Ib, XX },
  1385 + { "(bad)", XX, XX, XX },
  1386 + { "psraw", MS, Ib, XX },
  1387 + { "(bad)", XX, XX, XX },
  1388 + { "psllw", MS, Ib, XX },
  1389 + { "(bad)", XX, XX, XX },
1042 1390 },
1043 1391 /* GRP11 */
1044 1392 {
1045   - { "(bad)" },
1046   - { "(bad)" },
1047   - { "psrld", MS, Ib },
1048   - { "(bad)" },
1049   - { "psrad", MS, Ib },
1050   - { "(bad)" },
1051   - { "pslld", MS, Ib },
1052   - { "(bad)" },
  1393 + { "(bad)", XX, XX, XX },
  1394 + { "(bad)", XX, XX, XX },
  1395 + { "psrld", MS, Ib, XX },
  1396 + { "(bad)", XX, XX, XX },
  1397 + { "psrad", MS, Ib, XX },
  1398 + { "(bad)", XX, XX, XX },
  1399 + { "pslld", MS, Ib, XX },
  1400 + { "(bad)", XX, XX, XX },
1053 1401 },
1054 1402 /* GRP12 */
1055 1403 {
1056   - { "(bad)" },
1057   - { "(bad)" },
1058   - { "psrlq", MS, Ib },
1059   - { "(bad)" },
1060   - { "(bad)" },
1061   - { "(bad)" },
1062   - { "psllq", MS, Ib },
1063   - { "(bad)" },
  1404 + { "(bad)", XX, XX, XX },
  1405 + { "(bad)", XX, XX, XX },
  1406 + { "psrlq", MS, Ib, XX },
  1407 + { "psrldq", MS, Ib, XX },
  1408 + { "(bad)", XX, XX, XX },
  1409 + { "(bad)", XX, XX, XX },
  1410 + { "psllq", MS, Ib, XX },
  1411 + { "pslldq", MS, Ib, XX },
  1412 + },
  1413 + /* GRP13 */
  1414 + {
  1415 + { "fxsave", Ev, XX, XX },
  1416 + { "fxrstor", Ev, XX, XX },
  1417 + { "ldmxcsr", Ev, XX, XX },
  1418 + { "stmxcsr", Ev, XX, XX },
  1419 + { "(bad)", XX, XX, XX },
  1420 + { "lfence", None, XX, XX },
  1421 + { "mfence", None, XX, XX },
  1422 + { "sfence", None, XX, XX },
  1423 + /* FIXME: the sfence with memory operand is clflush! */
  1424 + },
  1425 + /* GRP14 */
  1426 + {
  1427 + { "prefetchnta", Ev, XX, XX },
  1428 + { "prefetcht0", Ev, XX, XX },
  1429 + { "prefetcht1", Ev, XX, XX },
  1430 + { "prefetcht2", Ev, XX, XX },
  1431 + { "(bad)", XX, XX, XX },
  1432 + { "(bad)", XX, XX, XX },
  1433 + { "(bad)", XX, XX, XX },
  1434 + { "(bad)", XX, XX, XX },
  1435 + },
  1436 + /* GRPAMD */
  1437 + {
  1438 + { "prefetch", Eb, XX, XX },
  1439 + { "prefetchw", Eb, XX, XX },
  1440 + { "(bad)", XX, XX, XX },
  1441 + { "(bad)", XX, XX, XX },
  1442 + { "(bad)", XX, XX, XX },
  1443 + { "(bad)", XX, XX, XX },
  1444 + { "(bad)", XX, XX, XX },
  1445 + { "(bad)", XX, XX, XX },
1064 1446 }
1065 1447 };
1066 1448  
1067   -#define PREFIX_REPZ 1
1068   -#define PREFIX_REPNZ 2
1069   -#define PREFIX_LOCK 4
1070   -#define PREFIX_CS 8
1071   -#define PREFIX_SS 0x10
1072   -#define PREFIX_DS 0x20
1073   -#define PREFIX_ES 0x40
1074   -#define PREFIX_FS 0x80
1075   -#define PREFIX_GS 0x100
1076   -#define PREFIX_DATA 0x200
1077   -#define PREFIX_ADR 0x400
1078   -#define PREFIX_FWAIT 0x800
  1449 +static const struct dis386 prefix_user_table[][4] = {
  1450 + /* PREGRP0 */
  1451 + {
  1452 + { "addps", XM, EX, XX },
  1453 + { "addss", XM, EX, XX },
  1454 + { "addpd", XM, EX, XX },
  1455 + { "addsd", XM, EX, XX },
  1456 + },
  1457 + /* PREGRP1 */
  1458 + {
  1459 + { "", XM, EX, OPSIMD }, /* See OP_SIMD_SUFFIX. */
  1460 + { "", XM, EX, OPSIMD },
  1461 + { "", XM, EX, OPSIMD },
  1462 + { "", XM, EX, OPSIMD },
  1463 + },
  1464 + /* PREGRP2 */
  1465 + {
  1466 + { "cvtpi2ps", XM, EM, XX },
  1467 + { "cvtsi2ssY", XM, Ev, XX },
  1468 + { "cvtpi2pd", XM, EM, XX },
  1469 + { "cvtsi2sdY", XM, Ev, XX },
  1470 + },
  1471 + /* PREGRP3 */
  1472 + {
  1473 + { "cvtps2pi", MX, EX, XX },
  1474 + { "cvtss2siY", Gv, EX, XX },
  1475 + { "cvtpd2pi", MX, EX, XX },
  1476 + { "cvtsd2siY", Gv, EX, XX },
  1477 + },
  1478 + /* PREGRP4 */
  1479 + {
  1480 + { "cvttps2pi", MX, EX, XX },
  1481 + { "cvttss2siY", Gv, EX, XX },
  1482 + { "cvttpd2pi", MX, EX, XX },
  1483 + { "cvttsd2siY", Gv, EX, XX },
  1484 + },
  1485 + /* PREGRP5 */
  1486 + {
  1487 + { "divps", XM, EX, XX },
  1488 + { "divss", XM, EX, XX },
  1489 + { "divpd", XM, EX, XX },
  1490 + { "divsd", XM, EX, XX },
  1491 + },
  1492 + /* PREGRP6 */
  1493 + {
  1494 + { "maxps", XM, EX, XX },
  1495 + { "maxss", XM, EX, XX },
  1496 + { "maxpd", XM, EX, XX },
  1497 + { "maxsd", XM, EX, XX },
  1498 + },
  1499 + /* PREGRP7 */
  1500 + {
  1501 + { "minps", XM, EX, XX },
  1502 + { "minss", XM, EX, XX },
  1503 + { "minpd", XM, EX, XX },
  1504 + { "minsd", XM, EX, XX },
  1505 + },
  1506 + /* PREGRP8 */
  1507 + {
  1508 + { "movups", XM, EX, XX },
  1509 + { "movss", XM, EX, XX },
  1510 + { "movupd", XM, EX, XX },
  1511 + { "movsd", XM, EX, XX },
  1512 + },
  1513 + /* PREGRP9 */
  1514 + {
  1515 + { "movups", EX, XM, XX },
  1516 + { "movss", EX, XM, XX },
  1517 + { "movupd", EX, XM, XX },
  1518 + { "movsd", EX, XM, XX },
  1519 + },
  1520 + /* PREGRP10 */
  1521 + {
  1522 + { "mulps", XM, EX, XX },
  1523 + { "mulss", XM, EX, XX },
  1524 + { "mulpd", XM, EX, XX },
  1525 + { "mulsd", XM, EX, XX },
  1526 + },
  1527 + /* PREGRP11 */
  1528 + {
  1529 + { "rcpps", XM, EX, XX },
  1530 + { "rcpss", XM, EX, XX },
  1531 + { "(bad)", XM, EX, XX },
  1532 + { "(bad)", XM, EX, XX },
  1533 + },
  1534 + /* PREGRP12 */
  1535 + {
  1536 + { "rsqrtps", XM, EX, XX },
  1537 + { "rsqrtss", XM, EX, XX },
  1538 + { "(bad)", XM, EX, XX },
  1539 + { "(bad)", XM, EX, XX },
  1540 + },
  1541 + /* PREGRP13 */
  1542 + {
  1543 + { "sqrtps", XM, EX, XX },
  1544 + { "sqrtss", XM, EX, XX },
  1545 + { "sqrtpd", XM, EX, XX },
  1546 + { "sqrtsd", XM, EX, XX },
  1547 + },
  1548 + /* PREGRP14 */
  1549 + {
  1550 + { "subps", XM, EX, XX },
  1551 + { "subss", XM, EX, XX },
  1552 + { "subpd", XM, EX, XX },
  1553 + { "subsd", XM, EX, XX },
  1554 + },
  1555 + /* PREGRP15 */
  1556 + {
  1557 + { "(bad)", XM, EX, XX },
  1558 + { "cvtdq2pd", XM, EX, XX },
  1559 + { "cvttpd2dq", XM, EX, XX },
  1560 + { "cvtpd2dq", XM, EX, XX },
  1561 + },
  1562 + /* PREGRP16 */
  1563 + {
  1564 + { "cvtdq2ps", XM, EX, XX },
  1565 + { "cvttps2dq",XM, EX, XX },
  1566 + { "cvtps2dq",XM, EX, XX },
  1567 + { "(bad)", XM, EX, XX },
  1568 + },
  1569 + /* PREGRP17 */
  1570 + {
  1571 + { "cvtps2pd", XM, EX, XX },
  1572 + { "cvtss2sd", XM, EX, XX },
  1573 + { "cvtpd2ps", XM, EX, XX },
  1574 + { "cvtsd2ss", XM, EX, XX },
  1575 + },
  1576 + /* PREGRP18 */
  1577 + {
  1578 + { "maskmovq", MX, MS, XX },
  1579 + { "(bad)", XM, EX, XX },
  1580 + { "maskmovdqu", XM, EX, XX },
  1581 + { "(bad)", XM, EX, XX },
  1582 + },
  1583 + /* PREGRP19 */
  1584 + {
  1585 + { "movq", MX, EM, XX },
  1586 + { "movdqu", XM, EX, XX },
  1587 + { "movdqa", XM, EX, XX },
  1588 + { "(bad)", XM, EX, XX },
  1589 + },
  1590 + /* PREGRP20 */
  1591 + {
  1592 + { "movq", EM, MX, XX },
  1593 + { "movdqu", EX, XM, XX },
  1594 + { "movdqa", EX, XM, XX },
  1595 + { "(bad)", EX, XM, XX },
  1596 + },
  1597 + /* PREGRP21 */
  1598 + {
  1599 + { "(bad)", EX, XM, XX },
  1600 + { "movq2dq", XM, MS, XX },
  1601 + { "movq", EX, XM, XX },
  1602 + { "movdq2q", MX, XS, XX },
  1603 + },
  1604 + /* PREGRP22 */
  1605 + {
  1606 + { "pshufw", MX, EM, Ib },
  1607 + { "pshufhw", XM, EX, Ib },
  1608 + { "pshufd", XM, EX, Ib },
  1609 + { "pshuflw", XM, EX, Ib },
  1610 + },
  1611 + /* PREGRP23 */
  1612 + {
  1613 + { "movd", Ed, MX, XX },
  1614 + { "movq", XM, EX, XX },
  1615 + { "movd", Ed, XM, XX },
  1616 + { "(bad)", Ed, XM, XX },
  1617 + },
  1618 + /* PREGRP24 */
  1619 + {
  1620 + { "(bad)", MX, EX, XX },
  1621 + { "(bad)", XM, EX, XX },
  1622 + { "punpckhqdq", XM, EX, XX },
  1623 + { "(bad)", XM, EX, XX },
  1624 + },
  1625 + /* PREGRP25 */
  1626 + {
  1627 + { "movntq", Ev, MX, XX },
  1628 + { "(bad)", Ev, XM, XX },
  1629 + { "movntdq", Ev, XM, XX },
  1630 + { "(bad)", Ev, XM, XX },
  1631 + },
  1632 + /* PREGRP26 */
  1633 + {
  1634 + { "(bad)", MX, EX, XX },
  1635 + { "(bad)", XM, EX, XX },
  1636 + { "punpcklqdq", XM, EX, XX },
  1637 + { "(bad)", XM, EX, XX },
  1638 + },
  1639 +};
1079 1640  
1080   -static int prefixes;
  1641 +static const struct dis386 x86_64_table[][2] = {
  1642 + {
  1643 + { "arpl", Ew, Gw, XX },
  1644 + { "movs{||lq|xd}", Gv, Ed, XX },
  1645 + },
  1646 +};
  1647 +
  1648 +#define INTERNAL_DISASSEMBLER_ERROR _("<internal disassembler error>")
1081 1649  
1082 1650 static void
1083 1651 ckprefix ()
1084 1652 {
  1653 + int newrex;
  1654 + rex = 0;
1085 1655 prefixes = 0;
  1656 + used_prefixes = 0;
  1657 + rex_used = 0;
1086 1658 while (1)
1087 1659 {
1088 1660 FETCH_DATA (the_info, codep + 1);
  1661 + newrex = 0;
1089 1662 switch (*codep)
1090 1663 {
  1664 + /* REX prefixes family. */
  1665 + case 0x40:
  1666 + case 0x41:
  1667 + case 0x42:
  1668 + case 0x43:
  1669 + case 0x44:
  1670 + case 0x45:
  1671 + case 0x46:
  1672 + case 0x47:
  1673 + case 0x48:
  1674 + case 0x49:
  1675 + case 0x4a:
  1676 + case 0x4b:
  1677 + case 0x4c:
  1678 + case 0x4d:
  1679 + case 0x4e:
  1680 + case 0x4f:
  1681 + if (mode_64bit)
  1682 + newrex = *codep;
  1683 + else
  1684 + return;
  1685 + break;
1091 1686 case 0xf3:
1092 1687 prefixes |= PREFIX_REPZ;
1093 1688 break;
... ... @@ -1119,22 +1714,114 @@ ckprefix ()
1119 1714 prefixes |= PREFIX_DATA;
1120 1715 break;
1121 1716 case 0x67:
1122   - prefixes |= PREFIX_ADR;
  1717 + prefixes |= PREFIX_ADDR;
1123 1718 break;
1124   - case 0x9b:
1125   - prefixes |= PREFIX_FWAIT;
  1719 + case FWAIT_OPCODE:
  1720 + /* fwait is really an instruction. If there are prefixes
  1721 + before the fwait, they belong to the fwait, *not* to the
  1722 + following instruction. */
  1723 + if (prefixes)
  1724 + {
  1725 + prefixes |= PREFIX_FWAIT;
  1726 + codep++;
  1727 + return;
  1728 + }
  1729 + prefixes = PREFIX_FWAIT;
1126 1730 break;
1127 1731 default:
1128 1732 return;
1129 1733 }
  1734 + /* Rex is ignored when followed by another prefix. */
  1735 + if (rex)
  1736 + {
  1737 + oappend (prefix_name (rex, 0));
  1738 + oappend (" ");
  1739 + }
  1740 + rex = newrex;
1130 1741 codep++;
1131 1742 }
1132 1743 }
1133 1744  
1134   -static char op1out[100], op2out[100], op3out[100];
1135   -static int op_address[3], op_ad, op_index[3];
1136   -static int start_pc;
  1745 +/* Return the name of the prefix byte PREF, or NULL if PREF is not a
  1746 + prefix byte. */
  1747 +
  1748 +static const char *
  1749 +prefix_name (pref, sizeflag)
  1750 + int pref;
  1751 + int sizeflag;
  1752 +{
  1753 + switch (pref)
  1754 + {
  1755 + /* REX prefixes family. */
  1756 + case 0x40:
  1757 + return "rex";
  1758 + case 0x41:
  1759 + return "rexZ";
  1760 + case 0x42:
  1761 + return "rexY";
  1762 + case 0x43:
  1763 + return "rexYZ";
  1764 + case 0x44:
  1765 + return "rexX";
  1766 + case 0x45:
  1767 + return "rexXZ";
  1768 + case 0x46:
  1769 + return "rexXY";
  1770 + case 0x47:
  1771 + return "rexXYZ";
  1772 + case 0x48:
  1773 + return "rex64";
  1774 + case 0x49:
  1775 + return "rex64Z";
  1776 + case 0x4a:
  1777 + return "rex64Y";
  1778 + case 0x4b:
  1779 + return "rex64YZ";
  1780 + case 0x4c:
  1781 + return "rex64X";
  1782 + case 0x4d:
  1783 + return "rex64XZ";
  1784 + case 0x4e:
  1785 + return "rex64XY";
  1786 + case 0x4f:
  1787 + return "rex64XYZ";
  1788 + case 0xf3:
  1789 + return "repz";
  1790 + case 0xf2:
  1791 + return "repnz";
  1792 + case 0xf0:
  1793 + return "lock";
  1794 + case 0x2e:
  1795 + return "cs";
  1796 + case 0x36:
  1797 + return "ss";
  1798 + case 0x3e:
  1799 + return "ds";
  1800 + case 0x26:
  1801 + return "es";
  1802 + case 0x64:
  1803 + return "fs";
  1804 + case 0x65:
  1805 + return "gs";
  1806 + case 0x66:
  1807 + return (sizeflag & DFLAG) ? "data16" : "data32";
  1808 + case 0x67:
  1809 + if (mode_64bit)
  1810 + return (sizeflag & AFLAG) ? "addr32" : "addr64";
  1811 + else
  1812 + return ((sizeflag & AFLAG) && !mode_64bit) ? "addr16" : "addr32";
  1813 + case FWAIT_OPCODE:
  1814 + return "fwait";
  1815 + default:
  1816 + return NULL;
  1817 + }
  1818 +}
1137 1819  
  1820 +static char op1out[100], op2out[100], op3out[100];
  1821 +static int op_ad, op_index[3];
  1822 +static bfd_vma op_address[3];
  1823 +static bfd_vma op_riprel[3];
  1824 +static bfd_vma start_pc;
1138 1825  
1139 1826 /*
1140 1827 * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
... ... @@ -1145,48 +1832,160 @@ static int start_pc;
1145 1832 * The function returns the length of this instruction in bytes.
1146 1833 */
1147 1834  
1148   -int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
1149   - int dflag));
  1835 +static char intel_syntax;
  1836 +static char open_char;
  1837 +static char close_char;
  1838 +static char separator_char;
  1839 +static char scale_char;
  1840 +
  1841 +/* Here for backwards compatibility. When gdb stops using
  1842 + print_insn_i386_att and print_insn_i386_intel these functions can
  1843 + disappear, and print_insn_i386 be merged into print_insn. */
1150 1844 int
1151   -print_insn_i386 (pc, info)
  1845 +print_insn_i386_att (pc, info)
1152 1846 bfd_vma pc;
1153 1847 disassemble_info *info;
1154 1848 {
1155   - if (info->mach == bfd_mach_i386_i386)
1156   - return print_insn_x86 (pc, info, 1, 1);
1157   - else if (info->mach == bfd_mach_i386_i8086)
1158   - return print_insn_x86 (pc, info, 0, 0);
1159   - else
1160   - abort ();
  1849 + intel_syntax = 0;
  1850 +
  1851 + return print_insn (pc, info);
  1852 +}
  1853 +
  1854 +int
  1855 +print_insn_i386_intel (pc, info)
  1856 + bfd_vma pc;
  1857 + disassemble_info *info;
  1858 +{
  1859 + intel_syntax = 1;
  1860 +
  1861 + return print_insn (pc, info);
1161 1862 }
1162 1863  
1163 1864 int
1164   -print_insn_x86 (pc, info, aflag, dflag)
  1865 +print_insn_i386 (pc, info)
  1866 + bfd_vma pc;
  1867 + disassemble_info *info;
  1868 +{
  1869 + intel_syntax = -1;
  1870 +
  1871 + return print_insn (pc, info);
  1872 +}
  1873 +
  1874 +static int
  1875 +print_insn (pc, info)
1165 1876 bfd_vma pc;
1166 1877 disassemble_info *info;
1167   - int volatile aflag;
1168   - int volatile dflag;
1169 1878 {
1170   - struct dis386 *dp;
  1879 + const struct dis386 *dp;
1171 1880 int i;
1172   - int enter_instruction;
  1881 + int two_source_ops;
1173 1882 char *first, *second, *third;
1174 1883 int needcomma;
1175   - unsigned char need_modrm;
1176   -
  1884 + unsigned char uses_SSE_prefix;
  1885 + int sizeflag;
  1886 + const char *p;
1177 1887 struct dis_private priv;
1178   - bfd_byte *inbuf = priv.the_buffer;
1179 1888  
1180   - /* The output looks better if we put 5 bytes on a line, since that
1181   - puts long word instructions on a single line. */
1182   - info->bytes_per_line = 5;
  1889 + mode_64bit = (info->mach == bfd_mach_x86_64_intel_syntax
  1890 + || info->mach == bfd_mach_x86_64);
  1891 +
  1892 + if (intel_syntax == -1)
  1893 + intel_syntax = (info->mach == bfd_mach_i386_i386_intel_syntax
  1894 + || info->mach == bfd_mach_x86_64_intel_syntax);
  1895 +
  1896 + if (info->mach == bfd_mach_i386_i386
  1897 + || info->mach == bfd_mach_x86_64
  1898 + || info->mach == bfd_mach_i386_i386_intel_syntax
  1899 + || info->mach == bfd_mach_x86_64_intel_syntax)
  1900 + priv.orig_sizeflag = AFLAG | DFLAG;
  1901 + else if (info->mach == bfd_mach_i386_i8086)
  1902 + priv.orig_sizeflag = 0;
  1903 + else
  1904 + abort ();
  1905 +
  1906 + for (p = info->disassembler_options; p != NULL; )
  1907 + {
  1908 + if (strncmp (p, "x86-64", 6) == 0)
  1909 + {
  1910 + mode_64bit = 1;
  1911 + priv.orig_sizeflag = AFLAG | DFLAG;
  1912 + }
  1913 + else if (strncmp (p, "i386", 4) == 0)
  1914 + {
  1915 + mode_64bit = 0;
  1916 + priv.orig_sizeflag = AFLAG | DFLAG;
  1917 + }
  1918 + else if (strncmp (p, "i8086", 5) == 0)
  1919 + {
  1920 + mode_64bit = 0;
  1921 + priv.orig_sizeflag = 0;
  1922 + }
  1923 + else if (strncmp (p, "intel", 5) == 0)
  1924 + {
  1925 + intel_syntax = 1;
  1926 + }
  1927 + else if (strncmp (p, "att", 3) == 0)
  1928 + {
  1929 + intel_syntax = 0;
  1930 + }
  1931 + else if (strncmp (p, "addr", 4) == 0)
  1932 + {
  1933 + if (p[4] == '1' && p[5] == '6')
  1934 + priv.orig_sizeflag &= ~AFLAG;
  1935 + else if (p[4] == '3' && p[5] == '2')
  1936 + priv.orig_sizeflag |= AFLAG;
  1937 + }
  1938 + else if (strncmp (p, "data", 4) == 0)
  1939 + {
  1940 + if (p[4] == '1' && p[5] == '6')
  1941 + priv.orig_sizeflag &= ~DFLAG;
  1942 + else if (p[4] == '3' && p[5] == '2')
  1943 + priv.orig_sizeflag |= DFLAG;
  1944 + }
  1945 + else if (strncmp (p, "suffix", 6) == 0)
  1946 + priv.orig_sizeflag |= SUFFIX_ALWAYS;
  1947 +
  1948 + p = strchr (p, ',');
  1949 + if (p != NULL)
  1950 + p++;
  1951 + }
  1952 +
  1953 + if (intel_syntax)
  1954 + {
  1955 + names64 = intel_names64;
  1956 + names32 = intel_names32;
  1957 + names16 = intel_names16;
  1958 + names8 = intel_names8;
  1959 + names8rex = intel_names8rex;
  1960 + names_seg = intel_names_seg;
  1961 + index16 = intel_index16;
  1962 + open_char = '[';
  1963 + close_char = ']';
  1964 + separator_char = '+';
  1965 + scale_char = '*';
  1966 + }
  1967 + else
  1968 + {
  1969 + names64 = att_names64;
  1970 + names32 = att_names32;
  1971 + names16 = att_names16;
  1972 + names8 = att_names8;
  1973 + names8rex = att_names8rex;
  1974 + names_seg = att_names_seg;
  1975 + index16 = att_index16;
  1976 + open_char = '(';
  1977 + close_char = ')';
  1978 + separator_char = ',';
  1979 + scale_char = ',';
  1980 + }
  1981 +
  1982 + /* The output looks better if we put 7 bytes on a line, since that
  1983 + puts most long word instructions on a single line. */
  1984 + info->bytes_per_line = 7;
1183 1985  
1184 1986 info->private_data = (PTR) &priv;
1185 1987 priv.max_fetched = priv.the_buffer;
1186 1988 priv.insn_start = pc;
1187   - if (setjmp (priv.bailout) != 0)
1188   - /* Error return. */
1189   - return -1;
1190 1989  
1191 1990 obuf[0] = 0;
1192 1991 op1out[0] = 0;
... ... @@ -1197,59 +1996,116 @@ print_insn_x86 (pc, info, aflag, dflag)
1197 1996  
1198 1997 the_info = info;
1199 1998 start_pc = pc;
1200   - start_codep = inbuf;
1201   - codep = inbuf;
1202   -
  1999 + start_codep = priv.the_buffer;
  2000 + codep = priv.the_buffer;
  2001 +
  2002 + if (setjmp (priv.bailout) != 0)
  2003 + {
  2004 + const char *name;
  2005 +
  2006 + /* Getting here means we tried for data but didn't get it. That
  2007 + means we have an incomplete instruction of some sort. Just
  2008 + print the first byte as a prefix or a .byte pseudo-op. */
  2009 + if (codep > priv.the_buffer)
  2010 + {
  2011 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
  2012 + if (name != NULL)
  2013 + (*info->fprintf_func) (info->stream, "%s", name);
  2014 + else
  2015 + {
  2016 + /* Just print the first byte as a .byte instruction. */
  2017 + (*info->fprintf_func) (info->stream, ".byte 0x%x",
  2018 + (unsigned int) priv.the_buffer[0]);
  2019 + }
  2020 +
  2021 + return 1;
  2022 + }
  2023 +
  2024 + return -1;
  2025 + }
  2026 +
  2027 + obufp = obuf;
1203 2028 ckprefix ();
1204 2029  
  2030 + insn_codep = codep;
  2031 + sizeflag = priv.orig_sizeflag;
  2032 +
1205 2033 FETCH_DATA (info, codep + 1);
1206   - if (*codep == 0xc8)
1207   - enter_instruction = 1;
1208   - else
1209   - enter_instruction = 0;
1210   -
1211   - obufp = obuf;
1212   -
1213   - if (prefixes & PREFIX_REPZ)
1214   - oappend ("repz ");
1215   - if (prefixes & PREFIX_REPNZ)
1216   - oappend ("repnz ");
1217   - if (prefixes & PREFIX_LOCK)
1218   - oappend ("lock ");
1219   -
  2034 + two_source_ops = (*codep == 0x62) || (*codep == 0xc8);
  2035 +
1220 2036 if ((prefixes & PREFIX_FWAIT)
1221 2037 && ((*codep < 0xd8) || (*codep > 0xdf)))
1222 2038 {
1223   - /* fwait not followed by floating point instruction */
1224   - (*info->fprintf_func) (info->stream, "fwait");
1225   - return (1);
1226   - }
1227   -
1228   - if (prefixes & PREFIX_DATA)
1229   - dflag ^= 1;
1230   -
1231   - if (prefixes & PREFIX_ADR)
1232   - {
1233   - aflag ^= 1;
1234   - if (aflag)
1235   - oappend ("addr32 ");
1236   - else
1237   - oappend ("addr16 ");
  2039 + const char *name;
  2040 +
  2041 + /* fwait not followed by floating point instruction. Print the
  2042 + first prefix, which is probably fwait itself. */
  2043 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
  2044 + if (name == NULL)
  2045 + name = INTERNAL_DISASSEMBLER_ERROR;
  2046 + (*info->fprintf_func) (info->stream, "%s", name);
  2047 + return 1;
1238 2048 }
1239   -
  2049 +
1240 2050 if (*codep == 0x0f)
1241 2051 {
1242 2052 FETCH_DATA (info, codep + 2);
1243 2053 dp = &dis386_twobyte[*++codep];
1244 2054 need_modrm = twobyte_has_modrm[*codep];
  2055 + uses_SSE_prefix = twobyte_uses_SSE_prefix[*codep];
1245 2056 }
1246 2057 else
1247 2058 {
1248 2059 dp = &dis386[*codep];
1249 2060 need_modrm = onebyte_has_modrm[*codep];
  2061 + uses_SSE_prefix = 0;
1250 2062 }
1251 2063 codep++;
1252 2064  
  2065 + if (!uses_SSE_prefix && (prefixes & PREFIX_REPZ))
  2066 + {
  2067 + oappend ("repz ");
  2068 + used_prefixes |= PREFIX_REPZ;
  2069 + }
  2070 + if (!uses_SSE_prefix && (prefixes & PREFIX_REPNZ))
  2071 + {
  2072 + oappend ("repnz ");
  2073 + used_prefixes |= PREFIX_REPNZ;
  2074 + }
  2075 + if (prefixes & PREFIX_LOCK)
  2076 + {
  2077 + oappend ("lock ");
  2078 + used_prefixes |= PREFIX_LOCK;
  2079 + }
  2080 +
  2081 + if (prefixes & PREFIX_ADDR)
  2082 + {
  2083 + sizeflag ^= AFLAG;
  2084 + if (dp->bytemode3 != loop_jcxz_mode || intel_syntax)
  2085 + {
  2086 + if ((sizeflag & AFLAG) || mode_64bit)
  2087 + oappend ("addr32 ");
  2088 + else
  2089 + oappend ("addr16 ");
  2090 + used_prefixes |= PREFIX_ADDR;
  2091 + }
  2092 + }
  2093 +
  2094 + if (!uses_SSE_prefix && (prefixes & PREFIX_DATA))
  2095 + {
  2096 + sizeflag ^= DFLAG;
  2097 + if (dp->bytemode3 == cond_jump_mode
  2098 + && dp->bytemode1 == v_mode
  2099 + && !intel_syntax)
  2100 + {
  2101 + if (sizeflag & DFLAG)
  2102 + oappend ("data32 ");
  2103 + else
  2104 + oappend ("data16 ");
  2105 + used_prefixes |= PREFIX_DATA;
  2106 + }
  2107 + }
  2108 +
1253 2109 if (need_modrm)
1254 2110 {
1255 2111 FETCH_DATA (info, codep + 1);
... ... @@ -1260,42 +2116,100 @@ print_insn_x86 (pc, info, aflag, dflag)
1260 2116  
1261 2117 if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
1262 2118 {
1263   - dofloat (aflag, dflag);
  2119 + dofloat (sizeflag);
1264 2120 }
1265 2121 else
1266 2122 {
  2123 + int index;
1267 2124 if (dp->name == NULL)
1268   - dp = &grps[dp->bytemode1][reg];
1269   -
1270   - putop (dp->name, aflag, dflag);
1271   -
1272   - obufp = op1out;
1273   - op_ad = 2;
1274   - if (dp->op1)
1275   - (*dp->op1)(dp->bytemode1, aflag, dflag);
1276   -
1277   - obufp = op2out;
1278   - op_ad = 1;
1279   - if (dp->op2)
1280   - (*dp->op2)(dp->bytemode2, aflag, dflag);
1281   -
1282   - obufp = op3out;
1283   - op_ad = 0;
1284   - if (dp->op3)
1285   - (*dp->op3)(dp->bytemode3, aflag, dflag);
  2125 + {
  2126 + switch (dp->bytemode1)
  2127 + {
  2128 + case USE_GROUPS:
  2129 + dp = &grps[dp->bytemode2][reg];
  2130 + break;
  2131 +
  2132 + case USE_PREFIX_USER_TABLE:
  2133 + index = 0;
  2134 + used_prefixes |= (prefixes & PREFIX_REPZ);
  2135 + if (prefixes & PREFIX_REPZ)
  2136 + index = 1;
  2137 + else
  2138 + {
  2139 + used_prefixes |= (prefixes & PREFIX_DATA);
  2140 + if (prefixes & PREFIX_DATA)
  2141 + index = 2;
  2142 + else
  2143 + {
  2144 + used_prefixes |= (prefixes & PREFIX_REPNZ);
  2145 + if (prefixes & PREFIX_REPNZ)
  2146 + index = 3;
  2147 + }
  2148 + }
  2149 + dp = &prefix_user_table[dp->bytemode2][index];
  2150 + break;
  2151 +
  2152 + case X86_64_SPECIAL:
  2153 + dp = &x86_64_table[dp->bytemode2][mode_64bit];
  2154 + break;
  2155 +
  2156 + default:
  2157 + oappend (INTERNAL_DISASSEMBLER_ERROR);
  2158 + break;
  2159 + }
  2160 + }
  2161 +
  2162 + if (putop (dp->name, sizeflag) == 0)
  2163 + {
  2164 + obufp = op1out;
  2165 + op_ad = 2;
  2166 + if (dp->op1)
  2167 + (*dp->op1) (dp->bytemode1, sizeflag);
  2168 +
  2169 + obufp = op2out;
  2170 + op_ad = 1;
  2171 + if (dp->op2)
  2172 + (*dp->op2) (dp->bytemode2, sizeflag);
  2173 +
  2174 + obufp = op3out;
  2175 + op_ad = 0;
  2176 + if (dp->op3)
  2177 + (*dp->op3) (dp->bytemode3, sizeflag);
  2178 + }
  2179 + }
  2180 +
  2181 + /* See if any prefixes were not used. If so, print the first one
  2182 + separately. If we don't do this, we'll wind up printing an
  2183 + instruction stream which does not precisely correspond to the
  2184 + bytes we are disassembling. */
  2185 + if ((prefixes & ~used_prefixes) != 0)
  2186 + {
  2187 + const char *name;
  2188 +
  2189 + name = prefix_name (priv.the_buffer[0], priv.orig_sizeflag);
  2190 + if (name == NULL)
  2191 + name = INTERNAL_DISASSEMBLER_ERROR;
  2192 + (*info->fprintf_func) (info->stream, "%s", name);
  2193 + return 1;
  2194 + }
  2195 + if (rex & ~rex_used)
  2196 + {
  2197 + const char *name;
  2198 + name = prefix_name (rex | 0x40, priv.orig_sizeflag);
  2199 + if (name == NULL)
  2200 + name = INTERNAL_DISASSEMBLER_ERROR;
  2201 + (*info->fprintf_func) (info->stream, "%s ", name);
1286 2202 }
1287   -
  2203 +
1288 2204 obufp = obuf + strlen (obuf);
1289 2205 for (i = strlen (obuf); i < 6; i++)
1290 2206 oappend (" ");
1291 2207 oappend (" ");
1292 2208 (*info->fprintf_func) (info->stream, "%s", obuf);
1293   -
1294   - /* enter instruction is printed with operands in the
1295   - * same order as the intel book; everything else
1296   - * is printed in reverse order
1297   - */
1298   - if (enter_instruction)
  2209 +
  2210 + /* The enter and bound instructions are printed with operands in the same
  2211 + order as the intel book; everything else is printed in reverse order. */
  2212 + if (intel_syntax || two_source_ops)
1299 2213 {
1300 2214 first = op1out;
1301 2215 second = op2out;
... ... @@ -1313,8 +2227,8 @@ print_insn_x86 (pc, info, aflag, dflag)
1313 2227 needcomma = 0;
1314 2228 if (*first)
1315 2229 {
1316   - if (op_index[0] != -1)
1317   - (*info->print_address_func) (op_address[op_index[0]], info);
  2230 + if (op_index[0] != -1 && !op_riprel[0])
  2231 + (*info->print_address_func) ((bfd_vma) op_address[op_index[0]], info);
1318 2232 else
1319 2233 (*info->fprintf_func) (info->stream, "%s", first);
1320 2234 needcomma = 1;
... ... @@ -1323,8 +2237,8 @@ print_insn_x86 (pc, info, aflag, dflag)
1323 2237 {
1324 2238 if (needcomma)
1325 2239 (*info->fprintf_func) (info->stream, ",");
1326   - if (op_index[1] != -1)
1327   - (*info->print_address_func) (op_address[op_index[1]], info);
  2240 + if (op_index[1] != -1 && !op_riprel[1])
  2241 + (*info->print_address_func) ((bfd_vma) op_address[op_index[1]], info);
1328 2242 else
1329 2243 (*info->fprintf_func) (info->stream, "%s", second);
1330 2244 needcomma = 1;
... ... @@ -1333,65 +2247,72 @@ print_insn_x86 (pc, info, aflag, dflag)
1333 2247 {
1334 2248 if (needcomma)
1335 2249 (*info->fprintf_func) (info->stream, ",");
1336   - if (op_index[2] != -1)
1337   - (*info->print_address_func) (op_address[op_index[2]], info);
  2250 + if (op_index[2] != -1 && !op_riprel[2])
  2251 + (*info->print_address_func) ((bfd_vma) op_address[op_index[2]], info);
1338 2252 else
1339 2253 (*info->fprintf_func) (info->stream, "%s", third);
1340 2254 }
1341   - return (codep - inbuf);
  2255 + for (i = 0; i < 3; i++)
  2256 + if (op_index[i] != -1 && op_riprel[i])
  2257 + {
  2258 + (*info->fprintf_func) (info->stream, " # ");
  2259 + (*info->print_address_func) ((bfd_vma) (start_pc + codep - start_codep
  2260 + + op_address[op_index[i]]), info);
  2261 + }
  2262 + return codep - priv.the_buffer;
1342 2263 }
1343 2264  
1344   -static char *float_mem[] = {
  2265 +static const char *float_mem[] = {
1345 2266 /* d8 */
1346   - "fadds",
1347   - "fmuls",
1348   - "fcoms",
1349   - "fcomps",
1350   - "fsubs",
1351   - "fsubrs",
1352   - "fdivs",
1353   - "fdivrs",
  2267 + "fadd{s||s|}",
  2268 + "fmul{s||s|}",
  2269 + "fcom{s||s|}",
  2270 + "fcomp{s||s|}",
  2271 + "fsub{s||s|}",
  2272 + "fsubr{s||s|}",
  2273 + "fdiv{s||s|}",
  2274 + "fdivr{s||s|}",
1354 2275 /* d9 */
1355   - "flds",
  2276 + "fld{s||s|}",
1356 2277 "(bad)",
1357   - "fsts",
1358   - "fstps",
  2278 + "fst{s||s|}",
  2279 + "fstp{s||s|}",
1359 2280 "fldenv",
1360 2281 "fldcw",
1361 2282 "fNstenv",
1362 2283 "fNstcw",
1363 2284 /* da */
1364   - "fiaddl",
1365   - "fimull",
1366   - "ficoml",
1367   - "ficompl",
1368   - "fisubl",
1369   - "fisubrl",
1370   - "fidivl",
1371   - "fidivrl",
  2285 + "fiadd{l||l|}",
  2286 + "fimul{l||l|}",
  2287 + "ficom{l||l|}",
  2288 + "ficomp{l||l|}",
  2289 + "fisub{l||l|}",
  2290 + "fisubr{l||l|}",
  2291 + "fidiv{l||l|}",
  2292 + "fidivr{l||l|}",
1372 2293 /* db */
1373   - "fildl",
  2294 + "fild{l||l|}",
1374 2295 "(bad)",
1375   - "fistl",
1376   - "fistpl",
  2296 + "fist{l||l|}",
  2297 + "fistp{l||l|}",
1377 2298 "(bad)",
1378   - "fldt",
  2299 + "fld{t||t|}",
1379 2300 "(bad)",
1380   - "fstpt",
  2301 + "fstp{t||t|}",
1381 2302 /* dc */
1382   - "faddl",
1383   - "fmull",
1384   - "fcoml",
1385   - "fcompl",
1386   - "fsubl",
1387   - "fsubrl",
1388   - "fdivl",
1389   - "fdivrl",
  2303 + "fadd{l||l|}",
  2304 + "fmul{l||l|}",
  2305 + "fcom{l||l|}",
  2306 + "fcomp{l||l|}",
  2307 + "fsub{l||l|}",
  2308 + "fsubr{l||l|}",
  2309 + "fdiv{l||l|}",
  2310 + "fdivr{l||l|}",
1390 2311 /* dd */
1391   - "fldl",
  2312 + "fld{l||l|}",
1392 2313 "(bad)",
1393   - "fstl",
1394   - "fstpl",
  2314 + "fst{l||l|}",
  2315 + "fstp{l||l|}",
1395 2316 "frstor",
1396 2317 "(bad)",
1397 2318 "fNsave",
... ... @@ -1411,7 +2332,7 @@ static char *float_mem[] = {
1411 2332 "fist",
1412 2333 "fistp",
1413 2334 "fbld",
1414   - "fildll",
  2335 + "fild{ll||ll|}",
1415 2336 "fbstp",
1416 2337 "fistpll",
1417 2338 };
... ... @@ -1419,34 +2340,34 @@ static char *float_mem[] = {
1419 2340 #define ST OP_ST, 0
1420 2341 #define STi OP_STi, 0
1421 2342  
1422   -#define FGRPd9_2 NULL, NULL, 0
1423   -#define FGRPd9_4 NULL, NULL, 1
1424   -#define FGRPd9_5 NULL, NULL, 2
1425   -#define FGRPd9_6 NULL, NULL, 3
1426   -#define FGRPd9_7 NULL, NULL, 4
1427   -#define FGRPda_5 NULL, NULL, 5
1428   -#define FGRPdb_4 NULL, NULL, 6
1429   -#define FGRPde_3 NULL, NULL, 7
1430   -#define FGRPdf_4 NULL, NULL, 8
1431   -
1432   -static struct dis386 float_reg[][8] = {
  2343 +#define FGRPd9_2 NULL, NULL, 0, NULL, 0, NULL, 0
  2344 +#define FGRPd9_4 NULL, NULL, 1, NULL, 0, NULL, 0
  2345 +#define FGRPd9_5 NULL, NULL, 2, NULL, 0, NULL, 0
  2346 +#define FGRPd9_6 NULL, NULL, 3, NULL, 0, NULL, 0
  2347 +#define FGRPd9_7 NULL, NULL, 4, NULL, 0, NULL, 0
  2348 +#define FGRPda_5 NULL, NULL, 5, NULL, 0, NULL, 0
  2349 +#define FGRPdb_4 NULL, NULL, 6, NULL, 0, NULL, 0
  2350 +#define FGRPde_3 NULL, NULL, 7, NULL, 0, NULL, 0
  2351 +#define FGRPdf_4 NULL, NULL, 8, NULL, 0, NULL, 0
  2352 +
  2353 +static const struct dis386 float_reg[][8] = {
1433 2354 /* d8 */
1434 2355 {
1435   - { "fadd", ST, STi },
1436   - { "fmul", ST, STi },
1437   - { "fcom", STi },
1438   - { "fcomp", STi },
1439   - { "fsub", ST, STi },
1440   - { "fsubr", ST, STi },
1441   - { "fdiv", ST, STi },
1442   - { "fdivr", ST, STi },
  2356 + { "fadd", ST, STi, XX },
  2357 + { "fmul", ST, STi, XX },
  2358 + { "fcom", STi, XX, XX },
  2359 + { "fcomp", STi, XX, XX },
  2360 + { "fsub", ST, STi, XX },
  2361 + { "fsubr", ST, STi, XX },
  2362 + { "fdiv", ST, STi, XX },
  2363 + { "fdivr", ST, STi, XX },
1443 2364 },
1444 2365 /* d9 */
1445 2366 {
1446   - { "fld", STi },
1447   - { "fxch", STi },
  2367 + { "fld", STi, XX, XX },
  2368 + { "fxch", STi, XX, XX },
1448 2369 { FGRPd9_2 },
1449   - { "(bad)" },
  2370 + { "(bad)", XX, XX, XX },
1450 2371 { FGRPd9_4 },
1451 2372 { FGRPd9_5 },
1452 2373 { FGRPd9_6 },
... ... @@ -1454,73 +2375,86 @@ static struct dis386 float_reg[][8] = {
1454 2375 },
1455 2376 /* da */
1456 2377 {
1457   - { "fcmovb", ST, STi },
1458   - { "fcmove", ST, STi },
1459   - { "fcmovbe",ST, STi },
1460   - { "fcmovu", ST, STi },
1461   - { "(bad)" },
  2378 + { "fcmovb", ST, STi, XX },
  2379 + { "fcmove", ST, STi, XX },
  2380 + { "fcmovbe",ST, STi, XX },
  2381 + { "fcmovu", ST, STi, XX },
  2382 + { "(bad)", XX, XX, XX },
1462 2383 { FGRPda_5 },
1463   - { "(bad)" },
1464   - { "(bad)" },
  2384 + { "(bad)", XX, XX, XX },
  2385 + { "(bad)", XX, XX, XX },
1465 2386 },
1466 2387 /* db */
1467 2388 {
1468   - { "fcmovnb",ST, STi },
1469   - { "fcmovne",ST, STi },
1470   - { "fcmovnbe",ST, STi },
1471   - { "fcmovnu",ST, STi },
  2389 + { "fcmovnb",ST, STi, XX },
  2390 + { "fcmovne",ST, STi, XX },
  2391 + { "fcmovnbe",ST, STi, XX },
  2392 + { "fcmovnu",ST, STi, XX },
1472 2393 { FGRPdb_4 },
1473   - { "fucomi", ST, STi },
1474   - { "fcomi", ST, STi },
1475   - { "(bad)" },
  2394 + { "fucomi", ST, STi, XX },
  2395 + { "fcomi", ST, STi, XX },
  2396 + { "(bad)", XX, XX, XX },
1476 2397 },
1477 2398 /* dc */
1478 2399 {
1479   - { "fadd", STi, ST },
1480   - { "fmul", STi, ST },
1481   - { "(bad)" },
1482   - { "(bad)" },
1483   - { "fsub", STi, ST },
1484   - { "fsubr", STi, ST },
1485   - { "fdiv", STi, ST },
1486   - { "fdivr", STi, ST },
  2400 + { "fadd", STi, ST, XX },
  2401 + { "fmul", STi, ST, XX },
  2402 + { "(bad)", XX, XX, XX },
  2403 + { "(bad)", XX, XX, XX },
  2404 +#if UNIXWARE_COMPAT
  2405 + { "fsub", STi, ST, XX },
  2406 + { "fsubr", STi, ST, XX },
  2407 + { "fdiv", STi, ST, XX },
  2408 + { "fdivr", STi, ST, XX },
  2409 +#else
  2410 + { "fsubr", STi, ST, XX },
  2411 + { "fsub", STi, ST, XX },
  2412 + { "fdivr", STi, ST, XX },
  2413 + { "fdiv", STi, ST, XX },
  2414 +#endif
1487 2415 },
1488 2416 /* dd */
1489 2417 {
1490   - { "ffree", STi },
1491   - { "(bad)" },
1492   - { "fst", STi },
1493   - { "fstp", STi },
1494   - { "fucom", STi },
1495   - { "fucomp", STi },
1496   - { "(bad)" },
1497   - { "(bad)" },
  2418 + { "ffree", STi, XX, XX },
  2419 + { "(bad)", XX, XX, XX },
  2420 + { "fst", STi, XX, XX },
  2421 + { "fstp", STi, XX, XX },
  2422 + { "fucom", STi, XX, XX },
  2423 + { "fucomp", STi, XX, XX },
  2424 + { "(bad)", XX, XX, XX },
  2425 + { "(bad)", XX, XX, XX },
1498 2426 },
1499 2427 /* de */
1500 2428 {
1501   - { "faddp", STi, ST },
1502   - { "fmulp", STi, ST },
1503   - { "(bad)" },
  2429 + { "faddp", STi, ST, XX },
  2430 + { "fmulp", STi, ST, XX },
  2431 + { "(bad)", XX, XX, XX },
1504 2432 { FGRPde_3 },
1505   - { "fsubp", STi, ST },
1506   - { "fsubrp", STi, ST },
1507   - { "fdivp", STi, ST },
1508   - { "fdivrp", STi, ST },
  2433 +#if UNIXWARE_COMPAT
  2434 + { "fsubp", STi, ST, XX },
  2435 + { "fsubrp", STi, ST, XX },
  2436 + { "fdivp", STi, ST, XX },
  2437 + { "fdivrp", STi, ST, XX },
  2438 +#else
  2439 + { "fsubrp", STi, ST, XX },
  2440 + { "fsubp", STi, ST, XX },
  2441 + { "fdivrp", STi, ST, XX },
  2442 + { "fdivp", STi, ST, XX },
  2443 +#endif
1509 2444 },
1510 2445 /* df */
1511 2446 {
1512   - { "(bad)" },
1513   - { "(bad)" },
1514   - { "(bad)" },
1515   - { "(bad)" },
  2447 + { "ffreep", STi, XX, XX },
  2448 + { "(bad)", XX, XX, XX },
  2449 + { "(bad)", XX, XX, XX },
  2450 + { "(bad)", XX, XX, XX },
1516 2451 { FGRPdf_4 },
1517   - { "fucomip",ST, STi },
1518   - { "fcomip", ST, STi },
1519   - { "(bad)" },
  2452 + { "fucomip",ST, STi, XX },
  2453 + { "fcomip", ST, STi, XX },
  2454 + { "(bad)", XX, XX, XX },
1520 2455 },
1521 2456 };
1522 2457  
1523   -
1524 2458 static char *fgrps[][8] = {
1525 2459 /* d9_2 0 */
1526 2460 {
... ... @@ -1570,79 +2504,78 @@ static char *fgrps[][8] = {
1570 2504 };
1571 2505  
1572 2506 static void
1573   -dofloat (aflag, dflag)
1574   - int aflag;
1575   - int dflag;
  2507 +dofloat (sizeflag)
  2508 + int sizeflag;
1576 2509 {
1577   - struct dis386 *dp;
  2510 + const struct dis386 *dp;
1578 2511 unsigned char floatop;
1579   -
  2512 +
1580 2513 floatop = codep[-1];
1581   -
  2514 +
1582 2515 if (mod != 3)
1583 2516 {
1584   - putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
  2517 + putop (float_mem[(floatop - 0xd8) * 8 + reg], sizeflag);
1585 2518 obufp = op1out;
1586   - OP_E (v_mode, aflag, dflag);
  2519 + if (floatop == 0xdb)
  2520 + OP_E (x_mode, sizeflag);
  2521 + else if (floatop == 0xdd)
  2522 + OP_E (d_mode, sizeflag);
  2523 + else
  2524 + OP_E (v_mode, sizeflag);
1587 2525 return;
1588 2526 }
  2527 + /* Skip mod/rm byte. */
  2528 + MODRM_CHECK;
1589 2529 codep++;
1590   -
  2530 +
1591 2531 dp = &float_reg[floatop - 0xd8][reg];
1592 2532 if (dp->name == NULL)
1593 2533 {
1594   - putop (fgrps[dp->bytemode1][rm], aflag, dflag);
1595   - /* instruction fnstsw is only one with strange arg */
1596   - if (floatop == 0xdf
1597   - && FETCH_DATA (the_info, codep + 1)
1598   - && *codep == 0xe0)
1599   - strcpy (op1out, "%eax");
  2534 + putop (fgrps[dp->bytemode1][rm], sizeflag);
  2535 +
  2536 + /* Instruction fnstsw is only one with strange arg. */
  2537 + if (floatop == 0xdf && codep[-1] == 0xe0)
  2538 + strcpy (op1out, names16[0]);
1600 2539 }
1601 2540 else
1602 2541 {
1603   - putop (dp->name, aflag, dflag);
  2542 + putop (dp->name, sizeflag);
  2543 +
1604 2544 obufp = op1out;
1605 2545 if (dp->op1)
1606   - (*dp->op1)(dp->bytemode1, aflag, dflag);
  2546 + (*dp->op1) (dp->bytemode1, sizeflag);
1607 2547 obufp = op2out;
1608 2548 if (dp->op2)
1609   - (*dp->op2)(dp->bytemode2, aflag, dflag);
  2549 + (*dp->op2) (dp->bytemode2, sizeflag);
1610 2550 }
1611 2551 }
1612 2552  
1613   -/* ARGSUSED */
1614   -static int
1615   -OP_ST (ignore, aflag, dflag)
1616   - int ignore;
1617   - int aflag;
1618   - int dflag;
  2553 +static void
  2554 +OP_ST (bytemode, sizeflag)
  2555 + int bytemode;
  2556 + int sizeflag;
1619 2557 {
1620 2558 oappend ("%st");
1621   - return (0);
1622 2559 }
1623 2560  
1624   -/* ARGSUSED */
1625   -static int
1626   -OP_STi (ignore, aflag, dflag)
1627   - int ignore;
1628   - int aflag;
1629   - int dflag;
  2561 +static void
  2562 +OP_STi (bytemode, sizeflag)
  2563 + int bytemode;
  2564 + int sizeflag;
1630 2565 {
1631 2566 sprintf (scratchbuf, "%%st(%d)", rm);
1632   - oappend (scratchbuf);
1633   - return (0);
  2567 + oappend (scratchbuf + intel_syntax);
1634 2568 }
1635 2569  
1636   -
1637   -/* capital letters in template are macros */
1638   -static void
1639   -putop (template, aflag, dflag)
1640   - char *template;
1641   - int aflag;
1642   - int dflag;
  2570 +/* Capital letters in template are macros. */
  2571 +static int
  2572 +putop (template, sizeflag)
  2573 + const char *template;
  2574 + int sizeflag;
1643 2575 {
1644   - char *p;
1645   -
  2576 + const char *p;
  2577 + int alt;
  2578 +
1646 2579 for (p = template; *p; p++)
1647 2580 {
1648 2581 switch (*p)
... ... @@ -1650,78 +2583,393 @@ putop (template, aflag, dflag)
1650 2583 default:
1651 2584 *obufp++ = *p;
1652 2585 break;
1653   - case 'C': /* For jcxz/jecxz */
1654   - if (aflag)
1655   - *obufp++ = 'e';
  2586 + case '{':
  2587 + alt = 0;
  2588 + if (intel_syntax)
  2589 + alt += 1;
  2590 + if (mode_64bit)
  2591 + alt += 2;
  2592 + while (alt != 0)
  2593 + {
  2594 + while (*++p != '|')
  2595 + {
  2596 + if (*p == '}')
  2597 + {
  2598 + /* Alternative not valid. */
  2599 + strcpy (obuf, "(bad)");
  2600 + obufp = obuf + 5;
  2601 + return 1;
  2602 + }
  2603 + else if (*p == '\0')
  2604 + abort ();
  2605 + }
  2606 + alt--;
  2607 + }
  2608 + break;
  2609 + case '|':
  2610 + while (*++p != '}')
  2611 + {
  2612 + if (*p == '\0')
  2613 + abort ();
  2614 + }
  2615 + break;
  2616 + case '}':
  2617 + break;
  2618 + case 'A':
  2619 + if (intel_syntax)
  2620 + break;
  2621 + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
  2622 + *obufp++ = 'b';
  2623 + break;
  2624 + case 'B':
  2625 + if (intel_syntax)
  2626 + break;
  2627 + if (sizeflag & SUFFIX_ALWAYS)
  2628 + *obufp++ = 'b';
  2629 + break;
  2630 + case 'E': /* For jcxz/jecxz */
  2631 + if (mode_64bit)
  2632 + {
  2633 + if (sizeflag & AFLAG)
  2634 + *obufp++ = 'r';
  2635 + else
  2636 + *obufp++ = 'e';
  2637 + }
  2638 + else
  2639 + if (sizeflag & AFLAG)
  2640 + *obufp++ = 'e';
  2641 + used_prefixes |= (prefixes & PREFIX_ADDR);
  2642 + break;
  2643 + case 'F':
  2644 + if (intel_syntax)
  2645 + break;
  2646 + if ((prefixes & PREFIX_ADDR) || (sizeflag & SUFFIX_ALWAYS))
  2647 + {
  2648 + if (sizeflag & AFLAG)
  2649 + *obufp++ = mode_64bit ? 'q' : 'l';
  2650 + else
  2651 + *obufp++ = mode_64bit ? 'l' : 'w';
  2652 + used_prefixes |= (prefixes & PREFIX_ADDR);
  2653 + }
  2654 + break;
  2655 + case 'H':
  2656 + if (intel_syntax)
  2657 + break;
  2658 + if ((prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_CS
  2659 + || (prefixes & (PREFIX_CS | PREFIX_DS)) == PREFIX_DS)
  2660 + {
  2661 + used_prefixes |= prefixes & (PREFIX_CS | PREFIX_DS);
  2662 + *obufp++ = ',';
  2663 + *obufp++ = 'p';
  2664 + if (prefixes & PREFIX_DS)
  2665 + *obufp++ = 't';
  2666 + else
  2667 + *obufp++ = 'n';
  2668 + }
  2669 + break;
  2670 + case 'L':
  2671 + if (intel_syntax)
  2672 + break;
  2673 + if (sizeflag & SUFFIX_ALWAYS)
  2674 + *obufp++ = 'l';
1656 2675 break;
1657 2676 case 'N':
1658 2677 if ((prefixes & PREFIX_FWAIT) == 0)
1659 2678 *obufp++ = 'n';
  2679 + else
  2680 + used_prefixes |= PREFIX_FWAIT;
  2681 + break;
  2682 + case 'O':
  2683 + USED_REX (REX_MODE64);
  2684 + if (rex & REX_MODE64)
  2685 + *obufp++ = 'o';
  2686 + else
  2687 + *obufp++ = 'd';
  2688 + break;
  2689 + case 'T':
  2690 + if (intel_syntax)
  2691 + break;
  2692 + if (mode_64bit)
  2693 + {
  2694 + *obufp++ = 'q';
  2695 + break;
  2696 + }
  2697 + /* Fall through. */
  2698 + case 'P':
  2699 + if (intel_syntax)
  2700 + break;
  2701 + if ((prefixes & PREFIX_DATA)
  2702 + || (rex & REX_MODE64)
  2703 + || (sizeflag & SUFFIX_ALWAYS))
  2704 + {
  2705 + USED_REX (REX_MODE64);
  2706 + if (rex & REX_MODE64)
  2707 + *obufp++ = 'q';
  2708 + else
  2709 + {
  2710 + if (sizeflag & DFLAG)
  2711 + *obufp++ = 'l';
  2712 + else
  2713 + *obufp++ = 'w';
  2714 + used_prefixes |= (prefixes & PREFIX_DATA);
  2715 + }
  2716 + }
  2717 + break;
  2718 + case 'U':
  2719 + if (intel_syntax)
  2720 + break;
  2721 + if (mode_64bit)
  2722 + {
  2723 + *obufp++ = 'q';
  2724 + break;
  2725 + }
  2726 + /* Fall through. */
  2727 + case 'Q':
  2728 + if (intel_syntax)
  2729 + break;
  2730 + USED_REX (REX_MODE64);
  2731 + if (mod != 3 || (sizeflag & SUFFIX_ALWAYS))
  2732 + {
  2733 + if (rex & REX_MODE64)
  2734 + *obufp++ = 'q';
  2735 + else
  2736 + {
  2737 + if (sizeflag & DFLAG)
  2738 + *obufp++ = 'l';
  2739 + else
  2740 + *obufp++ = 'w';
  2741 + used_prefixes |= (prefixes & PREFIX_DATA);
  2742 + }
  2743 + }
  2744 + break;
  2745 + case 'R':
  2746 + USED_REX (REX_MODE64);
  2747 + if (intel_syntax)
  2748 + {
  2749 + if (rex & REX_MODE64)
  2750 + {
  2751 + *obufp++ = 'q';
  2752 + *obufp++ = 't';
  2753 + }
  2754 + else if (sizeflag & DFLAG)
  2755 + {
  2756 + *obufp++ = 'd';
  2757 + *obufp++ = 'q';
  2758 + }
  2759 + else
  2760 + {
  2761 + *obufp++ = 'w';
  2762 + *obufp++ = 'd';
  2763 + }
  2764 + }
  2765 + else
  2766 + {
  2767 + if (rex & REX_MODE64)
  2768 + *obufp++ = 'q';
  2769 + else if (sizeflag & DFLAG)
  2770 + *obufp++ = 'l';
  2771 + else
  2772 + *obufp++ = 'w';
  2773 + }
  2774 + if (!(rex & REX_MODE64))
  2775 + used_prefixes |= (prefixes & PREFIX_DATA);
1660 2776 break;
1661 2777 case 'S':
1662   - /* operand size flag */
1663   - if (dflag)
1664   - *obufp++ = 'l';
  2778 + if (intel_syntax)
  2779 + break;
  2780 + if (sizeflag & SUFFIX_ALWAYS)
  2781 + {
  2782 + if (rex & REX_MODE64)
  2783 + *obufp++ = 'q';
  2784 + else
  2785 + {
  2786 + if (sizeflag & DFLAG)
  2787 + *obufp++ = 'l';
  2788 + else
  2789 + *obufp++ = 'w';
  2790 + used_prefixes |= (prefixes & PREFIX_DATA);
  2791 + }
  2792 + }
  2793 + break;
  2794 + case 'X':
  2795 + if (prefixes & PREFIX_DATA)
  2796 + *obufp++ = 'd';
1665 2797 else
1666   - *obufp++ = 'w';
  2798 + *obufp++ = 's';
  2799 + used_prefixes |= (prefixes & PREFIX_DATA);
  2800 + break;
  2801 + case 'Y':
  2802 + if (intel_syntax)
  2803 + break;
  2804 + if (rex & REX_MODE64)
  2805 + {
  2806 + USED_REX (REX_MODE64);
  2807 + *obufp++ = 'q';
  2808 + }
1667 2809 break;
  2810 + /* implicit operand size 'l' for i386 or 'q' for x86-64 */
1668 2811 case 'W':
1669 2812 /* operand size flag for cwtl, cbtw */
1670   - if (dflag)
  2813 + USED_REX (0);
  2814 + if (rex)
  2815 + *obufp++ = 'l';
  2816 + else if (sizeflag & DFLAG)
1671 2817 *obufp++ = 'w';
1672 2818 else
1673 2819 *obufp++ = 'b';
  2820 + if (intel_syntax)
  2821 + {
  2822 + if (rex)
  2823 + {
  2824 + *obufp++ = 'q';
  2825 + *obufp++ = 'e';
  2826 + }
  2827 + if (sizeflag & DFLAG)
  2828 + {
  2829 + *obufp++ = 'd';
  2830 + *obufp++ = 'e';
  2831 + }
  2832 + else
  2833 + {
  2834 + *obufp++ = 'w';
  2835 + }
  2836 + }
  2837 + if (!rex)
  2838 + used_prefixes |= (prefixes & PREFIX_DATA);
1674 2839 break;
1675 2840 }
1676 2841 }
1677 2842 *obufp = 0;
  2843 + return 0;
1678 2844 }
1679 2845  
1680 2846 static void
1681 2847 oappend (s)
1682   - char *s;
  2848 + const char *s;
1683 2849 {
1684 2850 strcpy (obufp, s);
1685 2851 obufp += strlen (s);
1686   - *obufp = 0;
1687 2852 }
1688 2853  
1689 2854 static void
1690   -append_prefix ()
  2855 +append_seg ()
1691 2856 {
1692 2857 if (prefixes & PREFIX_CS)
1693   - oappend ("%cs:");
  2858 + {
  2859 + used_prefixes |= PREFIX_CS;
  2860 + oappend ("%cs:" + intel_syntax);
  2861 + }
1694 2862 if (prefixes & PREFIX_DS)
1695   - oappend ("%ds:");
  2863 + {
  2864 + used_prefixes |= PREFIX_DS;
  2865 + oappend ("%ds:" + intel_syntax);
  2866 + }
1696 2867 if (prefixes & PREFIX_SS)
1697   - oappend ("%ss:");
  2868 + {
  2869 + used_prefixes |= PREFIX_SS;
  2870 + oappend ("%ss:" + intel_syntax);
  2871 + }
1698 2872 if (prefixes & PREFIX_ES)
1699   - oappend ("%es:");
  2873 + {
  2874 + used_prefixes |= PREFIX_ES;
  2875 + oappend ("%es:" + intel_syntax);
  2876 + }
1700 2877 if (prefixes & PREFIX_FS)
1701   - oappend ("%fs:");
  2878 + {
  2879 + used_prefixes |= PREFIX_FS;
  2880 + oappend ("%fs:" + intel_syntax);
  2881 + }
1702 2882 if (prefixes & PREFIX_GS)
1703   - oappend ("%gs:");
  2883 + {
  2884 + used_prefixes |= PREFIX_GS;
  2885 + oappend ("%gs:" + intel_syntax);
  2886 + }
1704 2887 }
1705 2888  
1706   -static int
1707   -OP_indirE (bytemode, aflag, dflag)
  2889 +static void
  2890 +OP_indirE (bytemode, sizeflag)
1708 2891 int bytemode;
1709   - int aflag;
1710   - int dflag;
  2892 + int sizeflag;
1711 2893 {
1712   - oappend ("*");
1713   - return OP_E (bytemode, aflag, dflag);
  2894 + if (!intel_syntax)
  2895 + oappend ("*");
  2896 + OP_E (bytemode, sizeflag);
1714 2897 }
1715 2898  
1716   -static int
1717   -OP_E (bytemode, aflag, dflag)
  2899 +static void
  2900 +print_operand_value (buf, hex, disp)
  2901 + char *buf;
  2902 + int hex;
  2903 + bfd_vma disp;
  2904 +{
  2905 + if (mode_64bit)
  2906 + {
  2907 + if (hex)
  2908 + {
  2909 + char tmp[30];
  2910 + int i;
  2911 + buf[0] = '0';
  2912 + buf[1] = 'x';
  2913 + sprintf_vma (tmp, disp);
  2914 + for (i = 0; tmp[i] == '0' && tmp[i + 1]; i++);
  2915 + strcpy (buf + 2, tmp + i);
  2916 + }
  2917 + else
  2918 + {
  2919 + bfd_signed_vma v = disp;
  2920 + char tmp[30];
  2921 + int i;
  2922 + if (v < 0)
  2923 + {
  2924 + *(buf++) = '-';
  2925 + v = -disp;
  2926 + /* Check for possible overflow on 0x8000000000000000. */
  2927 + if (v < 0)
  2928 + {
  2929 + strcpy (buf, "9223372036854775808");
  2930 + return;
  2931 + }
  2932 + }
  2933 + if (!v)
  2934 + {
  2935 + strcpy (buf, "0");
  2936 + return;
  2937 + }
  2938 +
  2939 + i = 0;
  2940 + tmp[29] = 0;
  2941 + while (v)
  2942 + {
  2943 + tmp[28 - i] = (v % 10) + '0';
  2944 + v /= 10;
  2945 + i++;
  2946 + }
  2947 + strcpy (buf, tmp + 29 - i);
  2948 + }
  2949 + }
  2950 + else
  2951 + {
  2952 + if (hex)
  2953 + sprintf (buf, "0x%x", (unsigned int) disp);
  2954 + else
  2955 + sprintf (buf, "%d", (int) disp);
  2956 + }
  2957 +}
  2958 +
  2959 +static void
  2960 +OP_E (bytemode, sizeflag)
1718 2961 int bytemode;
1719   - int aflag;
1720   - int dflag;
  2962 + int sizeflag;
1721 2963 {
1722   - int disp;
  2964 + bfd_vma disp;
  2965 + int add = 0;
  2966 + int riprel = 0;
  2967 + USED_REX (REX_EXTZ);
  2968 + if (rex & REX_EXTZ)
  2969 + add += 8;
1723 2970  
1724   - /* skip mod/rm byte */
  2971 + /* Skip mod/rm byte. */
  2972 + MODRM_CHECK;
1725 2973 codep++;
1726 2974  
1727 2975 if (mod == 3)
... ... @@ -1729,28 +2977,54 @@ OP_E (bytemode, aflag, dflag)
1729 2977 switch (bytemode)
1730 2978 {
1731 2979 case b_mode:
1732   - oappend (names8[rm]);
  2980 + USED_REX (0);
  2981 + if (rex)
  2982 + oappend (names8rex[rm + add]);
  2983 + else
  2984 + oappend (names8[rm + add]);
1733 2985 break;
1734 2986 case w_mode:
1735   - oappend (names16[rm]);
  2987 + oappend (names16[rm + add]);
  2988 + break;
  2989 + case d_mode:
  2990 + oappend (names32[rm + add]);
  2991 + break;
  2992 + case q_mode:
  2993 + oappend (names64[rm + add]);
  2994 + break;
  2995 + case m_mode:
  2996 + if (mode_64bit)
  2997 + oappend (names64[rm + add]);
  2998 + else
  2999 + oappend (names32[rm + add]);
1736 3000 break;
1737 3001 case v_mode:
1738   - if (dflag)
1739   - oappend (names32[rm]);
  3002 + USED_REX (REX_MODE64);
  3003 + if (rex & REX_MODE64)
  3004 + oappend (names64[rm + add]);
  3005 + else if (sizeflag & DFLAG)
  3006 + oappend (names32[rm + add]);
1740 3007 else
1741   - oappend (names16[rm]);
  3008 + oappend (names16[rm + add]);
  3009 + used_prefixes |= (prefixes & PREFIX_DATA);
  3010 + break;
  3011 + case 0:
  3012 + if (!(codep[-2] == 0xAE && codep[-1] == 0xF8 /* sfence */)
  3013 + && !(codep[-2] == 0xAE && codep[-1] == 0xF0 /* mfence */)
  3014 + && !(codep[-2] == 0xAE && codep[-1] == 0xe8 /* lfence */))
  3015 + BadOp (); /* bad sfence,lea,lds,les,lfs,lgs,lss modrm */
1742 3016 break;
1743 3017 default:
1744   - oappend ("<bad dis table>");
  3018 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1745 3019 break;
1746 3020 }
1747   - return 0;
  3021 + return;
1748 3022 }
1749 3023  
1750 3024 disp = 0;
1751   - append_prefix ();
  3025 + append_seg ();
1752 3026  
1753   - if (aflag) /* 32 bit address mode */
  3027 + if ((sizeflag & AFLAG) || mode_64bit) /* 32 bit address mode */
1754 3028 {
1755 3029 int havesib;
1756 3030 int havebase;
... ... @@ -1769,16 +3043,24 @@ OP_E (bytemode, aflag, dflag)
1769 3043 scale = (*codep >> 6) & 3;
1770 3044 index = (*codep >> 3) & 7;
1771 3045 base = *codep & 7;
  3046 + USED_REX (REX_EXTY);
  3047 + USED_REX (REX_EXTZ);
  3048 + if (rex & REX_EXTY)
  3049 + index += 8;
  3050 + if (rex & REX_EXTZ)
  3051 + base += 8;
1772 3052 codep++;
1773 3053 }
1774 3054  
1775 3055 switch (mod)
1776 3056 {
1777 3057 case 0:
1778   - if (base == 5)
  3058 + if ((base & 7) == 5)
1779 3059 {
1780 3060 havebase = 0;
1781   - disp = get32 ();
  3061 + if (mode_64bit && !havesib && (sizeflag & AFLAG))
  3062 + riprel = 1;
  3063 + disp = get32s ();
1782 3064 }
1783 3065 break;
1784 3066 case 1:
... ... @@ -1788,40 +3070,139 @@ OP_E (bytemode, aflag, dflag)
1788 3070 disp -= 0x100;
1789 3071 break;
1790 3072 case 2:
1791   - disp = get32 ();
  3073 + disp = get32s ();
1792 3074 break;
1793 3075 }
1794 3076  
1795   - if (mod != 0 || base == 5)
1796   - {
1797   - sprintf (scratchbuf, "0x%x", disp);
1798   - oappend (scratchbuf);
1799   - }
  3077 + if (!intel_syntax)
  3078 + if (mod != 0 || (base & 7) == 5)
  3079 + {
  3080 + print_operand_value (scratchbuf, !riprel, disp);
  3081 + oappend (scratchbuf);
  3082 + if (riprel)
  3083 + {
  3084 + set_op (disp, 1);
  3085 + oappend ("(%rip)");
  3086 + }
  3087 + }
1800 3088  
1801 3089 if (havebase || (havesib && (index != 4 || scale != 0)))
1802 3090 {
1803   - oappend ("(");
  3091 + if (intel_syntax)
  3092 + {
  3093 + switch (bytemode)
  3094 + {
  3095 + case b_mode:
  3096 + oappend ("BYTE PTR ");
  3097 + break;
  3098 + case w_mode:
  3099 + oappend ("WORD PTR ");
  3100 + break;
  3101 + case v_mode:
  3102 + oappend ("DWORD PTR ");
  3103 + break;
  3104 + case d_mode:
  3105 + oappend ("QWORD PTR ");
  3106 + break;
  3107 + case m_mode:
  3108 + if (mode_64bit)
  3109 + oappend ("DWORD PTR ");
  3110 + else
  3111 + oappend ("QWORD PTR ");
  3112 + break;
  3113 + case x_mode:
  3114 + oappend ("XWORD PTR ");
  3115 + break;
  3116 + default:
  3117 + break;
  3118 + }
  3119 + }
  3120 + *obufp++ = open_char;
  3121 + if (intel_syntax && riprel)
  3122 + oappend ("rip + ");
  3123 + *obufp = '\0';
  3124 + USED_REX (REX_EXTZ);
  3125 + if (!havesib && (rex & REX_EXTZ))
  3126 + base += 8;
1804 3127 if (havebase)
1805   - oappend (names32[base]);
  3128 + oappend (mode_64bit && (sizeflag & AFLAG)
  3129 + ? names64[base] : names32[base]);
1806 3130 if (havesib)
1807 3131 {
1808 3132 if (index != 4)
1809 3133 {
1810   - sprintf (scratchbuf, ",%s", names32[index]);
  3134 + if (intel_syntax)
  3135 + {
  3136 + if (havebase)
  3137 + {
  3138 + *obufp++ = separator_char;
  3139 + *obufp = '\0';
  3140 + }
  3141 + sprintf (scratchbuf, "%s",
  3142 + mode_64bit && (sizeflag & AFLAG)
  3143 + ? names64[index] : names32[index]);
  3144 + }
  3145 + else
  3146 + sprintf (scratchbuf, ",%s",
  3147 + mode_64bit && (sizeflag & AFLAG)
  3148 + ? names64[index] : names32[index]);
1811 3149 oappend (scratchbuf);
1812 3150 }
1813   - sprintf (scratchbuf, ",%d", 1 << scale);
1814   - oappend (scratchbuf);
  3151 + if (!intel_syntax
  3152 + || (intel_syntax
  3153 + && bytemode != b_mode
  3154 + && bytemode != w_mode
  3155 + && bytemode != v_mode))
  3156 + {
  3157 + *obufp++ = scale_char;
  3158 + *obufp = '\0';
  3159 + sprintf (scratchbuf, "%d", 1 << scale);
  3160 + oappend (scratchbuf);
  3161 + }
1815 3162 }
1816   - oappend (")");
  3163 + if (intel_syntax)
  3164 + if (mod != 0 || (base & 7) == 5)
  3165 + {
  3166 + /* Don't print zero displacements. */
  3167 + if (disp != 0)
  3168 + {
  3169 + if ((bfd_signed_vma) disp > 0)
  3170 + {
  3171 + *obufp++ = '+';
  3172 + *obufp = '\0';
  3173 + }
  3174 +
  3175 + print_operand_value (scratchbuf, 0, disp);
  3176 + oappend (scratchbuf);
  3177 + }
  3178 + }
  3179 +
  3180 + *obufp++ = close_char;
  3181 + *obufp = '\0';
1817 3182 }
  3183 + else if (intel_syntax)
  3184 + {
  3185 + if (mod != 0 || (base & 7) == 5)
  3186 + {
  3187 + if (prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
  3188 + | PREFIX_ES | PREFIX_FS | PREFIX_GS))
  3189 + ;
  3190 + else
  3191 + {
  3192 + oappend (names_seg[ds_reg - es_reg]);
  3193 + oappend (":");
  3194 + }
  3195 + print_operand_value (scratchbuf, 1, disp);
  3196 + oappend (scratchbuf);
  3197 + }
  3198 + }
1818 3199 }
1819 3200 else
1820 3201 { /* 16 bit address mode */
1821 3202 switch (mod)
1822 3203 {
1823 3204 case 0:
1824   - if (rm == 6)
  3205 + if ((rm & 7) == 6)
1825 3206 {
1826 3207 disp = get16 ();
1827 3208 if ((disp & 0x8000) != 0)
... ... @@ -1841,63 +3222,119 @@ OP_E (bytemode, aflag, dflag)
1841 3222 break;
1842 3223 }
1843 3224  
1844   - if (mod != 0 || rm == 6)
1845   - {
1846   - sprintf (scratchbuf, "0x%x", disp);
1847   - oappend (scratchbuf);
1848   - }
  3225 + if (!intel_syntax)
  3226 + if (mod != 0 || (rm & 7) == 6)
  3227 + {
  3228 + print_operand_value (scratchbuf, 0, disp);
  3229 + oappend (scratchbuf);
  3230 + }
1849 3231  
1850   - if (mod != 0 || rm != 6)
  3232 + if (mod != 0 || (rm & 7) != 6)
1851 3233 {
1852   - oappend ("(");
1853   - oappend (index16[rm]);
1854   - oappend (")");
  3234 + *obufp++ = open_char;
  3235 + *obufp = '\0';
  3236 + oappend (index16[rm + add]);
  3237 + *obufp++ = close_char;
  3238 + *obufp = '\0';
1855 3239 }
1856 3240 }
1857   - return 0;
1858 3241 }
1859 3242  
1860   -static int
1861   -OP_G (bytemode, aflag, dflag)
  3243 +static void
  3244 +OP_G (bytemode, sizeflag)
1862 3245 int bytemode;
1863   - int aflag;
1864   - int dflag;
  3246 + int sizeflag;
1865 3247 {
1866   - switch (bytemode)
  3248 + int add = 0;
  3249 + USED_REX (REX_EXTX);
  3250 + if (rex & REX_EXTX)
  3251 + add += 8;
  3252 + switch (bytemode)
1867 3253 {
1868 3254 case b_mode:
1869   - oappend (names8[reg]);
  3255 + USED_REX (0);
  3256 + if (rex)
  3257 + oappend (names8rex[reg + add]);
  3258 + else
  3259 + oappend (names8[reg + add]);
1870 3260 break;
1871 3261 case w_mode:
1872   - oappend (names16[reg]);
  3262 + oappend (names16[reg + add]);
1873 3263 break;
1874 3264 case d_mode:
1875   - oappend (names32[reg]);
  3265 + oappend (names32[reg + add]);
  3266 + break;
  3267 + case q_mode:
  3268 + oappend (names64[reg + add]);
1876 3269 break;
1877 3270 case v_mode:
1878   - if (dflag)
1879   - oappend (names32[reg]);
  3271 + USED_REX (REX_MODE64);
  3272 + if (rex & REX_MODE64)
  3273 + oappend (names64[reg + add]);
  3274 + else if (sizeflag & DFLAG)
  3275 + oappend (names32[reg + add]);
1880 3276 else
1881   - oappend (names16[reg]);
  3277 + oappend (names16[reg + add]);
  3278 + used_prefixes |= (prefixes & PREFIX_DATA);
1882 3279 break;
1883 3280 default:
1884   - oappend ("<internal disassembler error>");
  3281 + oappend (INTERNAL_DISASSEMBLER_ERROR);
1885 3282 break;
1886 3283 }
1887   - return (0);
1888 3284 }
1889 3285  
1890   -static int
  3286 +static bfd_vma
  3287 +get64 ()
  3288 +{
  3289 + bfd_vma x;
  3290 +#ifdef BFD64
  3291 + unsigned int a;
  3292 + unsigned int b;
  3293 +
  3294 + FETCH_DATA (the_info, codep + 8);
  3295 + a = *codep++ & 0xff;
  3296 + a |= (*codep++ & 0xff) << 8;
  3297 + a |= (*codep++ & 0xff) << 16;
  3298 + a |= (*codep++ & 0xff) << 24;
  3299 + b = *codep++ & 0xff;
  3300 + b |= (*codep++ & 0xff) << 8;
  3301 + b |= (*codep++ & 0xff) << 16;
  3302 + b |= (*codep++ & 0xff) << 24;
  3303 + x = a + ((bfd_vma) b << 32);
  3304 +#else
  3305 + abort ();
  3306 + x = 0;
  3307 +#endif
  3308 + return x;
  3309 +}
  3310 +
  3311 +static bfd_signed_vma
1891 3312 get32 ()
1892 3313 {
1893   - int x = 0;
  3314 + bfd_signed_vma x = 0;
1894 3315  
1895 3316 FETCH_DATA (the_info, codep + 4);
1896   - x = *codep++ & 0xff;
1897   - x |= (*codep++ & 0xff) << 8;
1898   - x |= (*codep++ & 0xff) << 16;
1899   - x |= (*codep++ & 0xff) << 24;
1900   - return (x);
  3317 + x = *codep++ & (bfd_signed_vma) 0xff;
  3318 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
  3319 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
  3320 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
  3321 + return x;
  3322 +}
  3323 +
  3324 +static bfd_signed_vma
  3325 +get32s ()
  3326 +{
  3327 + bfd_signed_vma x = 0;
  3328 +
  3329 + FETCH_DATA (the_info, codep + 4);
  3330 + x = *codep++ & (bfd_signed_vma) 0xff;
  3331 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 8;
  3332 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 16;
  3333 + x |= (*codep++ & (bfd_signed_vma) 0xff) << 24;
  3334 +
  3335 + x = (x ^ ((bfd_signed_vma) 1 << 31)) - ((bfd_signed_vma) 1 << 31);
  3336 +
  3337 + return x;
1901 3338 }
1902 3339  
1903 3340 static int
... ... @@ -1908,137 +3345,306 @@ get16 ()
1908 3345 FETCH_DATA (the_info, codep + 2);
1909 3346 x = *codep++ & 0xff;
1910 3347 x |= (*codep++ & 0xff) << 8;
1911   - return (x);
  3348 + return x;
1912 3349 }
1913 3350  
1914 3351 static void
1915   -set_op (op)
1916   - int op;
  3352 +set_op (op, riprel)
  3353 + bfd_vma op;
  3354 + int riprel;
1917 3355 {
1918 3356 op_index[op_ad] = op_ad;
1919   - op_address[op_ad] = op;
  3357 + if (mode_64bit)
  3358 + {
  3359 + op_address[op_ad] = op;
  3360 + op_riprel[op_ad] = riprel;
  3361 + }
  3362 + else
  3363 + {
  3364 + /* Mask to get a 32-bit address. */
  3365 + op_address[op_ad] = op & 0xffffffff;
  3366 + op_riprel[op_ad] = riprel & 0xffffffff;
  3367 + }
1920 3368 }
1921 3369  
1922   -static int
1923   -OP_REG (code, aflag, dflag)
  3370 +static void
  3371 +OP_REG (code, sizeflag)
  3372 + int code;
  3373 + int sizeflag;
  3374 +{
  3375 + const char *s;
  3376 + int add = 0;
  3377 + USED_REX (REX_EXTZ);
  3378 + if (rex & REX_EXTZ)
  3379 + add = 8;
  3380 +
  3381 + switch (code)
  3382 + {
  3383 + case indir_dx_reg:
  3384 + if (intel_syntax)
  3385 + s = "[dx]";
  3386 + else
  3387 + s = "(%dx)";
  3388 + break;
  3389 + case ax_reg: case cx_reg: case dx_reg: case bx_reg:
  3390 + case sp_reg: case bp_reg: case si_reg: case di_reg:
  3391 + s = names16[code - ax_reg + add];
  3392 + break;
  3393 + case es_reg: case ss_reg: case cs_reg:
  3394 + case ds_reg: case fs_reg: case gs_reg:
  3395 + s = names_seg[code - es_reg + add];
  3396 + break;
  3397 + case al_reg: case ah_reg: case cl_reg: case ch_reg:
  3398 + case dl_reg: case dh_reg: case bl_reg: case bh_reg:
  3399 + USED_REX (0);
  3400 + if (rex)
  3401 + s = names8rex[code - al_reg + add];
  3402 + else
  3403 + s = names8[code - al_reg];
  3404 + break;
  3405 + case rAX_reg: case rCX_reg: case rDX_reg: case rBX_reg:
  3406 + case rSP_reg: case rBP_reg: case rSI_reg: case rDI_reg:
  3407 + if (mode_64bit)
  3408 + {
  3409 + s = names64[code - rAX_reg + add];
  3410 + break;
  3411 + }
  3412 + code += eAX_reg - rAX_reg;
  3413 + /* Fall through. */
  3414 + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
  3415 + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
  3416 + USED_REX (REX_MODE64);
  3417 + if (rex & REX_MODE64)
  3418 + s = names64[code - eAX_reg + add];
  3419 + else if (sizeflag & DFLAG)
  3420 + s = names32[code - eAX_reg + add];
  3421 + else
  3422 + s = names16[code - eAX_reg + add];
  3423 + used_prefixes |= (prefixes & PREFIX_DATA);
  3424 + break;
  3425 + default:
  3426 + s = INTERNAL_DISASSEMBLER_ERROR;
  3427 + break;
  3428 + }
  3429 + oappend (s);
  3430 +}
  3431 +
  3432 +static void
  3433 +OP_IMREG (code, sizeflag)
1924 3434 int code;
1925   - int aflag;
1926   - int dflag;
  3435 + int sizeflag;
1927 3436 {
1928   - char *s;
1929   -
1930   - switch (code)
  3437 + const char *s;
  3438 +
  3439 + switch (code)
1931 3440 {
1932   - case indir_dx_reg: s = "(%dx)"; break;
1933   - case ax_reg: case cx_reg: case dx_reg: case bx_reg:
1934   - case sp_reg: case bp_reg: case si_reg: case di_reg:
1935   - s = names16[code - ax_reg];
1936   - break;
1937   - case es_reg: case ss_reg: case cs_reg:
1938   - case ds_reg: case fs_reg: case gs_reg:
1939   - s = names_seg[code - es_reg];
1940   - break;
1941   - case al_reg: case ah_reg: case cl_reg: case ch_reg:
1942   - case dl_reg: case dh_reg: case bl_reg: case bh_reg:
1943   - s = names8[code - al_reg];
1944   - break;
1945   - case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
1946   - case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
1947   - if (dflag)
  3441 + case indir_dx_reg:
  3442 + if (intel_syntax)
  3443 + s = "[dx]";
  3444 + else
  3445 + s = "(%dx)";
  3446 + break;
  3447 + case ax_reg: case cx_reg: case dx_reg: case bx_reg:
  3448 + case sp_reg: case bp_reg: case si_reg: case di_reg:
  3449 + s = names16[code - ax_reg];
  3450 + break;
  3451 + case es_reg: case ss_reg: case cs_reg:
  3452 + case ds_reg: case fs_reg: case gs_reg:
  3453 + s = names_seg[code - es_reg];
  3454 + break;
  3455 + case al_reg: case ah_reg: case cl_reg: case ch_reg:
  3456 + case dl_reg: case dh_reg: case bl_reg: case bh_reg:
  3457 + USED_REX (0);
  3458 + if (rex)
  3459 + s = names8rex[code - al_reg];
  3460 + else
  3461 + s = names8[code - al_reg];
  3462 + break;
  3463 + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
  3464 + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
  3465 + USED_REX (REX_MODE64);
  3466 + if (rex & REX_MODE64)
  3467 + s = names64[code - eAX_reg];
  3468 + else if (sizeflag & DFLAG)
1948 3469 s = names32[code - eAX_reg];
1949 3470 else
1950 3471 s = names16[code - eAX_reg];
  3472 + used_prefixes |= (prefixes & PREFIX_DATA);
1951 3473 break;
1952 3474 default:
1953   - s = "<internal disassembler error>";
  3475 + s = INTERNAL_DISASSEMBLER_ERROR;
1954 3476 break;
1955 3477 }
1956 3478 oappend (s);
1957   - return (0);
1958 3479 }
1959 3480  
1960   -static int
1961   -OP_I (bytemode, aflag, dflag)
  3481 +static void
  3482 +OP_I (bytemode, sizeflag)
  3483 + int bytemode;
  3484 + int sizeflag;
  3485 +{
  3486 + bfd_signed_vma op;
  3487 + bfd_signed_vma mask = -1;
  3488 +
  3489 + switch (bytemode)
  3490 + {
  3491 + case b_mode:
  3492 + FETCH_DATA (the_info, codep + 1);
  3493 + op = *codep++;
  3494 + mask = 0xff;
  3495 + break;
  3496 + case q_mode:
  3497 + if (mode_64bit)
  3498 + {
  3499 + op = get32s ();
  3500 + break;
  3501 + }
  3502 + /* Fall through. */
  3503 + case v_mode:
  3504 + USED_REX (REX_MODE64);
  3505 + if (rex & REX_MODE64)
  3506 + op = get32s ();
  3507 + else if (sizeflag & DFLAG)
  3508 + {
  3509 + op = get32 ();
  3510 + mask = 0xffffffff;
  3511 + }
  3512 + else
  3513 + {
  3514 + op = get16 ();
  3515 + mask = 0xfffff;
  3516 + }
  3517 + used_prefixes |= (prefixes & PREFIX_DATA);
  3518 + break;
  3519 + case w_mode:
  3520 + mask = 0xfffff;
  3521 + op = get16 ();
  3522 + break;
  3523 + default:
  3524 + oappend (INTERNAL_DISASSEMBLER_ERROR);
  3525 + return;
  3526 + }
  3527 +
  3528 + op &= mask;
  3529 + scratchbuf[0] = '$';
  3530 + print_operand_value (scratchbuf + 1, 1, op);
  3531 + oappend (scratchbuf + intel_syntax);
  3532 + scratchbuf[0] = '\0';
  3533 +}
  3534 +
  3535 +static void
  3536 +OP_I64 (bytemode, sizeflag)
1962 3537 int bytemode;
1963   - int aflag;
1964   - int dflag;
  3538 + int sizeflag;
1965 3539 {
1966   - int op;
1967   -
1968   - switch (bytemode)
  3540 + bfd_signed_vma op;
  3541 + bfd_signed_vma mask = -1;
  3542 +
  3543 + if (!mode_64bit)
  3544 + {
  3545 + OP_I (bytemode, sizeflag);
  3546 + return;
  3547 + }
  3548 +
  3549 + switch (bytemode)
1969 3550 {
1970 3551 case b_mode:
1971 3552 FETCH_DATA (the_info, codep + 1);
1972   - op = *codep++ & 0xff;
  3553 + op = *codep++;
  3554 + mask = 0xff;
1973 3555 break;
1974 3556 case v_mode:
1975   - if (dflag)
1976   - op = get32 ();
  3557 + USED_REX (REX_MODE64);
  3558 + if (rex & REX_MODE64)
  3559 + op = get64 ();
  3560 + else if (sizeflag & DFLAG)
  3561 + {
  3562 + op = get32 ();
  3563 + mask = 0xffffffff;
  3564 + }
1977 3565 else
1978   - op = get16 ();
  3566 + {
  3567 + op = get16 ();
  3568 + mask = 0xfffff;
  3569 + }
  3570 + used_prefixes |= (prefixes & PREFIX_DATA);
1979 3571 break;
1980 3572 case w_mode:
  3573 + mask = 0xfffff;
1981 3574 op = get16 ();
1982 3575 break;
1983 3576 default:
1984   - oappend ("<internal disassembler error>");
1985   - return (0);
  3577 + oappend (INTERNAL_DISASSEMBLER_ERROR);
  3578 + return;
1986 3579 }
1987   - sprintf (scratchbuf, "$0x%x", op);
1988   - oappend (scratchbuf);
1989   - return (0);
  3580 +
  3581 + op &= mask;
  3582 + scratchbuf[0] = '$';
  3583 + print_operand_value (scratchbuf + 1, 1, op);
  3584 + oappend (scratchbuf + intel_syntax);
  3585 + scratchbuf[0] = '\0';
1990 3586 }
1991 3587  
1992   -static int
1993   -OP_sI (bytemode, aflag, dflag)
  3588 +static void
  3589 +OP_sI (bytemode, sizeflag)
1994 3590 int bytemode;
1995   - int aflag;
1996   - int dflag;
  3591 + int sizeflag;
1997 3592 {
1998   - int op;
1999   -
2000   - switch (bytemode)
  3593 + bfd_signed_vma op;
  3594 + bfd_signed_vma mask = -1;
  3595 +
  3596 + switch (bytemode)
2001 3597 {
2002 3598 case b_mode:
2003 3599 FETCH_DATA (the_info, codep + 1);
2004 3600 op = *codep++;
2005 3601 if ((op & 0x80) != 0)
2006 3602 op -= 0x100;
  3603 + mask = 0xffffffff;
2007 3604 break;
2008 3605 case v_mode:
2009   - if (dflag)
2010   - op = get32 ();
  3606 + USED_REX (REX_MODE64);
  3607 + if (rex & REX_MODE64)
  3608 + op = get32s ();
  3609 + else if (sizeflag & DFLAG)
  3610 + {
  3611 + op = get32s ();
  3612 + mask = 0xffffffff;
  3613 + }
2011 3614 else
2012 3615 {
2013   - op = get16();
  3616 + mask = 0xffffffff;
  3617 + op = get16 ();
2014 3618 if ((op & 0x8000) != 0)
2015 3619 op -= 0x10000;
2016 3620 }
  3621 + used_prefixes |= (prefixes & PREFIX_DATA);
2017 3622 break;
2018 3623 case w_mode:
2019 3624 op = get16 ();
  3625 + mask = 0xffffffff;
2020 3626 if ((op & 0x8000) != 0)
2021 3627 op -= 0x10000;
2022 3628 break;
2023 3629 default:
2024   - oappend ("<internal disassembler error>");
2025   - return (0);
  3630 + oappend (INTERNAL_DISASSEMBLER_ERROR);
  3631 + return;
2026 3632 }
2027   - sprintf (scratchbuf, "$0x%x", op);
2028   - oappend (scratchbuf);
2029   - return (0);
  3633 +
  3634 + scratchbuf[0] = '$';
  3635 + print_operand_value (scratchbuf + 1, 1, op);
  3636 + oappend (scratchbuf + intel_syntax);
2030 3637 }
2031 3638  
2032   -static int
2033   -OP_J (bytemode, aflag, dflag)
  3639 +static void
  3640 +OP_J (bytemode, sizeflag)
2034 3641 int bytemode;
2035   - int aflag;
2036   - int dflag;
  3642 + int sizeflag;
2037 3643 {
2038   - int disp;
2039   - int mask = -1;
2040   -
2041   - switch (bytemode)
  3644 + bfd_vma disp;
  3645 + bfd_vma mask = -1;
  3646 +
  3647 + switch (bytemode)
2042 3648 {
2043 3649 case b_mode:
2044 3650 FETCH_DATA (the_info, codep + 1);
... ... @@ -2047,131 +3653,160 @@ OP_J (bytemode, aflag, dflag)
2047 3653 disp -= 0x100;
2048 3654 break;
2049 3655 case v_mode:
2050   - if (dflag)
2051   - disp = get32 ();
  3656 + if (sizeflag & DFLAG)
  3657 + disp = get32s ();
2052 3658 else
2053 3659 {
2054 3660 disp = get16 ();
2055   - if ((disp & 0x8000) != 0)
2056   - disp -= 0x10000;
2057   - /* for some reason, a data16 prefix on a jump instruction
  3661 + /* For some reason, a data16 prefix on a jump instruction
2058 3662 means that the pc is masked to 16 bits after the
2059 3663 displacement is added! */
2060 3664 mask = 0xffff;
2061 3665 }
2062 3666 break;
2063 3667 default:
2064   - oappend ("<internal disassembler error>");
2065   - return (0);
  3668 + oappend (INTERNAL_DISASSEMBLER_ERROR);
  3669 + return;
2066 3670 }
2067 3671 disp = (start_pc + codep - start_codep + disp) & mask;
2068   - set_op (disp);
2069   - sprintf (scratchbuf, "0x%x", disp);
  3672 + set_op (disp, 0);
  3673 + print_operand_value (scratchbuf, 1, disp);
2070 3674 oappend (scratchbuf);
2071   - return (0);
2072 3675 }
2073 3676  
2074   -/* ARGSUSED */
2075   -static int
2076   -OP_SEG (dummy, aflag, dflag)
  3677 +static void
  3678 +OP_SEG (dummy, sizeflag)
2077 3679 int dummy;
2078   - int aflag;
2079   - int dflag;
  3680 + int sizeflag;
2080 3681 {
2081   - static char *sreg[] = {
2082   - "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
2083   - };
2084   -
2085   - oappend (sreg[reg]);
2086   - return (0);
  3682 + oappend (names_seg[reg]);
2087 3683 }
2088 3684  
2089   -static int
2090   -OP_DIR (size, aflag, dflag)
2091   - int size;
2092   - int aflag;
2093   - int dflag;
  3685 +static void
  3686 +OP_DIR (dummy, sizeflag)
  3687 + int dummy;
  3688 + int sizeflag;
2094 3689 {
2095 3690 int seg, offset;
2096   -
2097   - switch (size)
  3691 +
  3692 + if (sizeflag & DFLAG)
2098 3693 {
2099   - case lptr:
2100   - if (aflag)
2101   - {
2102   - offset = get32 ();
2103   - seg = get16 ();
2104   - }
2105   - else
2106   - {
2107   - offset = get16 ();
2108   - seg = get16 ();
2109   - }
2110   - sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
2111   - oappend (scratchbuf);
2112   - break;
2113   - case v_mode:
2114   - if (aflag)
2115   - offset = get32 ();
2116   - else
2117   - {
2118   - offset = get16 ();
2119   - if ((offset & 0x8000) != 0)
2120   - offset -= 0x10000;
2121   - }
2122   -
2123   - offset = start_pc + codep - start_codep + offset;
2124   - set_op (offset);
2125   - sprintf (scratchbuf, "0x%x", offset);
2126   - oappend (scratchbuf);
2127   - break;
2128   - default:
2129   - oappend ("<internal disassembler error>");
2130   - break;
  3694 + offset = get32 ();
  3695 + seg = get16 ();
2131 3696 }
2132   - return (0);
  3697 + else
  3698 + {
  3699 + offset = get16 ();
  3700 + seg = get16 ();
  3701 + }
  3702 + used_prefixes |= (prefixes & PREFIX_DATA);
  3703 + if (intel_syntax)
  3704 + sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
  3705 + else
  3706 + sprintf (scratchbuf, "$0x%x,$0x%x", seg, offset);
  3707 + oappend (scratchbuf);
2133 3708 }
2134 3709  
2135   -/* ARGSUSED */
2136   -static int
2137   -OP_OFF (bytemode, aflag, dflag)
  3710 +static void
  3711 +OP_OFF (bytemode, sizeflag)
2138 3712 int bytemode;
2139   - int aflag;
2140   - int dflag;
  3713 + int sizeflag;
2141 3714 {
2142   - int off;
  3715 + bfd_vma off;
2143 3716  
2144   - append_prefix ();
  3717 + append_seg ();
2145 3718  
2146   - if (aflag)
  3719 + if ((sizeflag & AFLAG) || mode_64bit)
2147 3720 off = get32 ();
2148 3721 else
2149 3722 off = get16 ();
2150   -
2151   - sprintf (scratchbuf, "0x%x", off);
  3723 +
  3724 + if (intel_syntax)
  3725 + {
  3726 + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
  3727 + | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
  3728 + {
  3729 + oappend (names_seg[ds_reg - es_reg]);
  3730 + oappend (":");
  3731 + }
  3732 + }
  3733 + print_operand_value (scratchbuf, 1, off);
2152 3734 oappend (scratchbuf);
2153   - return (0);
2154 3735 }
2155 3736  
2156   -/* ARGSUSED */
2157   -static int
2158   -OP_ESDI (dummy, aflag, dflag)
2159   - int dummy;
2160   - int aflag;
2161   - int dflag;
  3737 +static void
  3738 +OP_OFF64 (bytemode, sizeflag)
  3739 + int bytemode;
  3740 + int sizeflag;
2162 3741 {
2163   - oappend ("%es:(");
2164   - oappend (aflag ? "%edi" : "%di");
2165   - oappend (")");
2166   - return (0);
  3742 + bfd_vma off;
  3743 +
  3744 + if (!mode_64bit)
  3745 + {
  3746 + OP_OFF (bytemode, sizeflag);
  3747 + return;
  3748 + }
  3749 +
  3750 + append_seg ();
  3751 +
  3752 + off = get64 ();
  3753 +
  3754 + if (intel_syntax)
  3755 + {
  3756 + if (!(prefixes & (PREFIX_CS | PREFIX_SS | PREFIX_DS
  3757 + | PREFIX_ES | PREFIX_FS | PREFIX_GS)))
  3758 + {
  3759 + oappend (names_seg[ds_reg - es_reg]);
  3760 + oappend (":");
  3761 + }
  3762 + }
  3763 + print_operand_value (scratchbuf, 1, off);
  3764 + oappend (scratchbuf);
2167 3765 }
2168 3766  
2169   -/* ARGSUSED */
2170   -static int
2171   -OP_DSSI (dummy, aflag, dflag)
2172   - int dummy;
2173   - int aflag;
2174   - int dflag;
  3767 +static void
  3768 +ptr_reg (code, sizeflag)
  3769 + int code;
  3770 + int sizeflag;
  3771 +{
  3772 + const char *s;
  3773 + if (intel_syntax)
  3774 + oappend ("[");
  3775 + else
  3776 + oappend ("(");
  3777 +
  3778 + USED_REX (REX_MODE64);
  3779 + if (rex & REX_MODE64)
  3780 + {
  3781 + if (!(sizeflag & AFLAG))
  3782 + s = names32[code - eAX_reg];
  3783 + else
  3784 + s = names64[code - eAX_reg];
  3785 + }
  3786 + else if (sizeflag & AFLAG)
  3787 + s = names32[code - eAX_reg];
  3788 + else
  3789 + s = names16[code - eAX_reg];
  3790 + oappend (s);
  3791 + if (intel_syntax)
  3792 + oappend ("]");
  3793 + else
  3794 + oappend (")");
  3795 +}
  3796 +
  3797 +static void
  3798 +OP_ESreg (code, sizeflag)
  3799 + int code;
  3800 + int sizeflag;
  3801 +{
  3802 + oappend ("%es:" + intel_syntax);
  3803 + ptr_reg (code, sizeflag);
  3804 +}
  3805 +
  3806 +static void
  3807 +OP_DSreg (code, sizeflag)
  3808 + int code;
  3809 + int sizeflag;
2175 3810 {
2176 3811 if ((prefixes
2177 3812 & (PREFIX_CS
... ... @@ -2181,120 +3816,328 @@ OP_DSSI (dummy, aflag, dflag)
2181 3816 | PREFIX_FS
2182 3817 | PREFIX_GS)) == 0)
2183 3818 prefixes |= PREFIX_DS;
2184   - append_prefix ();
2185   - oappend ("(");
2186   - oappend (aflag ? "%esi" : "%si");
2187   - oappend (")");
2188   - return (0);
  3819 + append_seg ();
  3820 + ptr_reg (code, sizeflag);
2189 3821 }
2190 3822  
2191   -#if 0
2192   -/* Not used. */
2193   -
2194   -/* ARGSUSED */
2195   -static int
2196   -OP_ONE (dummy, aflag, dflag)
  3823 +static void
  3824 +OP_C (dummy, sizeflag)
2197 3825 int dummy;
2198   - int aflag;
2199   - int dflag;
  3826 + int sizeflag;
2200 3827 {
2201   - oappend ("1");
2202   - return (0);
  3828 + int add = 0;
  3829 + USED_REX (REX_EXTX);
  3830 + if (rex & REX_EXTX)
  3831 + add = 8;
  3832 + sprintf (scratchbuf, "%%cr%d", reg + add);
  3833 + oappend (scratchbuf + intel_syntax);
2203 3834 }
2204 3835  
2205   -#endif
2206   -
2207   -/* ARGSUSED */
2208   -static int
2209   -OP_C (dummy, aflag, dflag)
  3836 +static void
  3837 +OP_D (dummy, sizeflag)
2210 3838 int dummy;
2211   - int aflag;
2212   - int dflag;
  3839 + int sizeflag;
2213 3840 {
2214   - codep++; /* skip mod/rm */
2215   - sprintf (scratchbuf, "%%cr%d", reg);
  3841 + int add = 0;
  3842 + USED_REX (REX_EXTX);
  3843 + if (rex & REX_EXTX)
  3844 + add = 8;
  3845 + if (intel_syntax)
  3846 + sprintf (scratchbuf, "db%d", reg + add);
  3847 + else
  3848 + sprintf (scratchbuf, "%%db%d", reg + add);
2216 3849 oappend (scratchbuf);
2217   - return (0);
2218 3850 }
2219 3851  
2220   -/* ARGSUSED */
2221   -static int
2222   -OP_D (dummy, aflag, dflag)
  3852 +static void
  3853 +OP_T (dummy, sizeflag)
2223 3854 int dummy;
2224   - int aflag;
2225   - int dflag;
  3855 + int sizeflag;
2226 3856 {
2227   - codep++; /* skip mod/rm */
2228   - sprintf (scratchbuf, "%%db%d", reg);
2229   - oappend (scratchbuf);
2230   - return (0);
  3857 + sprintf (scratchbuf, "%%tr%d", reg);
  3858 + oappend (scratchbuf + intel_syntax);
2231 3859 }
2232 3860  
2233   -/* ARGSUSED */
2234   -static int
2235   -OP_T (dummy, aflag, dflag)
2236   - int dummy;
2237   - int aflag;
2238   - int dflag;
  3861 +static void
  3862 +OP_Rd (bytemode, sizeflag)
  3863 + int bytemode;
  3864 + int sizeflag;
2239 3865 {
2240   - codep++; /* skip mod/rm */
2241   - sprintf (scratchbuf, "%%tr%d", reg);
2242   - oappend (scratchbuf);
2243   - return (0);
  3866 + if (mod == 3)
  3867 + OP_E (bytemode, sizeflag);
  3868 + else
  3869 + BadOp ();
2244 3870 }
2245 3871  
2246   -static int
2247   -OP_rm (bytemode, aflag, dflag)
  3872 +static void
  3873 +OP_MMX (bytemode, sizeflag)
2248 3874 int bytemode;
2249   - int aflag;
2250   - int dflag;
  3875 + int sizeflag;
2251 3876 {
2252   - switch (bytemode)
2253   - {
2254   - case d_mode:
2255   - oappend (names32[rm]);
2256   - break;
2257   - case w_mode:
2258   - oappend (names16[rm]);
2259   - break;
2260   - }
2261   - return (0);
  3877 + int add = 0;
  3878 + USED_REX (REX_EXTX);
  3879 + if (rex & REX_EXTX)
  3880 + add = 8;
  3881 + used_prefixes |= (prefixes & PREFIX_DATA);
  3882 + if (prefixes & PREFIX_DATA)
  3883 + sprintf (scratchbuf, "%%xmm%d", reg + add);
  3884 + else
  3885 + sprintf (scratchbuf, "%%mm%d", reg + add);
  3886 + oappend (scratchbuf + intel_syntax);
2262 3887 }
2263 3888  
2264   -static int
2265   -OP_MMX (bytemode, aflag, dflag)
  3889 +static void
  3890 +OP_XMM (bytemode, sizeflag)
2266 3891 int bytemode;
2267   - int aflag;
2268   - int dflag;
  3892 + int sizeflag;
2269 3893 {
2270   - sprintf (scratchbuf, "%%mm%d", reg);
2271   - oappend (scratchbuf);
2272   - return 0;
  3894 + int add = 0;
  3895 + USED_REX (REX_EXTX);
  3896 + if (rex & REX_EXTX)
  3897 + add = 8;
  3898 + sprintf (scratchbuf, "%%xmm%d", reg + add);
  3899 + oappend (scratchbuf + intel_syntax);
2273 3900 }
2274 3901  
2275   -static int
2276   -OP_EM (bytemode, aflag, dflag)
  3902 +static void
  3903 +OP_EM (bytemode, sizeflag)
2277 3904 int bytemode;
2278   - int aflag;
2279   - int dflag;
  3905 + int sizeflag;
2280 3906 {
  3907 + int add = 0;
2281 3908 if (mod != 3)
2282   - return OP_E (bytemode, aflag, dflag);
  3909 + {
  3910 + OP_E (bytemode, sizeflag);
  3911 + return;
  3912 + }
  3913 + USED_REX (REX_EXTZ);
  3914 + if (rex & REX_EXTZ)
  3915 + add = 8;
2283 3916  
  3917 + /* Skip mod/rm byte. */
  3918 + MODRM_CHECK;
2284 3919 codep++;
2285   - sprintf (scratchbuf, "%%mm%d", rm);
2286   - oappend (scratchbuf);
2287   - return 0;
  3920 + used_prefixes |= (prefixes & PREFIX_DATA);
  3921 + if (prefixes & PREFIX_DATA)
  3922 + sprintf (scratchbuf, "%%xmm%d", rm + add);
  3923 + else
  3924 + sprintf (scratchbuf, "%%mm%d", rm + add);
  3925 + oappend (scratchbuf + intel_syntax);
2288 3926 }
2289 3927  
2290   -static int
2291   -OP_MS (bytemode, aflag, dflag)
  3928 +static void
  3929 +OP_EX (bytemode, sizeflag)
2292 3930 int bytemode;
2293   - int aflag;
2294   - int dflag;
  3931 + int sizeflag;
2295 3932 {
2296   - ++codep;
2297   - sprintf (scratchbuf, "%%mm%d", rm);
2298   - oappend (scratchbuf);
2299   - return 0;
  3933 + int add = 0;
  3934 + if (mod != 3)
  3935 + {
  3936 + OP_E (bytemode, sizeflag);
  3937 + return;
  3938 + }
  3939 + USED_REX (REX_EXTZ);
  3940 + if (rex & REX_EXTZ)
  3941 + add = 8;
  3942 +
  3943 + /* Skip mod/rm byte. */
  3944 + MODRM_CHECK;
  3945 + codep++;
  3946 + sprintf (scratchbuf, "%%xmm%d", rm + add);
  3947 + oappend (scratchbuf + intel_syntax);
  3948 +}
  3949 +
  3950 +static void
  3951 +OP_MS (bytemode, sizeflag)
  3952 + int bytemode;
  3953 + int sizeflag;
  3954 +{
  3955 + if (mod == 3)
  3956 + OP_EM (bytemode, sizeflag);
  3957 + else
  3958 + BadOp ();
  3959 +}
  3960 +
  3961 +static void
  3962 +OP_XS (bytemode, sizeflag)
  3963 + int bytemode;
  3964 + int sizeflag;
  3965 +{
  3966 + if (mod == 3)
  3967 + OP_EX (bytemode, sizeflag);
  3968 + else
  3969 + BadOp ();
  3970 +}
  3971 +
  3972 +static const char *Suffix3DNow[] = {
  3973 +/* 00 */ NULL, NULL, NULL, NULL,
  3974 +/* 04 */ NULL, NULL, NULL, NULL,
  3975 +/* 08 */ NULL, NULL, NULL, NULL,
  3976 +/* 0C */ "pi2fw", "pi2fd", NULL, NULL,
  3977 +/* 10 */ NULL, NULL, NULL, NULL,
  3978 +/* 14 */ NULL, NULL, NULL, NULL,
  3979 +/* 18 */ NULL, NULL, NULL, NULL,
  3980 +/* 1C */ "pf2iw", "pf2id", NULL, NULL,
  3981 +/* 20 */ NULL, NULL, NULL, NULL,
  3982 +/* 24 */ NULL, NULL, NULL, NULL,
  3983 +/* 28 */ NULL, NULL, NULL, NULL,
  3984 +/* 2C */ NULL, NULL, NULL, NULL,
  3985 +/* 30 */ NULL, NULL, NULL, NULL,
  3986 +/* 34 */ NULL, NULL, NULL, NULL,
  3987 +/* 38 */ NULL, NULL, NULL, NULL,
  3988 +/* 3C */ NULL, NULL, NULL, NULL,
  3989 +/* 40 */ NULL, NULL, NULL, NULL,
  3990 +/* 44 */ NULL, NULL, NULL, NULL,
  3991 +/* 48 */ NULL, NULL, NULL, NULL,
  3992 +/* 4C */ NULL, NULL, NULL, NULL,
  3993 +/* 50 */ NULL, NULL, NULL, NULL,
  3994 +/* 54 */ NULL, NULL, NULL, NULL,
  3995 +/* 58 */ NULL, NULL, NULL, NULL,
  3996 +/* 5C */ NULL, NULL, NULL, NULL,
  3997 +/* 60 */ NULL, NULL, NULL, NULL,
  3998 +/* 64 */ NULL, NULL, NULL, NULL,
  3999 +/* 68 */ NULL, NULL, NULL, NULL,
  4000 +/* 6C */ NULL, NULL, NULL, NULL,
  4001 +/* 70 */ NULL, NULL, NULL, NULL,
  4002 +/* 74 */ NULL, NULL, NULL, NULL,
  4003 +/* 78 */ NULL, NULL, NULL, NULL,
  4004 +/* 7C */ NULL, NULL, NULL, NULL,
  4005 +/* 80 */ NULL, NULL, NULL, NULL,
  4006 +/* 84 */ NULL, NULL, NULL, NULL,
  4007 +/* 88 */ NULL, NULL, "pfnacc", NULL,
  4008 +/* 8C */ NULL, NULL, "pfpnacc", NULL,
  4009 +/* 90 */ "pfcmpge", NULL, NULL, NULL,
  4010 +/* 94 */ "pfmin", NULL, "pfrcp", "pfrsqrt",
  4011 +/* 98 */ NULL, NULL, "pfsub", NULL,
  4012 +/* 9C */ NULL, NULL, "pfadd", NULL,
  4013 +/* A0 */ "pfcmpgt", NULL, NULL, NULL,
  4014 +/* A4 */ "pfmax", NULL, "pfrcpit1", "pfrsqit1",
  4015 +/* A8 */ NULL, NULL, "pfsubr", NULL,
  4016 +/* AC */ NULL, NULL, "pfacc", NULL,
  4017 +/* B0 */ "pfcmpeq", NULL, NULL, NULL,
  4018 +/* B4 */ "pfmul", NULL, "pfrcpit2", "pfmulhrw",
  4019 +/* B8 */ NULL, NULL, NULL, "pswapd",
  4020 +/* BC */ NULL, NULL, NULL, "pavgusb",
  4021 +/* C0 */ NULL, NULL, NULL, NULL,
  4022 +/* C4 */ NULL, NULL, NULL, NULL,
  4023 +/* C8 */ NULL, NULL, NULL, NULL,
  4024 +/* CC */ NULL, NULL, NULL, NULL,
  4025 +/* D0 */ NULL, NULL, NULL, NULL,
  4026 +/* D4 */ NULL, NULL, NULL, NULL,
  4027 +/* D8 */ NULL, NULL, NULL, NULL,
  4028 +/* DC */ NULL, NULL, NULL, NULL,
  4029 +/* E0 */ NULL, NULL, NULL, NULL,
  4030 +/* E4 */ NULL, NULL, NULL, NULL,
  4031 +/* E8 */ NULL, NULL, NULL, NULL,
  4032 +/* EC */ NULL, NULL, NULL, NULL,
  4033 +/* F0 */ NULL, NULL, NULL, NULL,
  4034 +/* F4 */ NULL, NULL, NULL, NULL,
  4035 +/* F8 */ NULL, NULL, NULL, NULL,
  4036 +/* FC */ NULL, NULL, NULL, NULL,
  4037 +};
  4038 +
  4039 +static void
  4040 +OP_3DNowSuffix (bytemode, sizeflag)
  4041 + int bytemode;
  4042 + int sizeflag;
  4043 +{
  4044 + const char *mnemonic;
  4045 +
  4046 + FETCH_DATA (the_info, codep + 1);
  4047 + /* AMD 3DNow! instructions are specified by an opcode suffix in the
  4048 + place where an 8-bit immediate would normally go. ie. the last
  4049 + byte of the instruction. */
  4050 + obufp = obuf + strlen (obuf);
  4051 + mnemonic = Suffix3DNow[*codep++ & 0xff];
  4052 + if (mnemonic)
  4053 + oappend (mnemonic);
  4054 + else
  4055 + {
  4056 + /* Since a variable sized modrm/sib chunk is between the start
  4057 + of the opcode (0x0f0f) and the opcode suffix, we need to do
  4058 + all the modrm processing first, and don't know until now that
  4059 + we have a bad opcode. This necessitates some cleaning up. */
  4060 + op1out[0] = '\0';
  4061 + op2out[0] = '\0';
  4062 + BadOp ();
  4063 + }
  4064 +}
  4065 +
  4066 +static const char *simd_cmp_op[] = {
  4067 + "eq",
  4068 + "lt",
  4069 + "le",
  4070 + "unord",
  4071 + "neq",
  4072 + "nlt",
  4073 + "nle",
  4074 + "ord"
  4075 +};
  4076 +
  4077 +static void
  4078 +OP_SIMD_Suffix (bytemode, sizeflag)
  4079 + int bytemode;
  4080 + int sizeflag;
  4081 +{
  4082 + unsigned int cmp_type;
  4083 +
  4084 + FETCH_DATA (the_info, codep + 1);
  4085 + obufp = obuf + strlen (obuf);
  4086 + cmp_type = *codep++ & 0xff;
  4087 + if (cmp_type < 8)
  4088 + {
  4089 + char suffix1 = 'p', suffix2 = 's';
  4090 + used_prefixes |= (prefixes & PREFIX_REPZ);
  4091 + if (prefixes & PREFIX_REPZ)
  4092 + suffix1 = 's';
  4093 + else
  4094 + {
  4095 + used_prefixes |= (prefixes & PREFIX_DATA);
  4096 + if (prefixes & PREFIX_DATA)
  4097 + suffix2 = 'd';
  4098 + else
  4099 + {
  4100 + used_prefixes |= (prefixes & PREFIX_REPNZ);
  4101 + if (prefixes & PREFIX_REPNZ)
  4102 + suffix1 = 's', suffix2 = 'd';
  4103 + }
  4104 + }
  4105 + sprintf (scratchbuf, "cmp%s%c%c",
  4106 + simd_cmp_op[cmp_type], suffix1, suffix2);
  4107 + used_prefixes |= (prefixes & PREFIX_REPZ);
  4108 + oappend (scratchbuf);
  4109 + }
  4110 + else
  4111 + {
  4112 + /* We have a bad extension byte. Clean up. */
  4113 + op1out[0] = '\0';
  4114 + op2out[0] = '\0';
  4115 + BadOp ();
  4116 + }
  4117 +}
  4118 +
  4119 +static void
  4120 +SIMD_Fixup (extrachar, sizeflag)
  4121 + int extrachar;
  4122 + int sizeflag;
  4123 +{
  4124 + /* Change movlps/movhps to movhlps/movlhps for 2 register operand
  4125 + forms of these instructions. */
  4126 + if (mod == 3)
  4127 + {
  4128 + char *p = obuf + strlen (obuf);
  4129 + *(p + 1) = '\0';
  4130 + *p = *(p - 1);
  4131 + *(p - 1) = *(p - 2);
  4132 + *(p - 2) = *(p - 3);
  4133 + *(p - 3) = extrachar;
  4134 + }
  4135 +}
  4136 +
  4137 +static void
  4138 +BadOp (void)
  4139 +{
  4140 + /* Throw away prefixes and 1st. opcode byte. */
  4141 + codep = insn_codep + 1;
  4142 + oappend ("(bad)");
2300 4143 }
... ...
linux-user/mmap.c
... ... @@ -188,7 +188,7 @@ long target_mmap(unsigned long start, unsigned long len, int prot,
188 188 host_start = start & host_page_mask;
189 189  
190 190 if (!(flags & MAP_FIXED)) {
191   -#if defined(__alpha__) || defined(__sparc__)
  191 +#if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__)
192 192 /* tell the kenel to search at the same place as i386 */
193 193 if (host_start == 0)
194 194 host_start = 0x40000000;
... ...
linux-user/syscall.c
... ... @@ -207,7 +207,7 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \
207 207 #define __NR_sys_getdents64 __NR_getdents64
208 208 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo
209 209  
210   -#if defined(__alpha__) || defined (__ia64__)
  210 +#if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__)
211 211 #define __NR__llseek __NR_lseek
212 212 #endif
213 213  
... ...
target-i386/cpu.h
... ... @@ -252,7 +252,7 @@ enum {
252 252 CC_OP_NB,
253 253 };
254 254  
255   -#ifdef __i386__
  255 +#if defined(__i386__) || defined(__x86_64__)
256 256 #define USE_X86LDOUBLE
257 257 #endif
258 258  
... ...
target-i386/helper.c
... ... @@ -1802,14 +1802,14 @@ void helper_invlpg(unsigned int addr)
1802 1802 }
1803 1803  
1804 1804 /* rdtsc */
1805   -#ifndef __i386__
  1805 +#if !defined(__i386__) && !defined(__x86_64__)
1806 1806 uint64_t emu_time;
1807 1807 #endif
1808 1808  
1809 1809 void helper_rdtsc(void)
1810 1810 {
1811 1811 uint64_t val;
1812   -#ifdef __i386__
  1812 +#if defined(__i386__) || defined(__x86_64__)
1813 1813 asm("rdtsc" : "=A" (val));
1814 1814 #else
1815 1815 /* better than nothing: the time increases */
... ...