Commit dc99065b5f97cc0410f88e3f90c7440531a55f9f

Authored by bellard
1 parent ca735206

added flags computation optimization


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@34 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
... ... @@ -33,7 +33,7 @@ LIBS+=-ldl -lm
33 33 # profiling code
34 34 ifdef TARGET_GPROF
35 35 LDFLAGS+=-p
36   -CFLAGS+=-p
  36 +main.o: CFLAGS+=-p
37 37 endif
38 38  
39 39 OBJS= elfload.o main.o thunk.o syscall.o
... ...
1   -- optimize translated cache chaining (DLL PLT like system)
2   -- improved 16 bit support
3   -- optimize inverse flags propagation (easy by generating intermediate
4   - micro operation array).
  1 +- optimize translated cache chaining (DLL PLT-like system)
  2 +- 64 bit syscalls
5 3 - signals
6 4 - threads
7 5 - make it self runnable (use same trick as ld.so : include its own relocator and libc)
  6 +- improved 16 bit support
8 7 - fix FPU exceptions (in particular: gen_op_fpush not before mem load)
9   -- tests
... ...
dis-asm.h 0 → 100644
  1 +/* Interface between the opcode library and its callers.
  2 + Written by Cygnus Support, 1993.
  3 +
  4 + The opcode library (libopcodes.a) provides instruction decoders for
  5 + a large variety of instruction sets, callable with an identical
  6 + interface, for making instruction-processing programs more independent
  7 + of the instruction set being processed. */
  8 +
  9 +#ifndef DIS_ASM_H
  10 +#define DIS_ASM_H
  11 +
  12 +#include <stdio.h>
  13 +#include "bfd.h"
  14 +
  15 +typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
  16 +
  17 +enum dis_insn_type {
  18 + dis_noninsn, /* Not a valid instruction */
  19 + dis_nonbranch, /* Not a branch instruction */
  20 + dis_branch, /* Unconditional branch */
  21 + dis_condbranch, /* Conditional branch */
  22 + dis_jsr, /* Jump to subroutine */
  23 + dis_condjsr, /* Conditional jump to subroutine */
  24 + dis_dref, /* Data reference instruction */
  25 + dis_dref2 /* Two data references in instruction */
  26 +};
  27 +
  28 +/* This struct is passed into the instruction decoding routine,
  29 + and is passed back out into each callback. The various fields are used
  30 + for conveying information from your main routine into your callbacks,
  31 + for passing information into the instruction decoders (such as the
  32 + addresses of the callback functions), or for passing information
  33 + back from the instruction decoders to their callers.
  34 +
  35 + It must be initialized before it is first passed; this can be done
  36 + by hand, or using one of the initialization macros below. */
  37 +
  38 +typedef struct disassemble_info {
  39 + fprintf_ftype fprintf_func;
  40 + FILE *stream;
  41 + PTR application_data;
  42 +
  43 + /* Target description. We could replace this with a pointer to the bfd,
  44 + but that would require one. There currently isn't any such requirement
  45 + so to avoid introducing one we record these explicitly. */
  46 + /* The bfd_flavour. This can be bfd_target_unknown_flavour. */
  47 + enum bfd_flavour flavour;
  48 + /* The bfd_arch value. */
  49 + enum bfd_architecture arch;
  50 + /* The bfd_mach value. */
  51 + unsigned long mach;
  52 + /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
  53 + enum bfd_endian endian;
  54 +
  55 + /* An array of pointers to symbols either at the location being disassembled
  56 + or at the start of the function being disassembled. The array is sorted
  57 + so that the first symbol is intended to be the one used. The others are
  58 + present for any misc. purposes. This is not set reliably, but if it is
  59 + not NULL, it is correct. */
  60 + asymbol **symbols;
  61 + /* Number of symbols in array. */
  62 + int num_symbols;
  63 +
  64 + /* For use by the disassembler.
  65 + The top 16 bits are reserved for public use (and are documented here).
  66 + The bottom 16 bits are for the internal use of the disassembler. */
  67 + unsigned long flags;
  68 +#define INSN_HAS_RELOC 0x80000000
  69 + PTR private_data;
  70 +
  71 + /* Function used to get bytes to disassemble. MEMADDR is the
  72 + address of the stuff to be disassembled, MYADDR is the address to
  73 + put the bytes in, and LENGTH is the number of bytes to read.
  74 + INFO is a pointer to this struct.
  75 + Returns an errno value or 0 for success. */
  76 + int (*read_memory_func)
  77 + PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, int length,
  78 + struct disassemble_info *info));
  79 +
  80 + /* Function which should be called if we get an error that we can't
  81 + recover from. STATUS is the errno value from read_memory_func and
  82 + MEMADDR is the address that we were trying to read. INFO is a
  83 + pointer to this struct. */
  84 + void (*memory_error_func)
  85 + PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
  86 +
  87 + /* Function called to print ADDR. */
  88 + void (*print_address_func)
  89 + PARAMS ((bfd_vma addr, struct disassemble_info *info));
  90 +
  91 + /* Function called to determine if there is a symbol at the given ADDR.
  92 + If there is, the function returns 1, otherwise it returns 0.
  93 + This is used by ports which support an overlay manager where
  94 + the overlay number is held in the top part of an address. In
  95 + some circumstances we want to include the overlay number in the
  96 + address, (normally because there is a symbol associated with
  97 + that address), but sometimes we want to mask out the overlay bits. */
  98 + int (* symbol_at_address_func)
  99 + PARAMS ((bfd_vma addr, struct disassemble_info * info));
  100 +
  101 + /* These are for buffer_read_memory. */
  102 + bfd_byte *buffer;
  103 + bfd_vma buffer_vma;
  104 + int buffer_length;
  105 +
  106 + /* This variable may be set by the instruction decoder. It suggests
  107 + the number of bytes objdump should display on a single line. If
  108 + the instruction decoder sets this, it should always set it to
  109 + the same value in order to get reasonable looking output. */
  110 + int bytes_per_line;
  111 +
  112 + /* the next two variables control the way objdump displays the raw data */
  113 + /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
  114 + /* output will look like this:
  115 + 00: 00000000 00000000
  116 + with the chunks displayed according to "display_endian". */
  117 + int bytes_per_chunk;
  118 + enum bfd_endian display_endian;
  119 +
  120 + /* Results from instruction decoders. Not all decoders yet support
  121 + this information. This info is set each time an instruction is
  122 + decoded, and is only valid for the last such instruction.
  123 +
  124 + To determine whether this decoder supports this information, set
  125 + insn_info_valid to 0, decode an instruction, then check it. */
  126 +
  127 + char insn_info_valid; /* Branch info has been set. */
  128 + char branch_delay_insns; /* How many sequential insn's will run before
  129 + a branch takes effect. (0 = normal) */
  130 + char data_size; /* Size of data reference in insn, in bytes */
  131 + enum dis_insn_type insn_type; /* Type of instruction */
  132 + bfd_vma target; /* Target address of branch or dref, if known;
  133 + zero if unknown. */
  134 + bfd_vma target2; /* Second target address for dref2 */
  135 +
  136 +} disassemble_info;
  137 +
  138 +
  139 +/* Standard disassemblers. Disassemble one instruction at the given
  140 + target address. Return number of bytes processed. */
  141 +typedef int (*disassembler_ftype)
  142 + PARAMS((bfd_vma, disassemble_info *));
  143 +
  144 +extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
  145 +extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
  146 +extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info*));
  147 +extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
  148 +extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
  149 +extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
  150 +extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
  151 +extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
  152 +extern int print_insn_h8300s PARAMS ((bfd_vma, disassemble_info*));
  153 +extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
  154 +extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
  155 +extern disassembler_ftype arc_get_disassembler PARAMS ((int, int));
  156 +extern int print_insn_big_arm PARAMS ((bfd_vma, disassemble_info*));
  157 +extern int print_insn_little_arm PARAMS ((bfd_vma, disassemble_info*));
  158 +extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
  159 +extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
  160 +extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
  161 +extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
  162 +extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
  163 +extern int print_insn_shl PARAMS ((bfd_vma, disassemble_info*));
  164 +extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
  165 +extern int print_insn_m32r PARAMS ((bfd_vma, disassemble_info*));
  166 +extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
  167 +extern int print_insn_mn10200 PARAMS ((bfd_vma, disassemble_info*));
  168 +extern int print_insn_mn10300 PARAMS ((bfd_vma, disassemble_info*));
  169 +extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
  170 +extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
  171 +extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
  172 +extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
  173 +extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
  174 +extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*));
  175 +extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
  176 +extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
  177 +
  178 +/* Fetch the disassembler for a given BFD, if that support is available. */
  179 +extern disassembler_ftype disassembler PARAMS ((bfd *));
  180 +
  181 +
  182 +/* This block of definitions is for particular callers who read instructions
  183 + into a buffer before calling the instruction decoder. */
  184 +
  185 +/* Here is a function which callers may wish to use for read_memory_func.
  186 + It gets bytes from a buffer. */
  187 +extern int buffer_read_memory
  188 + PARAMS ((bfd_vma, bfd_byte *, int, struct disassemble_info *));
  189 +
  190 +/* This function goes with buffer_read_memory.
  191 + It prints a message using info->fprintf_func and info->stream. */
  192 +extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
  193 +
  194 +
  195 +/* Just print the address in hex. This is included for completeness even
  196 + though both GDB and objdump provide their own (to print symbolic
  197 + addresses). */
  198 +extern void generic_print_address
  199 + PARAMS ((bfd_vma, struct disassemble_info *));
  200 +
  201 +/* Always true. */
  202 +extern int generic_symbol_at_address
  203 + PARAMS ((bfd_vma, struct disassemble_info *));
  204 +
  205 +/* Macro to initialize a disassemble_info struct. This should be called
  206 + by all applications creating such a struct. */
  207 +#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
  208 + (INFO).flavour = bfd_target_unknown_flavour, \
  209 + (INFO).arch = bfd_arch_unknown, \
  210 + (INFO).mach = 0, \
  211 + (INFO).endian = BFD_ENDIAN_UNKNOWN, \
  212 + INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC)
  213 +
  214 +/* Call this macro to initialize only the internal variables for the
  215 + disassembler. Architecture dependent things such as byte order, or machine
  216 + variant are not touched by this macro. This makes things much easier for
  217 + GDB which must initialize these things seperatly. */
  218 +
  219 +#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
  220 + (INFO).fprintf_func = (FPRINTF_FUNC), \
  221 + (INFO).stream = (STREAM), \
  222 + (INFO).symbols = NULL, \
  223 + (INFO).num_symbols = 0, \
  224 + (INFO).buffer = NULL, \
  225 + (INFO).buffer_vma = 0, \
  226 + (INFO).buffer_length = 0, \
  227 + (INFO).read_memory_func = buffer_read_memory, \
  228 + (INFO).memory_error_func = perror_memory, \
  229 + (INFO).print_address_func = generic_print_address, \
  230 + (INFO).symbol_at_address_func = generic_symbol_at_address, \
  231 + (INFO).flags = 0, \
  232 + (INFO).bytes_per_line = 0, \
  233 + (INFO).bytes_per_chunk = 0, \
  234 + (INFO).display_endian = BFD_ENDIAN_UNKNOWN, \
  235 + (INFO).insn_info_valid = 0
  236 +
  237 +#endif /* ! defined (DIS_ASM_H) */
... ...
dis-buf.c 0 → 100644
  1 +/* Disassemble from a buffer, for GNU.
  2 + Copyright (C) 1993, 1994 Free Software Foundation, Inc.
  3 +
  4 +This program is free software; you can redistribute it and/or modify
  5 +it under the terms of the GNU General Public License as published by
  6 +the Free Software Foundation; either version 2 of the License, or
  7 +(at your option) any later version.
  8 +
  9 +This program is distributed in the hope that it will be useful,
  10 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 +GNU General Public License for more details.
  13 +
  14 +You should have received a copy of the GNU General Public License
  15 +along with this program; if not, write to the Free Software
  16 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  17 +
  18 +#include "dis-asm.h"
  19 +#include <errno.h>
  20 +
  21 +/* Get LENGTH bytes from info's buffer, at target address memaddr.
  22 + Transfer them to myaddr. */
  23 +int
  24 +buffer_read_memory (memaddr, myaddr, length, info)
  25 + bfd_vma memaddr;
  26 + bfd_byte *myaddr;
  27 + int length;
  28 + struct disassemble_info *info;
  29 +{
  30 + if (memaddr < info->buffer_vma
  31 + || memaddr + length > info->buffer_vma + info->buffer_length)
  32 + /* Out of bounds. Use EIO because GDB uses it. */
  33 + return EIO;
  34 + memcpy (myaddr, info->buffer + (memaddr - info->buffer_vma), length);
  35 + return 0;
  36 +}
  37 +
  38 +/* Print an error message. We can assume that this is in response to
  39 + an error return from buffer_read_memory. */
  40 +void
  41 +perror_memory (status, memaddr, info)
  42 + int status;
  43 + bfd_vma memaddr;
  44 + struct disassemble_info *info;
  45 +{
  46 + if (status != EIO)
  47 + /* Can't happen. */
  48 + (*info->fprintf_func) (info->stream, "Unknown error %d\n", status);
  49 + else
  50 + /* Actually, address between memaddr and memaddr + len was
  51 + out of bounds. */
  52 + (*info->fprintf_func) (info->stream,
  53 + "Address 0x%x is out of bounds.\n", memaddr);
  54 +}
  55 +
  56 +/* This could be in a separate file, to save miniscule amounts of space
  57 + in statically linked executables. */
  58 +
  59 +/* Just print the address is hex. This is included for completeness even
  60 + though both GDB and objdump provide their own (to print symbolic
  61 + addresses). */
  62 +
  63 +void
  64 +generic_print_address (addr, info)
  65 + bfd_vma addr;
  66 + struct disassemble_info *info;
  67 +{
  68 + (*info->fprintf_func) (info->stream, "0x%x", addr);
  69 +}
  70 +
  71 +/* Just return the given address. */
  72 +
  73 +int
  74 +generic_symbol_at_address (addr, info)
  75 + bfd_vma addr;
  76 + struct disassemble_info * info;
  77 +{
  78 + return 1;
  79 +}
... ...
dyngen.c
... ... @@ -28,7 +28,7 @@
28 28 #include "thunk.h"
29 29  
30 30 /* all dynamically generated functions begin with this code */
31   -#define OP_PREFIX "op"
  31 +#define OP_PREFIX "op_"
32 32  
33 33 int elf_must_swap(Elf32_Ehdr *h)
34 34 {
... ... @@ -201,7 +201,7 @@ int strstart(const char *str, const char *val, const char **ptr)
201 201 /* generate op code */
202 202 void gen_code(const char *name, unsigned long offset, unsigned long size,
203 203 FILE *outfile, uint8_t *text, void *relocs, int nb_relocs, int reloc_sh_type,
204   - Elf32_Sym *symtab, char *strtab)
  204 + Elf32_Sym *symtab, char *strtab, int gen_switch)
205 205 {
206 206 int copy_size = 0;
207 207 uint8_t *p_start, *p_end;
... ... @@ -258,8 +258,6 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
258 258 if (n >= MAX_ARGS)
259 259 error("too many arguments in %s", name);
260 260 args_present[n - 1] = 1;
261   - } else {
262   - fprintf(outfile, "extern char %s;\n", sym_name);
263 261 }
264 262 }
265 263 }
... ... @@ -274,8 +272,6 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
274 272 if (n >= MAX_ARGS)
275 273 error("too many arguments in %s", name);
276 274 args_present[n - 1] = 1;
277   - } else {
278   - fprintf(outfile, "extern char %s;\n", sym_name);
279 275 }
280 276 }
281 277 }
... ... @@ -289,33 +285,59 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
289 285 error("inconsistent argument numbering in %s", name);
290 286 }
291 287  
292   - /* output C code */
293   - fprintf(outfile, "extern void %s();\n", name);
294   - fprintf(outfile, "static inline void gen_%s(", name);
295   - if (nb_args == 0) {
296   - fprintf(outfile, "void");
297   - } else {
298   - for(i = 0; i < nb_args; i++) {
299   - if (i != 0)
300   - fprintf(outfile, ", ");
301   - fprintf(outfile, "long param%d", i + 1);
  288 + if (gen_switch) {
  289 +
  290 + /* output C code */
  291 + fprintf(outfile, "case INDEX_%s: {\n", name);
  292 + if (nb_args > 0) {
  293 + fprintf(outfile, " long ");
  294 + for(i = 0; i < nb_args; i++) {
  295 + if (i != 0)
  296 + fprintf(outfile, ", ");
  297 + fprintf(outfile, "param%d", i + 1);
  298 + }
  299 + fprintf(outfile, ";\n");
302 300 }
303   - }
304   - fprintf(outfile, ")\n");
305   - fprintf(outfile, "{\n");
306   - fprintf(outfile, " memcpy(gen_code_ptr, &%s, %d);\n", name, copy_size);
307   -
308   - /* patch relocations */
309   - switch(e_machine) {
310   - case EM_386:
311   - {
  301 + fprintf(outfile, " extern void %s();\n", name);
  302 +
  303 + if (reloc_sh_type == SHT_REL) {
312 304 Elf32_Rel *rel;
313   - char name[256];
314   - int type;
315   - long addend;
316 305 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
317 306 if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
318 307 sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
  308 + if (!strstart(sym_name, "__op_param", &p)) {
  309 + fprintf(outfile, "extern char %s;\n", sym_name);
  310 + }
  311 + }
  312 + }
  313 + } else {
  314 + Elf32_Rela *rel;
  315 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  316 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  317 + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
  318 + if (!strstart(sym_name, "__op_param", &p)) {
  319 + fprintf(outfile, "extern char %s;\n", sym_name);
  320 + }
  321 + }
  322 + }
  323 + }
  324 +
  325 + fprintf(outfile, " memcpy(gen_code_ptr, &%s, %d);\n", name, copy_size);
  326 + for(i = 0; i < nb_args; i++) {
  327 + fprintf(outfile, " param%d = *opparam_ptr++;\n", i + 1);
  328 + }
  329 +
  330 + /* patch relocations */
  331 + switch(e_machine) {
  332 + case EM_386:
  333 + {
  334 + Elf32_Rel *rel;
  335 + char name[256];
  336 + int type;
  337 + long addend;
  338 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  339 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  340 + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
319 341 if (strstart(sym_name, "__op_param", &p)) {
320 342 snprintf(name, sizeof(name), "param%s", p);
321 343 } else {
... ... @@ -336,20 +358,38 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
336 358 error("unsupported i386 relocation (%d)", type);
337 359 }
338 360 }
  361 + }
  362 + }
  363 + break;
  364 + default:
  365 + error("unsupported CPU for relocations (%d)", e_machine);
  366 + }
  367 + fprintf(outfile, " gen_code_ptr += %d;\n", copy_size);
  368 + fprintf(outfile, "}\n");
  369 + fprintf(outfile, "break;\n\n");
  370 + } else {
  371 + fprintf(outfile, "static inline void gen_%s(", name);
  372 + if (nb_args == 0) {
  373 + fprintf(outfile, "void");
  374 + } else {
  375 + for(i = 0; i < nb_args; i++) {
  376 + if (i != 0)
  377 + fprintf(outfile, ", ");
  378 + fprintf(outfile, "long param%d", i + 1);
339 379 }
340 380 }
341   - break;
342   - default:
343   - error("unsupported CPU for relocations (%d)", e_machine);
  381 + fprintf(outfile, ")\n");
  382 + fprintf(outfile, "{\n");
  383 + for(i = 0; i < nb_args; i++) {
  384 + fprintf(outfile, " *gen_opparam_ptr++ = param%d;\n", i + 1);
  385 + }
  386 + fprintf(outfile, " *gen_opc_ptr++ = INDEX_%s;\n", name);
  387 + fprintf(outfile, "}\n\n");
344 388 }
345   -
346   -
347   - fprintf(outfile, " gen_code_ptr += %d;\n", copy_size);
348   - fprintf(outfile, "}\n\n");
349 389 }
350 390  
351 391 /* load an elf object file */
352   -int load_elf(const char *filename, FILE *outfile)
  392 +int load_elf(const char *filename, FILE *outfile, int do_print_enum)
353 393 {
354 394 int fd;
355 395 Elf32_Ehdr ehdr;
... ... @@ -476,23 +516,77 @@ int load_elf(const char *filename, FILE *outfile)
476 516 error("unsupported CPU (e_machine=%d)", e_machine);
477 517 }
478 518  
479   - fprintf(outfile, "#include \"gen-%s.h\"\n\n", cpu_name);
  519 + if (do_print_enum) {
  520 + fprintf(outfile, "DEF(end)\n");
  521 + for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
  522 + const char *name, *p;
  523 + name = strtab + sym->st_name;
  524 + if (strstart(name, OP_PREFIX, &p)) {
  525 + fprintf(outfile, "DEF(%s)\n", p);
  526 + }
  527 + }
  528 + } else {
  529 + /* generate big code generation switch */
  530 +fprintf(outfile,
  531 +"int dyngen_code(uint8_t *gen_code_buf,\n"
  532 +" const uint16_t *opc_buf, const uint32_t *opparam_buf)\n"
  533 +"{\n"
  534 +" uint8_t *gen_code_ptr;\n"
  535 +" const uint16_t *opc_ptr;\n"
  536 +" const uint32_t *opparam_ptr;\n"
  537 +" gen_code_ptr = gen_code_buf;\n"
  538 +" opc_ptr = opc_buf;\n"
  539 +" opparam_ptr = opparam_buf;\n"
  540 +" for(;;) {\n"
  541 +" switch(*opc_ptr++) {\n"
  542 +);
480 543  
481   - for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
482   - const char *name;
483   - name = strtab + sym->st_name;
484   - if (strstart(name, "op_", NULL) ||
485   - strstart(name, "op1_", NULL) ||
486   - strstart(name, "op2_", NULL) ||
487   - strstart(name, "op3_", NULL)) {
  544 + for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
  545 + const char *name;
  546 + name = strtab + sym->st_name;
  547 + if (strstart(name, OP_PREFIX, NULL)) {
488 548 #if 0
489   - printf("%4d: %s pos=0x%08x len=%d\n",
490   - i, name, sym->st_value, sym->st_size);
  549 + printf("%4d: %s pos=0x%08x len=%d\n",
  550 + i, name, sym->st_value, sym->st_size);
491 551 #endif
492   - if (sym->st_shndx != (text_sec - shdr))
493   - error("invalid section for opcode (0x%x)", sym->st_shndx);
494   - gen_code(name, sym->st_value, sym->st_size, outfile,
495   - text, relocs, nb_relocs, reloc_sh_type, symtab, strtab);
  552 + if (sym->st_shndx != (text_sec - shdr))
  553 + error("invalid section for opcode (0x%x)", sym->st_shndx);
  554 + gen_code(name, sym->st_value, sym->st_size, outfile,
  555 + text, relocs, nb_relocs, reloc_sh_type, symtab, strtab, 1);
  556 + }
  557 + }
  558 +
  559 +fprintf(outfile,
  560 +" default:\n"
  561 +" goto the_end;\n"
  562 +" }\n"
  563 +" }\n"
  564 +" the_end:\n"
  565 +);
  566 +
  567 +/* generate a return */
  568 + switch(e_machine) {
  569 + case EM_386:
  570 + fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");
  571 + break;
  572 + default:
  573 + error("no return generation for cpu '%s'", cpu_name);
  574 + }
  575 +
  576 + fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");
  577 + fprintf(outfile, "}\n\n");
  578 +
  579 +/* generate gen_xxx functions */
  580 +/* XXX: suppress the use of these functions to simplify code */
  581 + for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
  582 + const char *name;
  583 + name = strtab + sym->st_name;
  584 + if (strstart(name, OP_PREFIX, NULL)) {
  585 + if (sym->st_shndx != (text_sec - shdr))
  586 + error("invalid section for opcode (0x%x)", sym->st_shndx);
  587 + gen_code(name, sym->st_value, sym->st_size, outfile,
  588 + text, relocs, nb_relocs, reloc_sh_type, symtab, strtab, 0);
  589 + }
496 590 }
497 591 }
498 592  
... ... @@ -503,20 +597,23 @@ int load_elf(const char *filename, FILE *outfile)
503 597 void usage(void)
504 598 {
505 599 printf("dyngen (c) 2003 Fabrice Bellard\n"
506   - "usage: dyngen [-o outfile] objfile\n"
507   - "Generate a dynamic code generator from an object file\n");
  600 + "usage: dyngen [-o outfile] [-c] objfile\n"
  601 + "Generate a dynamic code generator from an object file\n"
  602 + "-c output enum of operations\n"
  603 + );
508 604 exit(1);
509 605 }
510 606  
511 607 int main(int argc, char **argv)
512 608 {
513   - int c;
  609 + int c, do_print_enum;
514 610 const char *filename, *outfilename;
515 611 FILE *outfile;
516 612  
517 613 outfilename = "out.c";
  614 + do_print_enum = 0;
518 615 for(;;) {
519   - c = getopt(argc, argv, "ho:");
  616 + c = getopt(argc, argv, "ho:c");
520 617 if (c == -1)
521 618 break;
522 619 switch(c) {
... ... @@ -526,6 +623,9 @@ int main(int argc, char **argv)
526 623 case 'o':
527 624 outfilename = optarg;
528 625 break;
  626 + case 'c':
  627 + do_print_enum = 1;
  628 + break;
529 629 }
530 630 }
531 631 if (optind >= argc)
... ... @@ -534,7 +634,7 @@ int main(int argc, char **argv)
534 634 outfile = fopen(outfilename, "w");
535 635 if (!outfile)
536 636 error("could not open '%s'", outfilename);
537   - load_elf(filename, outfile);
  637 + load_elf(filename, outfile, do_print_enum);
538 638 fclose(outfile);
539 639 return 0;
540 640 }
... ...
exec-i386.c
... ... @@ -19,7 +19,7 @@
19 19 */
20 20 #include "exec-i386.h"
21 21  
22   -#define DEBUG_EXEC
  22 +//#define DEBUG_EXEC
23 23 #define DEBUG_FLUSH
24 24  
25 25 /* main execution loop */
... ...
gen-i386.h
1   -static inline void gen_start(void)
2   -{
3   -}
4   -
5   -static inline void gen_end(void)
6   -{
7   - *gen_code_ptr++ = 0xc3; /* ret */
8   -}
i386-dis.c 0 → 100644
  1 +/* Print i386 instructions for GDB, the GNU debugger.
  2 + Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
  3 + Free Software Foundation, Inc.
  4 +
  5 +This file is part of GDB.
  6 +
  7 +This program is free software; you can redistribute it and/or modify
  8 +it under the terms of the GNU General Public License as published by
  9 +the Free Software Foundation; either version 2 of the License, or
  10 +(at your option) any later version.
  11 +
  12 +This program is distributed in the hope that it will be useful,
  13 +but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15 +GNU General Public License for more details.
  16 +
  17 +You should have received a copy of the GNU General Public License
  18 +along with this program; if not, write to the Free Software
  19 +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  20 +
  21 +/*
  22 + * 80386 instruction printer by Pace Willisson (pace@prep.ai.mit.edu)
  23 + * July 1988
  24 + * modified by John Hassey (hassey@dg-rtp.dg.com)
  25 + */
  26 +
  27 +/*
  28 + * The main tables describing the instructions is essentially a copy
  29 + * of the "Opcode Map" chapter (Appendix A) of the Intel 80386
  30 + * Programmers Manual. Usually, there is a capital letter, followed
  31 + * by a small letter. The capital letter tell the addressing mode,
  32 + * and the small letter tells about the operand size. Refer to
  33 + * the Intel manual for details.
  34 + */
  35 +
  36 +#include "dis-asm.h"
  37 +
  38 +#define MAXLEN 20
  39 +
  40 +#include <setjmp.h>
  41 +
  42 +static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
  43 +
  44 +struct dis_private
  45 +{
  46 + /* Points to first byte not fetched. */
  47 + bfd_byte *max_fetched;
  48 + bfd_byte the_buffer[MAXLEN];
  49 + bfd_vma insn_start;
  50 + jmp_buf bailout;
  51 +};
  52 +
  53 +/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
  54 + to ADDR (exclusive) are valid. Returns 1 for success, longjmps
  55 + on error. */
  56 +#define FETCH_DATA(info, addr) \
  57 + ((addr) <= ((struct dis_private *)(info->private_data))->max_fetched \
  58 + ? 1 : fetch_data ((info), (addr)))
  59 +
  60 +static int
  61 +fetch_data (info, addr)
  62 + struct disassemble_info *info;
  63 + bfd_byte *addr;
  64 +{
  65 + int status;
  66 + struct dis_private *priv = (struct dis_private *)info->private_data;
  67 + bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
  68 +
  69 + status = (*info->read_memory_func) (start,
  70 + priv->max_fetched,
  71 + addr - priv->max_fetched,
  72 + info);
  73 + if (status != 0)
  74 + {
  75 + (*info->memory_error_func) (status, start, info);
  76 + longjmp (priv->bailout, 1);
  77 + }
  78 + else
  79 + priv->max_fetched = addr;
  80 + return 1;
  81 +}
  82 +
  83 +#define Eb OP_E, b_mode
  84 +#define indirEb OP_indirE, b_mode
  85 +#define Gb OP_G, b_mode
  86 +#define Ev OP_E, v_mode
  87 +#define indirEv OP_indirE, v_mode
  88 +#define Ew OP_E, w_mode
  89 +#define Ma OP_E, v_mode
  90 +#define M OP_E, 0
  91 +#define Mp OP_E, 0 /* ? */
  92 +#define Gv OP_G, v_mode
  93 +#define Gw OP_G, w_mode
  94 +#define Rw OP_rm, w_mode
  95 +#define Rd OP_rm, d_mode
  96 +#define Ib OP_I, b_mode
  97 +#define sIb OP_sI, b_mode /* sign extened byte */
  98 +#define Iv OP_I, v_mode
  99 +#define Iw OP_I, w_mode
  100 +#define Jb OP_J, b_mode
  101 +#define Jv OP_J, v_mode
  102 +#if 0
  103 +#define ONE OP_ONE, 0
  104 +#endif
  105 +#define Cd OP_C, d_mode
  106 +#define Dd OP_D, d_mode
  107 +#define Td OP_T, d_mode
  108 +
  109 +#define eAX OP_REG, eAX_reg
  110 +#define eBX OP_REG, eBX_reg
  111 +#define eCX OP_REG, eCX_reg
  112 +#define eDX OP_REG, eDX_reg
  113 +#define eSP OP_REG, eSP_reg
  114 +#define eBP OP_REG, eBP_reg
  115 +#define eSI OP_REG, eSI_reg
  116 +#define eDI OP_REG, eDI_reg
  117 +#define AL OP_REG, al_reg
  118 +#define CL OP_REG, cl_reg
  119 +#define DL OP_REG, dl_reg
  120 +#define BL OP_REG, bl_reg
  121 +#define AH OP_REG, ah_reg
  122 +#define CH OP_REG, ch_reg
  123 +#define DH OP_REG, dh_reg
  124 +#define BH OP_REG, bh_reg
  125 +#define AX OP_REG, ax_reg
  126 +#define DX OP_REG, dx_reg
  127 +#define indirDX OP_REG, indir_dx_reg
  128 +
  129 +#define Sw OP_SEG, w_mode
  130 +#define Ap OP_DIR, lptr
  131 +#define Av OP_DIR, v_mode
  132 +#define Ob OP_OFF, b_mode
  133 +#define Ov OP_OFF, v_mode
  134 +#define Xb OP_DSSI, b_mode
  135 +#define Xv OP_DSSI, v_mode
  136 +#define Yb OP_ESDI, b_mode
  137 +#define Yv OP_ESDI, v_mode
  138 +
  139 +#define es OP_REG, es_reg
  140 +#define ss OP_REG, ss_reg
  141 +#define cs OP_REG, cs_reg
  142 +#define ds OP_REG, ds_reg
  143 +#define fs OP_REG, fs_reg
  144 +#define gs OP_REG, gs_reg
  145 +
  146 +#define MX OP_MMX, 0
  147 +#define EM OP_EM, v_mode
  148 +#define MS OP_MS, b_mode
  149 +
  150 +typedef int (*op_rtn) PARAMS ((int bytemode, int aflag, int dflag));
  151 +
  152 +static int OP_E PARAMS ((int, int, int));
  153 +static int OP_G PARAMS ((int, int, int));
  154 +static int OP_I PARAMS ((int, int, int));
  155 +static int OP_indirE PARAMS ((int, int, int));
  156 +static int OP_sI PARAMS ((int, int, int));
  157 +static int OP_REG PARAMS ((int, int, int));
  158 +static int OP_J PARAMS ((int, int, int));
  159 +static int OP_DIR PARAMS ((int, int, int));
  160 +static int OP_OFF PARAMS ((int, int, int));
  161 +static int OP_ESDI PARAMS ((int, int, int));
  162 +static int OP_DSSI PARAMS ((int, int, int));
  163 +static int OP_SEG PARAMS ((int, int, int));
  164 +static int OP_C PARAMS ((int, int, int));
  165 +static int OP_D PARAMS ((int, int, int));
  166 +static int OP_T PARAMS ((int, int, int));
  167 +static int OP_rm PARAMS ((int, int, int));
  168 +static int OP_ST PARAMS ((int, int, int));
  169 +static int OP_STi PARAMS ((int, int, int));
  170 +#if 0
  171 +static int OP_ONE PARAMS ((int, int, int));
  172 +#endif
  173 +static int OP_MMX PARAMS ((int, int, int));
  174 +static int OP_EM PARAMS ((int, int, int));
  175 +static int OP_MS PARAMS ((int, int, int));
  176 +
  177 +static void append_prefix PARAMS ((void));
  178 +static void set_op PARAMS ((int op));
  179 +static void putop PARAMS ((char *template, int aflag, int dflag));
  180 +static void dofloat PARAMS ((int aflag, int dflag));
  181 +static int get16 PARAMS ((void));
  182 +static int get32 PARAMS ((void));
  183 +static void ckprefix PARAMS ((void));
  184 +
  185 +#define b_mode 1
  186 +#define v_mode 2
  187 +#define w_mode 3
  188 +#define d_mode 4
  189 +
  190 +#define es_reg 100
  191 +#define cs_reg 101
  192 +#define ss_reg 102
  193 +#define ds_reg 103
  194 +#define fs_reg 104
  195 +#define gs_reg 105
  196 +#define eAX_reg 107
  197 +#define eCX_reg 108
  198 +#define eDX_reg 109
  199 +#define eBX_reg 110
  200 +#define eSP_reg 111
  201 +#define eBP_reg 112
  202 +#define eSI_reg 113
  203 +#define eDI_reg 114
  204 +
  205 +#define lptr 115
  206 +
  207 +#define al_reg 116
  208 +#define cl_reg 117
  209 +#define dl_reg 118
  210 +#define bl_reg 119
  211 +#define ah_reg 120
  212 +#define ch_reg 121
  213 +#define dh_reg 122
  214 +#define bh_reg 123
  215 +
  216 +#define ax_reg 124
  217 +#define cx_reg 125
  218 +#define dx_reg 126
  219 +#define bx_reg 127
  220 +#define sp_reg 128
  221 +#define bp_reg 129
  222 +#define si_reg 130
  223 +#define di_reg 131
  224 +
  225 +#define indir_dx_reg 150
  226 +
  227 +#define GRP1b NULL, NULL, 0
  228 +#define GRP1S NULL, NULL, 1
  229 +#define GRP1Ss NULL, NULL, 2
  230 +#define GRP2b NULL, NULL, 3
  231 +#define GRP2S NULL, NULL, 4
  232 +#define GRP2b_one NULL, NULL, 5
  233 +#define GRP2S_one NULL, NULL, 6
  234 +#define GRP2b_cl NULL, NULL, 7
  235 +#define GRP2S_cl NULL, NULL, 8
  236 +#define GRP3b NULL, NULL, 9
  237 +#define GRP3S NULL, NULL, 10
  238 +#define GRP4 NULL, NULL, 11
  239 +#define GRP5 NULL, NULL, 12
  240 +#define GRP6 NULL, NULL, 13
  241 +#define GRP7 NULL, NULL, 14
  242 +#define GRP8 NULL, NULL, 15
  243 +#define GRP9 NULL, NULL, 16
  244 +#define GRP10 NULL, NULL, 17
  245 +#define GRP11 NULL, NULL, 18
  246 +#define GRP12 NULL, NULL, 19
  247 +
  248 +#define FLOATCODE 50
  249 +#define FLOAT NULL, NULL, FLOATCODE
  250 +
  251 +struct dis386 {
  252 + char *name;
  253 + op_rtn op1;
  254 + int bytemode1;
  255 + op_rtn op2;
  256 + int bytemode2;
  257 + op_rtn op3;
  258 + int bytemode3;
  259 +};
  260 +
  261 +static struct dis386 dis386[] = {
  262 + /* 00 */
  263 + { "addb", Eb, Gb },
  264 + { "addS", Ev, Gv },
  265 + { "addb", Gb, Eb },
  266 + { "addS", Gv, Ev },
  267 + { "addb", AL, Ib },
  268 + { "addS", eAX, Iv },
  269 + { "pushS", es },
  270 + { "popS", es },
  271 + /* 08 */
  272 + { "orb", Eb, Gb },
  273 + { "orS", Ev, Gv },
  274 + { "orb", Gb, Eb },
  275 + { "orS", Gv, Ev },
  276 + { "orb", AL, Ib },
  277 + { "orS", eAX, Iv },
  278 + { "pushS", cs },
  279 + { "(bad)" }, /* 0x0f extended opcode escape */
  280 + /* 10 */
  281 + { "adcb", Eb, Gb },
  282 + { "adcS", Ev, Gv },
  283 + { "adcb", Gb, Eb },
  284 + { "adcS", Gv, Ev },
  285 + { "adcb", AL, Ib },
  286 + { "adcS", eAX, Iv },
  287 + { "pushS", ss },
  288 + { "popS", ss },
  289 + /* 18 */
  290 + { "sbbb", Eb, Gb },
  291 + { "sbbS", Ev, Gv },
  292 + { "sbbb", Gb, Eb },
  293 + { "sbbS", Gv, Ev },
  294 + { "sbbb", AL, Ib },
  295 + { "sbbS", eAX, Iv },
  296 + { "pushS", ds },
  297 + { "popS", ds },
  298 + /* 20 */
  299 + { "andb", Eb, Gb },
  300 + { "andS", Ev, Gv },
  301 + { "andb", Gb, Eb },
  302 + { "andS", Gv, Ev },
  303 + { "andb", AL, Ib },
  304 + { "andS", eAX, Iv },
  305 + { "(bad)" }, /* SEG ES prefix */
  306 + { "daa" },
  307 + /* 28 */
  308 + { "subb", Eb, Gb },
  309 + { "subS", Ev, Gv },
  310 + { "subb", Gb, Eb },
  311 + { "subS", Gv, Ev },
  312 + { "subb", AL, Ib },
  313 + { "subS", eAX, Iv },
  314 + { "(bad)" }, /* SEG CS prefix */
  315 + { "das" },
  316 + /* 30 */
  317 + { "xorb", Eb, Gb },
  318 + { "xorS", Ev, Gv },
  319 + { "xorb", Gb, Eb },
  320 + { "xorS", Gv, Ev },
  321 + { "xorb", AL, Ib },
  322 + { "xorS", eAX, Iv },
  323 + { "(bad)" }, /* SEG SS prefix */
  324 + { "aaa" },
  325 + /* 38 */
  326 + { "cmpb", Eb, Gb },
  327 + { "cmpS", Ev, Gv },
  328 + { "cmpb", Gb, Eb },
  329 + { "cmpS", Gv, Ev },
  330 + { "cmpb", AL, Ib },
  331 + { "cmpS", eAX, Iv },
  332 + { "(bad)" }, /* SEG DS prefix */
  333 + { "aas" },
  334 + /* 40 */
  335 + { "incS", eAX },
  336 + { "incS", eCX },
  337 + { "incS", eDX },
  338 + { "incS", eBX },
  339 + { "incS", eSP },
  340 + { "incS", eBP },
  341 + { "incS", eSI },
  342 + { "incS", eDI },
  343 + /* 48 */
  344 + { "decS", eAX },
  345 + { "decS", eCX },
  346 + { "decS", eDX },
  347 + { "decS", eBX },
  348 + { "decS", eSP },
  349 + { "decS", eBP },
  350 + { "decS", eSI },
  351 + { "decS", eDI },
  352 + /* 50 */
  353 + { "pushS", eAX },
  354 + { "pushS", eCX },
  355 + { "pushS", eDX },
  356 + { "pushS", eBX },
  357 + { "pushS", eSP },
  358 + { "pushS", eBP },
  359 + { "pushS", eSI },
  360 + { "pushS", eDI },
  361 + /* 58 */
  362 + { "popS", eAX },
  363 + { "popS", eCX },
  364 + { "popS", eDX },
  365 + { "popS", eBX },
  366 + { "popS", eSP },
  367 + { "popS", eBP },
  368 + { "popS", eSI },
  369 + { "popS", eDI },
  370 + /* 60 */
  371 + { "pusha" },
  372 + { "popa" },
  373 + { "boundS", Gv, Ma },
  374 + { "arpl", Ew, Gw },
  375 + { "(bad)" }, /* seg fs */
  376 + { "(bad)" }, /* seg gs */
  377 + { "(bad)" }, /* op size prefix */
  378 + { "(bad)" }, /* adr size prefix */
  379 + /* 68 */
  380 + { "pushS", Iv }, /* 386 book wrong */
  381 + { "imulS", Gv, Ev, Iv },
  382 + { "pushS", sIb }, /* push of byte really pushes 2 or 4 bytes */
  383 + { "imulS", Gv, Ev, Ib },
  384 + { "insb", Yb, indirDX },
  385 + { "insS", Yv, indirDX },
  386 + { "outsb", indirDX, Xb },
  387 + { "outsS", indirDX, Xv },
  388 + /* 70 */
  389 + { "jo", Jb },
  390 + { "jno", Jb },
  391 + { "jb", Jb },
  392 + { "jae", Jb },
  393 + { "je", Jb },
  394 + { "jne", Jb },
  395 + { "jbe", Jb },
  396 + { "ja", Jb },
  397 + /* 78 */
  398 + { "js", Jb },
  399 + { "jns", Jb },
  400 + { "jp", Jb },
  401 + { "jnp", Jb },
  402 + { "jl", Jb },
  403 + { "jnl", Jb },
  404 + { "jle", Jb },
  405 + { "jg", Jb },
  406 + /* 80 */
  407 + { GRP1b },
  408 + { GRP1S },
  409 + { "(bad)" },
  410 + { GRP1Ss },
  411 + { "testb", Eb, Gb },
  412 + { "testS", Ev, Gv },
  413 + { "xchgb", Eb, Gb },
  414 + { "xchgS", Ev, Gv },
  415 + /* 88 */
  416 + { "movb", Eb, Gb },
  417 + { "movS", Ev, Gv },
  418 + { "movb", Gb, Eb },
  419 + { "movS", Gv, Ev },
  420 + { "movS", Ev, Sw },
  421 + { "leaS", Gv, M },
  422 + { "movS", Sw, Ev },
  423 + { "popS", Ev },
  424 + /* 90 */
  425 + { "nop" },
  426 + { "xchgS", eCX, eAX },
  427 + { "xchgS", eDX, eAX },
  428 + { "xchgS", eBX, eAX },
  429 + { "xchgS", eSP, eAX },
  430 + { "xchgS", eBP, eAX },
  431 + { "xchgS", eSI, eAX },
  432 + { "xchgS", eDI, eAX },
  433 + /* 98 */
  434 + { "cWtS" },
  435 + { "cStd" },
  436 + { "lcall", Ap },
  437 + { "(bad)" }, /* fwait */
  438 + { "pushf" },
  439 + { "popf" },
  440 + { "sahf" },
  441 + { "lahf" },
  442 + /* a0 */
  443 + { "movb", AL, Ob },
  444 + { "movS", eAX, Ov },
  445 + { "movb", Ob, AL },
  446 + { "movS", Ov, eAX },
  447 + { "movsb", Yb, Xb },
  448 + { "movsS", Yv, Xv },
  449 + { "cmpsb", Yb, Xb },
  450 + { "cmpsS", Yv, Xv },
  451 + /* a8 */
  452 + { "testb", AL, Ib },
  453 + { "testS", eAX, Iv },
  454 + { "stosb", Yb, AL },
  455 + { "stosS", Yv, eAX },
  456 + { "lodsb", AL, Xb },
  457 + { "lodsS", eAX, Xv },
  458 + { "scasb", AL, Yb },
  459 + { "scasS", eAX, Yv },
  460 + /* b0 */
  461 + { "movb", AL, Ib },
  462 + { "movb", CL, Ib },
  463 + { "movb", DL, Ib },
  464 + { "movb", BL, Ib },
  465 + { "movb", AH, Ib },
  466 + { "movb", CH, Ib },
  467 + { "movb", DH, Ib },
  468 + { "movb", BH, Ib },
  469 + /* b8 */
  470 + { "movS", eAX, Iv },
  471 + { "movS", eCX, Iv },
  472 + { "movS", eDX, Iv },
  473 + { "movS", eBX, Iv },
  474 + { "movS", eSP, Iv },
  475 + { "movS", eBP, Iv },
  476 + { "movS", eSI, Iv },
  477 + { "movS", eDI, Iv },
  478 + /* c0 */
  479 + { GRP2b },
  480 + { GRP2S },
  481 + { "ret", Iw },
  482 + { "ret" },
  483 + { "lesS", Gv, Mp },
  484 + { "ldsS", Gv, Mp },
  485 + { "movb", Eb, Ib },
  486 + { "movS", Ev, Iv },
  487 + /* c8 */
  488 + { "enter", Iw, Ib },
  489 + { "leave" },
  490 + { "lret", Iw },
  491 + { "lret" },
  492 + { "int3" },
  493 + { "int", Ib },
  494 + { "into" },
  495 + { "iret" },
  496 + /* d0 */
  497 + { GRP2b_one },
  498 + { GRP2S_one },
  499 + { GRP2b_cl },
  500 + { GRP2S_cl },
  501 + { "aam", Ib },
  502 + { "aad", Ib },
  503 + { "(bad)" },
  504 + { "xlat" },
  505 + /* d8 */
  506 + { FLOAT },
  507 + { FLOAT },
  508 + { FLOAT },
  509 + { FLOAT },
  510 + { FLOAT },
  511 + { FLOAT },
  512 + { FLOAT },
  513 + { FLOAT },
  514 + /* e0 */
  515 + { "loopne", Jb },
  516 + { "loope", Jb },
  517 + { "loop", Jb },
  518 + { "jCcxz", Jb },
  519 + { "inb", AL, Ib },
  520 + { "inS", eAX, Ib },
  521 + { "outb", Ib, AL },
  522 + { "outS", Ib, eAX },
  523 + /* e8 */
  524 + { "call", Av },
  525 + { "jmp", Jv },
  526 + { "ljmp", Ap },
  527 + { "jmp", Jb },
  528 + { "inb", AL, indirDX },
  529 + { "inS", eAX, indirDX },
  530 + { "outb", indirDX, AL },
  531 + { "outS", indirDX, eAX },
  532 + /* f0 */
  533 + { "(bad)" }, /* lock prefix */
  534 + { "(bad)" },
  535 + { "(bad)" }, /* repne */
  536 + { "(bad)" }, /* repz */
  537 + { "hlt" },
  538 + { "cmc" },
  539 + { GRP3b },
  540 + { GRP3S },
  541 + /* f8 */
  542 + { "clc" },
  543 + { "stc" },
  544 + { "cli" },
  545 + { "sti" },
  546 + { "cld" },
  547 + { "std" },
  548 + { GRP4 },
  549 + { GRP5 },
  550 +};
  551 +
  552 +static struct dis386 dis386_twobyte[] = {
  553 + /* 00 */
  554 + { GRP6 },
  555 + { GRP7 },
  556 + { "larS", Gv, Ew },
  557 + { "lslS", Gv, Ew },
  558 + { "(bad)" },
  559 + { "(bad)" },
  560 + { "clts" },
  561 + { "(bad)" },
  562 + /* 08 */
  563 + { "invd" },
  564 + { "wbinvd" },
  565 + { "(bad)" }, { "ud2a" },
  566 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  567 + /* 10 */
  568 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  569 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  570 + /* 18 */
  571 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  572 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  573 + /* 20 */
  574 + /* these are all backward in appendix A of the intel book */
  575 + { "movl", Rd, Cd },
  576 + { "movl", Rd, Dd },
  577 + { "movl", Cd, Rd },
  578 + { "movl", Dd, Rd },
  579 + { "movl", Rd, Td },
  580 + { "(bad)" },
  581 + { "movl", Td, Rd },
  582 + { "(bad)" },
  583 + /* 28 */
  584 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  585 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  586 + /* 30 */
  587 + { "wrmsr" }, { "rdtsc" }, { "rdmsr" }, { "rdpmc" },
  588 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  589 + /* 38 */
  590 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  591 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  592 + /* 40 */
  593 + { "cmovo", Gv,Ev }, { "cmovno", Gv,Ev }, { "cmovb", Gv,Ev }, { "cmovae", Gv,Ev },
  594 + { "cmove", Gv,Ev }, { "cmovne", Gv,Ev }, { "cmovbe", Gv,Ev }, { "cmova", Gv,Ev },
  595 + /* 48 */
  596 + { "cmovs", Gv,Ev }, { "cmovns", Gv,Ev }, { "cmovp", Gv,Ev }, { "cmovnp", Gv,Ev },
  597 + { "cmovl", Gv,Ev }, { "cmovge", Gv,Ev }, { "cmovle", Gv,Ev }, { "cmovg", Gv,Ev },
  598 + /* 50 */
  599 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  600 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  601 + /* 58 */
  602 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  603 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  604 + /* 60 */
  605 + { "punpcklbw", MX, EM },
  606 + { "punpcklwd", MX, EM },
  607 + { "punpckldq", MX, EM },
  608 + { "packsswb", MX, EM },
  609 + { "pcmpgtb", MX, EM },
  610 + { "pcmpgtw", MX, EM },
  611 + { "pcmpgtd", MX, EM },
  612 + { "packuswb", MX, EM },
  613 + /* 68 */
  614 + { "punpckhbw", MX, EM },
  615 + { "punpckhwd", MX, EM },
  616 + { "punpckhdq", MX, EM },
  617 + { "packssdw", MX, EM },
  618 + { "(bad)" }, { "(bad)" },
  619 + { "movd", MX, Ev },
  620 + { "movq", MX, EM },
  621 + /* 70 */
  622 + { "(bad)" },
  623 + { GRP10 },
  624 + { GRP11 },
  625 + { GRP12 },
  626 + { "pcmpeqb", MX, EM },
  627 + { "pcmpeqw", MX, EM },
  628 + { "pcmpeqd", MX, EM },
  629 + { "emms" },
  630 + /* 78 */
  631 + { "(bad)" }, { "(bad)" }, { "(bad)" }, { "(bad)" },
  632 + { "(bad)" }, { "(bad)" },
  633 + { "movd", Ev, MX },
  634 + { "movq", EM, MX },
  635 + /* 80 */
  636 + { "jo", Jv },
  637 + { "jno", Jv },
  638 + { "jb", Jv },
  639 + { "jae", Jv },
  640 + { "je", Jv },
  641 + { "jne", Jv },
  642 + { "jbe", Jv },
  643 + { "ja", Jv },
  644 + /* 88 */
  645 + { "js", Jv },
  646 + { "jns", Jv },
  647 + { "jp", Jv },
  648 + { "jnp", Jv },
  649 + { "jl", Jv },
  650 + { "jge", Jv },
  651 + { "jle", Jv },
  652 + { "jg", Jv },
  653 + /* 90 */
  654 + { "seto", Eb },
  655 + { "setno", Eb },
  656 + { "setb", Eb },
  657 + { "setae", Eb },
  658 + { "sete", Eb },
  659 + { "setne", Eb },
  660 + { "setbe", Eb },
  661 + { "seta", Eb },
  662 + /* 98 */
  663 + { "sets", Eb },
  664 + { "setns", Eb },
  665 + { "setp", Eb },
  666 + { "setnp", Eb },
  667 + { "setl", Eb },
  668 + { "setge", Eb },
  669 + { "setle", Eb },
  670 + { "setg", Eb },
  671 + /* a0 */
  672 + { "pushS", fs },
  673 + { "popS", fs },
  674 + { "cpuid" },
  675 + { "btS", Ev, Gv },
  676 + { "shldS", Ev, Gv, Ib },
  677 + { "shldS", Ev, Gv, CL },
  678 + { "(bad)" },
  679 + { "(bad)" },
  680 + /* a8 */
  681 + { "pushS", gs },
  682 + { "popS", gs },
  683 + { "rsm" },
  684 + { "btsS", Ev, Gv },
  685 + { "shrdS", Ev, Gv, Ib },
  686 + { "shrdS", Ev, Gv, CL },
  687 + { "(bad)" },
  688 + { "imulS", Gv, Ev },
  689 + /* b0 */
  690 + { "cmpxchgb", Eb, Gb },
  691 + { "cmpxchgS", Ev, Gv },
  692 + { "lssS", Gv, Mp }, /* 386 lists only Mp */
  693 + { "btrS", Ev, Gv },
  694 + { "lfsS", Gv, Mp }, /* 386 lists only Mp */
  695 + { "lgsS", Gv, Mp }, /* 386 lists only Mp */
  696 + { "movzbS", Gv, Eb },
  697 + { "movzwS", Gv, Ew },
  698 + /* b8 */
  699 + { "ud2b" },
  700 + { "(bad)" },
  701 + { GRP8 },
  702 + { "btcS", Ev, Gv },
  703 + { "bsfS", Gv, Ev },
  704 + { "bsrS", Gv, Ev },
  705 + { "movsbS", Gv, Eb },
  706 + { "movswS", Gv, Ew },
  707 + /* c0 */
  708 + { "xaddb", Eb, Gb },
  709 + { "xaddS", Ev, Gv },
  710 + { "(bad)" },
  711 + { "(bad)" },
  712 + { "(bad)" },
  713 + { "(bad)" },
  714 + { "(bad)" },
  715 + { GRP9 },
  716 + /* c8 */
  717 + { "bswap", eAX },
  718 + { "bswap", eCX },
  719 + { "bswap", eDX },
  720 + { "bswap", eBX },
  721 + { "bswap", eSP },
  722 + { "bswap", eBP },
  723 + { "bswap", eSI },
  724 + { "bswap", eDI },
  725 + /* d0 */
  726 + { "(bad)" },
  727 + { "psrlw", MX, EM },
  728 + { "psrld", MX, EM },
  729 + { "psrlq", MX, EM },
  730 + { "(bad)" },
  731 + { "pmullw", MX, EM },
  732 + { "(bad)" }, { "(bad)" },
  733 + /* d8 */
  734 + { "psubusb", MX, EM },
  735 + { "psubusw", MX, EM },
  736 + { "(bad)" },
  737 + { "pand", MX, EM },
  738 + { "paddusb", MX, EM },
  739 + { "paddusw", MX, EM },
  740 + { "(bad)" },
  741 + { "pandn", MX, EM },
  742 + /* e0 */
  743 + { "(bad)" },
  744 + { "psraw", MX, EM },
  745 + { "psrad", MX, EM },
  746 + { "(bad)" },
  747 + { "(bad)" },
  748 + { "pmulhw", MX, EM },
  749 + { "(bad)" }, { "(bad)" },
  750 + /* e8 */
  751 + { "psubsb", MX, EM },
  752 + { "psubsw", MX, EM },
  753 + { "(bad)" },
  754 + { "por", MX, EM },
  755 + { "paddsb", MX, EM },
  756 + { "paddsw", MX, EM },
  757 + { "(bad)" },
  758 + { "pxor", MX, EM },
  759 + /* f0 */
  760 + { "(bad)" },
  761 + { "psllw", MX, EM },
  762 + { "pslld", MX, EM },
  763 + { "psllq", MX, EM },
  764 + { "(bad)" },
  765 + { "pmaddwd", MX, EM },
  766 + { "(bad)" }, { "(bad)" },
  767 + /* f8 */
  768 + { "psubb", MX, EM },
  769 + { "psubw", MX, EM },
  770 + { "psubd", MX, EM },
  771 + { "(bad)" },
  772 + { "paddb", MX, EM },
  773 + { "paddw", MX, EM },
  774 + { "paddd", MX, EM },
  775 + { "(bad)" }
  776 +};
  777 +
  778 +static const unsigned char onebyte_has_modrm[256] = {
  779 + 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0,
  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 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  784 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  785 + 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0,
  786 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  787 + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
  788 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  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 + 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0,
  792 + 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,
  793 + 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  794 + 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1
  795 +};
  796 +
  797 +static const unsigned char twobyte_has_modrm[256] = {
  798 + /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0, /* 0f */
  799 + /* 10 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 1f */
  800 + /* 20 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* 2f */
  801 + /* 30 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 3f */
  802 + /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
  803 + /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 5f */
  804 + /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1, /* 6f */
  805 + /* 70 */ 0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,1, /* 7f */
  806 + /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
  807 + /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
  808 + /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
  809 + /* b0 */ 1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1, /* bf */
  810 + /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
  811 + /* d0 */ 0,1,1,1,0,1,0,0,1,1,0,1,1,1,0,1, /* df */
  812 + /* e0 */ 0,1,1,0,0,1,0,0,1,1,0,1,1,1,0,1, /* ef */
  813 + /* f0 */ 0,1,1,1,0,1,0,0,1,1,1,0,1,1,1,0 /* ff */
  814 +};
  815 +
  816 +static char obuf[100];
  817 +static char *obufp;
  818 +static char scratchbuf[100];
  819 +static unsigned char *start_codep;
  820 +static unsigned char *codep;
  821 +static disassemble_info *the_info;
  822 +static int mod;
  823 +static int rm;
  824 +static int reg;
  825 +static void oappend PARAMS ((char *s));
  826 +
  827 +static char *names32[]={
  828 + "%eax","%ecx","%edx","%ebx", "%esp","%ebp","%esi","%edi",
  829 +};
  830 +static char *names16[] = {
  831 + "%ax","%cx","%dx","%bx","%sp","%bp","%si","%di",
  832 +};
  833 +static char *names8[] = {
  834 + "%al","%cl","%dl","%bl","%ah","%ch","%dh","%bh",
  835 +};
  836 +static char *names_seg[] = {
  837 + "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
  838 +};
  839 +static char *index16[] = {
  840 + "bx+si","bx+di","bp+si","bp+di","si","di","bp","bx"
  841 +};
  842 +
  843 +static struct dis386 grps[][8] = {
  844 + /* GRP1b */
  845 + {
  846 + { "addb", Eb, Ib },
  847 + { "orb", Eb, Ib },
  848 + { "adcb", Eb, Ib },
  849 + { "sbbb", Eb, Ib },
  850 + { "andb", Eb, Ib },
  851 + { "subb", Eb, Ib },
  852 + { "xorb", Eb, Ib },
  853 + { "cmpb", Eb, Ib }
  854 + },
  855 + /* GRP1S */
  856 + {
  857 + { "addS", Ev, Iv },
  858 + { "orS", Ev, Iv },
  859 + { "adcS", Ev, Iv },
  860 + { "sbbS", Ev, Iv },
  861 + { "andS", Ev, Iv },
  862 + { "subS", Ev, Iv },
  863 + { "xorS", Ev, Iv },
  864 + { "cmpS", Ev, Iv }
  865 + },
  866 + /* GRP1Ss */
  867 + {
  868 + { "addS", Ev, sIb },
  869 + { "orS", Ev, sIb },
  870 + { "adcS", Ev, sIb },
  871 + { "sbbS", Ev, sIb },
  872 + { "andS", Ev, sIb },
  873 + { "subS", Ev, sIb },
  874 + { "xorS", Ev, sIb },
  875 + { "cmpS", Ev, sIb }
  876 + },
  877 + /* GRP2b */
  878 + {
  879 + { "rolb", Eb, Ib },
  880 + { "rorb", Eb, Ib },
  881 + { "rclb", Eb, Ib },
  882 + { "rcrb", Eb, Ib },
  883 + { "shlb", Eb, Ib },
  884 + { "shrb", Eb, Ib },
  885 + { "(bad)" },
  886 + { "sarb", Eb, Ib },
  887 + },
  888 + /* GRP2S */
  889 + {
  890 + { "rolS", Ev, Ib },
  891 + { "rorS", Ev, Ib },
  892 + { "rclS", Ev, Ib },
  893 + { "rcrS", Ev, Ib },
  894 + { "shlS", Ev, Ib },
  895 + { "shrS", Ev, Ib },
  896 + { "(bad)" },
  897 + { "sarS", Ev, Ib },
  898 + },
  899 + /* GRP2b_one */
  900 + {
  901 + { "rolb", Eb },
  902 + { "rorb", Eb },
  903 + { "rclb", Eb },
  904 + { "rcrb", Eb },
  905 + { "shlb", Eb },
  906 + { "shrb", Eb },
  907 + { "(bad)" },
  908 + { "sarb", Eb },
  909 + },
  910 + /* GRP2S_one */
  911 + {
  912 + { "rolS", Ev },
  913 + { "rorS", Ev },
  914 + { "rclS", Ev },
  915 + { "rcrS", Ev },
  916 + { "shlS", Ev },
  917 + { "shrS", Ev },
  918 + { "(bad)" },
  919 + { "sarS", Ev },
  920 + },
  921 + /* GRP2b_cl */
  922 + {
  923 + { "rolb", Eb, CL },
  924 + { "rorb", Eb, CL },
  925 + { "rclb", Eb, CL },
  926 + { "rcrb", Eb, CL },
  927 + { "shlb", Eb, CL },
  928 + { "shrb", Eb, CL },
  929 + { "(bad)" },
  930 + { "sarb", Eb, CL },
  931 + },
  932 + /* GRP2S_cl */
  933 + {
  934 + { "rolS", Ev, CL },
  935 + { "rorS", Ev, CL },
  936 + { "rclS", Ev, CL },
  937 + { "rcrS", Ev, CL },
  938 + { "shlS", Ev, CL },
  939 + { "shrS", Ev, CL },
  940 + { "(bad)" },
  941 + { "sarS", Ev, CL }
  942 + },
  943 + /* GRP3b */
  944 + {
  945 + { "testb", Eb, Ib },
  946 + { "(bad)", Eb },
  947 + { "notb", Eb },
  948 + { "negb", Eb },
  949 + { "mulb", AL, Eb },
  950 + { "imulb", AL, Eb },
  951 + { "divb", AL, Eb },
  952 + { "idivb", AL, Eb }
  953 + },
  954 + /* GRP3S */
  955 + {
  956 + { "testS", Ev, Iv },
  957 + { "(bad)" },
  958 + { "notS", Ev },
  959 + { "negS", Ev },
  960 + { "mulS", eAX, Ev },
  961 + { "imulS", eAX, Ev },
  962 + { "divS", eAX, Ev },
  963 + { "idivS", eAX, Ev },
  964 + },
  965 + /* GRP4 */
  966 + {
  967 + { "incb", Eb },
  968 + { "decb", Eb },
  969 + { "(bad)" },
  970 + { "(bad)" },
  971 + { "(bad)" },
  972 + { "(bad)" },
  973 + { "(bad)" },
  974 + { "(bad)" },
  975 + },
  976 + /* GRP5 */
  977 + {
  978 + { "incS", Ev },
  979 + { "decS", Ev },
  980 + { "call", indirEv },
  981 + { "lcall", indirEv },
  982 + { "jmp", indirEv },
  983 + { "ljmp", indirEv },
  984 + { "pushS", Ev },
  985 + { "(bad)" },
  986 + },
  987 + /* GRP6 */
  988 + {
  989 + { "sldt", Ew },
  990 + { "str", Ew },
  991 + { "lldt", Ew },
  992 + { "ltr", Ew },
  993 + { "verr", Ew },
  994 + { "verw", Ew },
  995 + { "(bad)" },
  996 + { "(bad)" }
  997 + },
  998 + /* GRP7 */
  999 + {
  1000 + { "sgdt", Ew },
  1001 + { "sidt", Ew },
  1002 + { "lgdt", Ew },
  1003 + { "lidt", Ew },
  1004 + { "smsw", Ew },
  1005 + { "(bad)" },
  1006 + { "lmsw", Ew },
  1007 + { "invlpg", Ew },
  1008 + },
  1009 + /* GRP8 */
  1010 + {
  1011 + { "(bad)" },
  1012 + { "(bad)" },
  1013 + { "(bad)" },
  1014 + { "(bad)" },
  1015 + { "btS", Ev, Ib },
  1016 + { "btsS", Ev, Ib },
  1017 + { "btrS", Ev, Ib },
  1018 + { "btcS", Ev, Ib },
  1019 + },
  1020 + /* GRP9 */
  1021 + {
  1022 + { "(bad)" },
  1023 + { "cmpxchg8b", Ev },
  1024 + { "(bad)" },
  1025 + { "(bad)" },
  1026 + { "(bad)" },
  1027 + { "(bad)" },
  1028 + { "(bad)" },
  1029 + { "(bad)" },
  1030 + },
  1031 + /* GRP10 */
  1032 + {
  1033 + { "(bad)" },
  1034 + { "(bad)" },
  1035 + { "psrlw", MS, Ib },
  1036 + { "(bad)" },
  1037 + { "psraw", MS, Ib },
  1038 + { "(bad)" },
  1039 + { "psllw", MS, Ib },
  1040 + { "(bad)" },
  1041 + },
  1042 + /* GRP11 */
  1043 + {
  1044 + { "(bad)" },
  1045 + { "(bad)" },
  1046 + { "psrld", MS, Ib },
  1047 + { "(bad)" },
  1048 + { "psrad", MS, Ib },
  1049 + { "(bad)" },
  1050 + { "pslld", MS, Ib },
  1051 + { "(bad)" },
  1052 + },
  1053 + /* GRP12 */
  1054 + {
  1055 + { "(bad)" },
  1056 + { "(bad)" },
  1057 + { "psrlq", MS, Ib },
  1058 + { "(bad)" },
  1059 + { "(bad)" },
  1060 + { "(bad)" },
  1061 + { "psllq", MS, Ib },
  1062 + { "(bad)" },
  1063 + }
  1064 +};
  1065 +
  1066 +#define PREFIX_REPZ 1
  1067 +#define PREFIX_REPNZ 2
  1068 +#define PREFIX_LOCK 4
  1069 +#define PREFIX_CS 8
  1070 +#define PREFIX_SS 0x10
  1071 +#define PREFIX_DS 0x20
  1072 +#define PREFIX_ES 0x40
  1073 +#define PREFIX_FS 0x80
  1074 +#define PREFIX_GS 0x100
  1075 +#define PREFIX_DATA 0x200
  1076 +#define PREFIX_ADR 0x400
  1077 +#define PREFIX_FWAIT 0x800
  1078 +
  1079 +static int prefixes;
  1080 +
  1081 +static void
  1082 +ckprefix ()
  1083 +{
  1084 + prefixes = 0;
  1085 + while (1)
  1086 + {
  1087 + FETCH_DATA (the_info, codep + 1);
  1088 + switch (*codep)
  1089 + {
  1090 + case 0xf3:
  1091 + prefixes |= PREFIX_REPZ;
  1092 + break;
  1093 + case 0xf2:
  1094 + prefixes |= PREFIX_REPNZ;
  1095 + break;
  1096 + case 0xf0:
  1097 + prefixes |= PREFIX_LOCK;
  1098 + break;
  1099 + case 0x2e:
  1100 + prefixes |= PREFIX_CS;
  1101 + break;
  1102 + case 0x36:
  1103 + prefixes |= PREFIX_SS;
  1104 + break;
  1105 + case 0x3e:
  1106 + prefixes |= PREFIX_DS;
  1107 + break;
  1108 + case 0x26:
  1109 + prefixes |= PREFIX_ES;
  1110 + break;
  1111 + case 0x64:
  1112 + prefixes |= PREFIX_FS;
  1113 + break;
  1114 + case 0x65:
  1115 + prefixes |= PREFIX_GS;
  1116 + break;
  1117 + case 0x66:
  1118 + prefixes |= PREFIX_DATA;
  1119 + break;
  1120 + case 0x67:
  1121 + prefixes |= PREFIX_ADR;
  1122 + break;
  1123 + case 0x9b:
  1124 + prefixes |= PREFIX_FWAIT;
  1125 + break;
  1126 + default:
  1127 + return;
  1128 + }
  1129 + codep++;
  1130 + }
  1131 +}
  1132 +
  1133 +static char op1out[100], op2out[100], op3out[100];
  1134 +static int op_address[3], op_ad, op_index[3];
  1135 +static int start_pc;
  1136 +
  1137 +
  1138 +/*
  1139 + * On the 386's of 1988, the maximum length of an instruction is 15 bytes.
  1140 + * (see topic "Redundant prefixes" in the "Differences from 8086"
  1141 + * section of the "Virtual 8086 Mode" chapter.)
  1142 + * 'pc' should be the address of this instruction, it will
  1143 + * be used to print the target address if this is a relative jump or call
  1144 + * The function returns the length of this instruction in bytes.
  1145 + */
  1146 +
  1147 +int print_insn_x86 PARAMS ((bfd_vma pc, disassemble_info *info, int aflag,
  1148 + int dflag));
  1149 +int
  1150 +print_insn_i386 (pc, info)
  1151 + bfd_vma pc;
  1152 + disassemble_info *info;
  1153 +{
  1154 + if (info->mach == bfd_mach_i386_i386)
  1155 + return print_insn_x86 (pc, info, 1, 1);
  1156 + else if (info->mach == bfd_mach_i386_i8086)
  1157 + return print_insn_x86 (pc, info, 0, 0);
  1158 + else
  1159 + abort ();
  1160 +}
  1161 +
  1162 +int
  1163 +print_insn_x86 (pc, info, aflag, dflag)
  1164 + bfd_vma pc;
  1165 + disassemble_info *info;
  1166 + int aflag;
  1167 + int dflag;
  1168 +{
  1169 + struct dis386 *dp;
  1170 + int i;
  1171 + int enter_instruction;
  1172 + char *first, *second, *third;
  1173 + int needcomma;
  1174 + unsigned char need_modrm;
  1175 +
  1176 + struct dis_private priv;
  1177 + bfd_byte *inbuf = priv.the_buffer;
  1178 +
  1179 + /* The output looks better if we put 5 bytes on a line, since that
  1180 + puts long word instructions on a single line. */
  1181 + info->bytes_per_line = 5;
  1182 +
  1183 + info->private_data = (PTR) &priv;
  1184 + priv.max_fetched = priv.the_buffer;
  1185 + priv.insn_start = pc;
  1186 + if (setjmp (priv.bailout) != 0)
  1187 + /* Error return. */
  1188 + return -1;
  1189 +
  1190 + obuf[0] = 0;
  1191 + op1out[0] = 0;
  1192 + op2out[0] = 0;
  1193 + op3out[0] = 0;
  1194 +
  1195 + op_index[0] = op_index[1] = op_index[2] = -1;
  1196 +
  1197 + the_info = info;
  1198 + start_pc = pc;
  1199 + start_codep = inbuf;
  1200 + codep = inbuf;
  1201 +
  1202 + ckprefix ();
  1203 +
  1204 + FETCH_DATA (info, codep + 1);
  1205 + if (*codep == 0xc8)
  1206 + enter_instruction = 1;
  1207 + else
  1208 + enter_instruction = 0;
  1209 +
  1210 + obufp = obuf;
  1211 +
  1212 + if (prefixes & PREFIX_REPZ)
  1213 + oappend ("repz ");
  1214 + if (prefixes & PREFIX_REPNZ)
  1215 + oappend ("repnz ");
  1216 + if (prefixes & PREFIX_LOCK)
  1217 + oappend ("lock ");
  1218 +
  1219 + if ((prefixes & PREFIX_FWAIT)
  1220 + && ((*codep < 0xd8) || (*codep > 0xdf)))
  1221 + {
  1222 + /* fwait not followed by floating point instruction */
  1223 + (*info->fprintf_func) (info->stream, "fwait");
  1224 + return (1);
  1225 + }
  1226 +
  1227 + if (prefixes & PREFIX_DATA)
  1228 + dflag ^= 1;
  1229 +
  1230 + if (prefixes & PREFIX_ADR)
  1231 + {
  1232 + aflag ^= 1;
  1233 + if (aflag)
  1234 + oappend ("addr32 ");
  1235 + else
  1236 + oappend ("addr16 ");
  1237 + }
  1238 +
  1239 + if (*codep == 0x0f)
  1240 + {
  1241 + FETCH_DATA (info, codep + 2);
  1242 + dp = &dis386_twobyte[*++codep];
  1243 + need_modrm = twobyte_has_modrm[*codep];
  1244 + }
  1245 + else
  1246 + {
  1247 + dp = &dis386[*codep];
  1248 + need_modrm = onebyte_has_modrm[*codep];
  1249 + }
  1250 + codep++;
  1251 +
  1252 + if (need_modrm)
  1253 + {
  1254 + FETCH_DATA (info, codep + 1);
  1255 + mod = (*codep >> 6) & 3;
  1256 + reg = (*codep >> 3) & 7;
  1257 + rm = *codep & 7;
  1258 + }
  1259 +
  1260 + if (dp->name == NULL && dp->bytemode1 == FLOATCODE)
  1261 + {
  1262 + dofloat (aflag, dflag);
  1263 + }
  1264 + else
  1265 + {
  1266 + if (dp->name == NULL)
  1267 + dp = &grps[dp->bytemode1][reg];
  1268 +
  1269 + putop (dp->name, aflag, dflag);
  1270 +
  1271 + obufp = op1out;
  1272 + op_ad = 2;
  1273 + if (dp->op1)
  1274 + (*dp->op1)(dp->bytemode1, aflag, dflag);
  1275 +
  1276 + obufp = op2out;
  1277 + op_ad = 1;
  1278 + if (dp->op2)
  1279 + (*dp->op2)(dp->bytemode2, aflag, dflag);
  1280 +
  1281 + obufp = op3out;
  1282 + op_ad = 0;
  1283 + if (dp->op3)
  1284 + (*dp->op3)(dp->bytemode3, aflag, dflag);
  1285 + }
  1286 +
  1287 + obufp = obuf + strlen (obuf);
  1288 + for (i = strlen (obuf); i < 6; i++)
  1289 + oappend (" ");
  1290 + oappend (" ");
  1291 + (*info->fprintf_func) (info->stream, "%s", obuf);
  1292 +
  1293 + /* enter instruction is printed with operands in the
  1294 + * same order as the intel book; everything else
  1295 + * is printed in reverse order
  1296 + */
  1297 + if (enter_instruction)
  1298 + {
  1299 + first = op1out;
  1300 + second = op2out;
  1301 + third = op3out;
  1302 + op_ad = op_index[0];
  1303 + op_index[0] = op_index[2];
  1304 + op_index[2] = op_ad;
  1305 + }
  1306 + else
  1307 + {
  1308 + first = op3out;
  1309 + second = op2out;
  1310 + third = op1out;
  1311 + }
  1312 + needcomma = 0;
  1313 + if (*first)
  1314 + {
  1315 + if (op_index[0] != -1)
  1316 + (*info->print_address_func) (op_address[op_index[0]], info);
  1317 + else
  1318 + (*info->fprintf_func) (info->stream, "%s", first);
  1319 + needcomma = 1;
  1320 + }
  1321 + if (*second)
  1322 + {
  1323 + if (needcomma)
  1324 + (*info->fprintf_func) (info->stream, ",");
  1325 + if (op_index[1] != -1)
  1326 + (*info->print_address_func) (op_address[op_index[1]], info);
  1327 + else
  1328 + (*info->fprintf_func) (info->stream, "%s", second);
  1329 + needcomma = 1;
  1330 + }
  1331 + if (*third)
  1332 + {
  1333 + if (needcomma)
  1334 + (*info->fprintf_func) (info->stream, ",");
  1335 + if (op_index[2] != -1)
  1336 + (*info->print_address_func) (op_address[op_index[2]], info);
  1337 + else
  1338 + (*info->fprintf_func) (info->stream, "%s", third);
  1339 + }
  1340 + return (codep - inbuf);
  1341 +}
  1342 +
  1343 +static char *float_mem[] = {
  1344 + /* d8 */
  1345 + "fadds",
  1346 + "fmuls",
  1347 + "fcoms",
  1348 + "fcomps",
  1349 + "fsubs",
  1350 + "fsubrs",
  1351 + "fdivs",
  1352 + "fdivrs",
  1353 + /* d9 */
  1354 + "flds",
  1355 + "(bad)",
  1356 + "fsts",
  1357 + "fstps",
  1358 + "fldenv",
  1359 + "fldcw",
  1360 + "fNstenv",
  1361 + "fNstcw",
  1362 + /* da */
  1363 + "fiaddl",
  1364 + "fimull",
  1365 + "ficoml",
  1366 + "ficompl",
  1367 + "fisubl",
  1368 + "fisubrl",
  1369 + "fidivl",
  1370 + "fidivrl",
  1371 + /* db */
  1372 + "fildl",
  1373 + "(bad)",
  1374 + "fistl",
  1375 + "fistpl",
  1376 + "(bad)",
  1377 + "fldt",
  1378 + "(bad)",
  1379 + "fstpt",
  1380 + /* dc */
  1381 + "faddl",
  1382 + "fmull",
  1383 + "fcoml",
  1384 + "fcompl",
  1385 + "fsubl",
  1386 + "fsubrl",
  1387 + "fdivl",
  1388 + "fdivrl",
  1389 + /* dd */
  1390 + "fldl",
  1391 + "(bad)",
  1392 + "fstl",
  1393 + "fstpl",
  1394 + "frstor",
  1395 + "(bad)",
  1396 + "fNsave",
  1397 + "fNstsw",
  1398 + /* de */
  1399 + "fiadd",
  1400 + "fimul",
  1401 + "ficom",
  1402 + "ficomp",
  1403 + "fisub",
  1404 + "fisubr",
  1405 + "fidiv",
  1406 + "fidivr",
  1407 + /* df */
  1408 + "fild",
  1409 + "(bad)",
  1410 + "fist",
  1411 + "fistp",
  1412 + "fbld",
  1413 + "fildll",
  1414 + "fbstp",
  1415 + "fistpll",
  1416 +};
  1417 +
  1418 +#define ST OP_ST, 0
  1419 +#define STi OP_STi, 0
  1420 +
  1421 +#define FGRPd9_2 NULL, NULL, 0
  1422 +#define FGRPd9_4 NULL, NULL, 1
  1423 +#define FGRPd9_5 NULL, NULL, 2
  1424 +#define FGRPd9_6 NULL, NULL, 3
  1425 +#define FGRPd9_7 NULL, NULL, 4
  1426 +#define FGRPda_5 NULL, NULL, 5
  1427 +#define FGRPdb_4 NULL, NULL, 6
  1428 +#define FGRPde_3 NULL, NULL, 7
  1429 +#define FGRPdf_4 NULL, NULL, 8
  1430 +
  1431 +static struct dis386 float_reg[][8] = {
  1432 + /* d8 */
  1433 + {
  1434 + { "fadd", ST, STi },
  1435 + { "fmul", ST, STi },
  1436 + { "fcom", STi },
  1437 + { "fcomp", STi },
  1438 + { "fsub", ST, STi },
  1439 + { "fsubr", ST, STi },
  1440 + { "fdiv", ST, STi },
  1441 + { "fdivr", ST, STi },
  1442 + },
  1443 + /* d9 */
  1444 + {
  1445 + { "fld", STi },
  1446 + { "fxch", STi },
  1447 + { FGRPd9_2 },
  1448 + { "(bad)" },
  1449 + { FGRPd9_4 },
  1450 + { FGRPd9_5 },
  1451 + { FGRPd9_6 },
  1452 + { FGRPd9_7 },
  1453 + },
  1454 + /* da */
  1455 + {
  1456 + { "fcmovb", ST, STi },
  1457 + { "fcmove", ST, STi },
  1458 + { "fcmovbe",ST, STi },
  1459 + { "fcmovu", ST, STi },
  1460 + { "(bad)" },
  1461 + { FGRPda_5 },
  1462 + { "(bad)" },
  1463 + { "(bad)" },
  1464 + },
  1465 + /* db */
  1466 + {
  1467 + { "fcmovnb",ST, STi },
  1468 + { "fcmovne",ST, STi },
  1469 + { "fcmovnbe",ST, STi },
  1470 + { "fcmovnu",ST, STi },
  1471 + { FGRPdb_4 },
  1472 + { "fucomi", ST, STi },
  1473 + { "fcomi", ST, STi },
  1474 + { "(bad)" },
  1475 + },
  1476 + /* dc */
  1477 + {
  1478 + { "fadd", STi, ST },
  1479 + { "fmul", STi, ST },
  1480 + { "(bad)" },
  1481 + { "(bad)" },
  1482 + { "fsub", STi, ST },
  1483 + { "fsubr", STi, ST },
  1484 + { "fdiv", STi, ST },
  1485 + { "fdivr", STi, ST },
  1486 + },
  1487 + /* dd */
  1488 + {
  1489 + { "ffree", STi },
  1490 + { "(bad)" },
  1491 + { "fst", STi },
  1492 + { "fstp", STi },
  1493 + { "fucom", STi },
  1494 + { "fucomp", STi },
  1495 + { "(bad)" },
  1496 + { "(bad)" },
  1497 + },
  1498 + /* de */
  1499 + {
  1500 + { "faddp", STi, ST },
  1501 + { "fmulp", STi, ST },
  1502 + { "(bad)" },
  1503 + { FGRPde_3 },
  1504 + { "fsubp", STi, ST },
  1505 + { "fsubrp", STi, ST },
  1506 + { "fdivp", STi, ST },
  1507 + { "fdivrp", STi, ST },
  1508 + },
  1509 + /* df */
  1510 + {
  1511 + { "(bad)" },
  1512 + { "(bad)" },
  1513 + { "(bad)" },
  1514 + { "(bad)" },
  1515 + { FGRPdf_4 },
  1516 + { "fucomip",ST, STi },
  1517 + { "fcomip", ST, STi },
  1518 + { "(bad)" },
  1519 + },
  1520 +};
  1521 +
  1522 +
  1523 +static char *fgrps[][8] = {
  1524 + /* d9_2 0 */
  1525 + {
  1526 + "fnop","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
  1527 + },
  1528 +
  1529 + /* d9_4 1 */
  1530 + {
  1531 + "fchs","fabs","(bad)","(bad)","ftst","fxam","(bad)","(bad)",
  1532 + },
  1533 +
  1534 + /* d9_5 2 */
  1535 + {
  1536 + "fld1","fldl2t","fldl2e","fldpi","fldlg2","fldln2","fldz","(bad)",
  1537 + },
  1538 +
  1539 + /* d9_6 3 */
  1540 + {
  1541 + "f2xm1","fyl2x","fptan","fpatan","fxtract","fprem1","fdecstp","fincstp",
  1542 + },
  1543 +
  1544 + /* d9_7 4 */
  1545 + {
  1546 + "fprem","fyl2xp1","fsqrt","fsincos","frndint","fscale","fsin","fcos",
  1547 + },
  1548 +
  1549 + /* da_5 5 */
  1550 + {
  1551 + "(bad)","fucompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
  1552 + },
  1553 +
  1554 + /* db_4 6 */
  1555 + {
  1556 + "feni(287 only)","fdisi(287 only)","fNclex","fNinit",
  1557 + "fNsetpm(287 only)","(bad)","(bad)","(bad)",
  1558 + },
  1559 +
  1560 + /* de_3 7 */
  1561 + {
  1562 + "(bad)","fcompp","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
  1563 + },
  1564 +
  1565 + /* df_4 8 */
  1566 + {
  1567 + "fNstsw","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)","(bad)",
  1568 + },
  1569 +};
  1570 +
  1571 +static void
  1572 +dofloat (aflag, dflag)
  1573 + int aflag;
  1574 + int dflag;
  1575 +{
  1576 + struct dis386 *dp;
  1577 + unsigned char floatop;
  1578 +
  1579 + floatop = codep[-1];
  1580 +
  1581 + if (mod != 3)
  1582 + {
  1583 + putop (float_mem[(floatop - 0xd8) * 8 + reg], aflag, dflag);
  1584 + obufp = op1out;
  1585 + OP_E (v_mode, aflag, dflag);
  1586 + return;
  1587 + }
  1588 + codep++;
  1589 +
  1590 + dp = &float_reg[floatop - 0xd8][reg];
  1591 + if (dp->name == NULL)
  1592 + {
  1593 + putop (fgrps[dp->bytemode1][rm], aflag, dflag);
  1594 + /* instruction fnstsw is only one with strange arg */
  1595 + if (floatop == 0xdf
  1596 + && FETCH_DATA (the_info, codep + 1)
  1597 + && *codep == 0xe0)
  1598 + strcpy (op1out, "%eax");
  1599 + }
  1600 + else
  1601 + {
  1602 + putop (dp->name, aflag, dflag);
  1603 + obufp = op1out;
  1604 + if (dp->op1)
  1605 + (*dp->op1)(dp->bytemode1, aflag, dflag);
  1606 + obufp = op2out;
  1607 + if (dp->op2)
  1608 + (*dp->op2)(dp->bytemode2, aflag, dflag);
  1609 + }
  1610 +}
  1611 +
  1612 +/* ARGSUSED */
  1613 +static int
  1614 +OP_ST (ignore, aflag, dflag)
  1615 + int ignore;
  1616 + int aflag;
  1617 + int dflag;
  1618 +{
  1619 + oappend ("%st");
  1620 + return (0);
  1621 +}
  1622 +
  1623 +/* ARGSUSED */
  1624 +static int
  1625 +OP_STi (ignore, aflag, dflag)
  1626 + int ignore;
  1627 + int aflag;
  1628 + int dflag;
  1629 +{
  1630 + sprintf (scratchbuf, "%%st(%d)", rm);
  1631 + oappend (scratchbuf);
  1632 + return (0);
  1633 +}
  1634 +
  1635 +
  1636 +/* capital letters in template are macros */
  1637 +static void
  1638 +putop (template, aflag, dflag)
  1639 + char *template;
  1640 + int aflag;
  1641 + int dflag;
  1642 +{
  1643 + char *p;
  1644 +
  1645 + for (p = template; *p; p++)
  1646 + {
  1647 + switch (*p)
  1648 + {
  1649 + default:
  1650 + *obufp++ = *p;
  1651 + break;
  1652 + case 'C': /* For jcxz/jecxz */
  1653 + if (aflag)
  1654 + *obufp++ = 'e';
  1655 + break;
  1656 + case 'N':
  1657 + if ((prefixes & PREFIX_FWAIT) == 0)
  1658 + *obufp++ = 'n';
  1659 + break;
  1660 + case 'S':
  1661 + /* operand size flag */
  1662 + if (dflag)
  1663 + *obufp++ = 'l';
  1664 + else
  1665 + *obufp++ = 'w';
  1666 + break;
  1667 + case 'W':
  1668 + /* operand size flag for cwtl, cbtw */
  1669 + if (dflag)
  1670 + *obufp++ = 'w';
  1671 + else
  1672 + *obufp++ = 'b';
  1673 + break;
  1674 + }
  1675 + }
  1676 + *obufp = 0;
  1677 +}
  1678 +
  1679 +static void
  1680 +oappend (s)
  1681 + char *s;
  1682 +{
  1683 + strcpy (obufp, s);
  1684 + obufp += strlen (s);
  1685 + *obufp = 0;
  1686 +}
  1687 +
  1688 +static void
  1689 +append_prefix ()
  1690 +{
  1691 + if (prefixes & PREFIX_CS)
  1692 + oappend ("%cs:");
  1693 + if (prefixes & PREFIX_DS)
  1694 + oappend ("%ds:");
  1695 + if (prefixes & PREFIX_SS)
  1696 + oappend ("%ss:");
  1697 + if (prefixes & PREFIX_ES)
  1698 + oappend ("%es:");
  1699 + if (prefixes & PREFIX_FS)
  1700 + oappend ("%fs:");
  1701 + if (prefixes & PREFIX_GS)
  1702 + oappend ("%gs:");
  1703 +}
  1704 +
  1705 +static int
  1706 +OP_indirE (bytemode, aflag, dflag)
  1707 + int bytemode;
  1708 + int aflag;
  1709 + int dflag;
  1710 +{
  1711 + oappend ("*");
  1712 + return OP_E (bytemode, aflag, dflag);
  1713 +}
  1714 +
  1715 +static int
  1716 +OP_E (bytemode, aflag, dflag)
  1717 + int bytemode;
  1718 + int aflag;
  1719 + int dflag;
  1720 +{
  1721 + int disp;
  1722 +
  1723 + /* skip mod/rm byte */
  1724 + codep++;
  1725 +
  1726 + if (mod == 3)
  1727 + {
  1728 + switch (bytemode)
  1729 + {
  1730 + case b_mode:
  1731 + oappend (names8[rm]);
  1732 + break;
  1733 + case w_mode:
  1734 + oappend (names16[rm]);
  1735 + break;
  1736 + case v_mode:
  1737 + if (dflag)
  1738 + oappend (names32[rm]);
  1739 + else
  1740 + oappend (names16[rm]);
  1741 + break;
  1742 + default:
  1743 + oappend ("<bad dis table>");
  1744 + break;
  1745 + }
  1746 + return 0;
  1747 + }
  1748 +
  1749 + disp = 0;
  1750 + append_prefix ();
  1751 +
  1752 + if (aflag) /* 32 bit address mode */
  1753 + {
  1754 + int havesib;
  1755 + int havebase;
  1756 + int base;
  1757 + int index = 0;
  1758 + int scale = 0;
  1759 +
  1760 + havesib = 0;
  1761 + havebase = 1;
  1762 + base = rm;
  1763 +
  1764 + if (base == 4)
  1765 + {
  1766 + havesib = 1;
  1767 + FETCH_DATA (the_info, codep + 1);
  1768 + scale = (*codep >> 6) & 3;
  1769 + index = (*codep >> 3) & 7;
  1770 + base = *codep & 7;
  1771 + codep++;
  1772 + }
  1773 +
  1774 + switch (mod)
  1775 + {
  1776 + case 0:
  1777 + if (base == 5)
  1778 + {
  1779 + havebase = 0;
  1780 + disp = get32 ();
  1781 + }
  1782 + break;
  1783 + case 1:
  1784 + FETCH_DATA (the_info, codep + 1);
  1785 + disp = *codep++;
  1786 + if ((disp & 0x80) != 0)
  1787 + disp -= 0x100;
  1788 + break;
  1789 + case 2:
  1790 + disp = get32 ();
  1791 + break;
  1792 + }
  1793 +
  1794 + if (mod != 0 || base == 5)
  1795 + {
  1796 + sprintf (scratchbuf, "0x%x", disp);
  1797 + oappend (scratchbuf);
  1798 + }
  1799 +
  1800 + if (havebase || (havesib && (index != 4 || scale != 0)))
  1801 + {
  1802 + oappend ("(");
  1803 + if (havebase)
  1804 + oappend (names32[base]);
  1805 + if (havesib)
  1806 + {
  1807 + if (index != 4)
  1808 + {
  1809 + sprintf (scratchbuf, ",%s", names32[index]);
  1810 + oappend (scratchbuf);
  1811 + }
  1812 + sprintf (scratchbuf, ",%d", 1 << scale);
  1813 + oappend (scratchbuf);
  1814 + }
  1815 + oappend (")");
  1816 + }
  1817 + }
  1818 + else
  1819 + { /* 16 bit address mode */
  1820 + switch (mod)
  1821 + {
  1822 + case 0:
  1823 + if (rm == 6)
  1824 + {
  1825 + disp = get16 ();
  1826 + if ((disp & 0x8000) != 0)
  1827 + disp -= 0x10000;
  1828 + }
  1829 + break;
  1830 + case 1:
  1831 + FETCH_DATA (the_info, codep + 1);
  1832 + disp = *codep++;
  1833 + if ((disp & 0x80) != 0)
  1834 + disp -= 0x100;
  1835 + break;
  1836 + case 2:
  1837 + disp = get16 ();
  1838 + if ((disp & 0x8000) != 0)
  1839 + disp -= 0x10000;
  1840 + break;
  1841 + }
  1842 +
  1843 + if (mod != 0 || rm == 6)
  1844 + {
  1845 + sprintf (scratchbuf, "0x%x", disp);
  1846 + oappend (scratchbuf);
  1847 + }
  1848 +
  1849 + if (mod != 0 || rm != 6)
  1850 + {
  1851 + oappend ("(");
  1852 + oappend (index16[rm]);
  1853 + oappend (")");
  1854 + }
  1855 + }
  1856 + return 0;
  1857 +}
  1858 +
  1859 +static int
  1860 +OP_G (bytemode, aflag, dflag)
  1861 + int bytemode;
  1862 + int aflag;
  1863 + int dflag;
  1864 +{
  1865 + switch (bytemode)
  1866 + {
  1867 + case b_mode:
  1868 + oappend (names8[reg]);
  1869 + break;
  1870 + case w_mode:
  1871 + oappend (names16[reg]);
  1872 + break;
  1873 + case d_mode:
  1874 + oappend (names32[reg]);
  1875 + break;
  1876 + case v_mode:
  1877 + if (dflag)
  1878 + oappend (names32[reg]);
  1879 + else
  1880 + oappend (names16[reg]);
  1881 + break;
  1882 + default:
  1883 + oappend ("<internal disassembler error>");
  1884 + break;
  1885 + }
  1886 + return (0);
  1887 +}
  1888 +
  1889 +static int
  1890 +get32 ()
  1891 +{
  1892 + int x = 0;
  1893 +
  1894 + FETCH_DATA (the_info, codep + 4);
  1895 + x = *codep++ & 0xff;
  1896 + x |= (*codep++ & 0xff) << 8;
  1897 + x |= (*codep++ & 0xff) << 16;
  1898 + x |= (*codep++ & 0xff) << 24;
  1899 + return (x);
  1900 +}
  1901 +
  1902 +static int
  1903 +get16 ()
  1904 +{
  1905 + int x = 0;
  1906 +
  1907 + FETCH_DATA (the_info, codep + 2);
  1908 + x = *codep++ & 0xff;
  1909 + x |= (*codep++ & 0xff) << 8;
  1910 + return (x);
  1911 +}
  1912 +
  1913 +static void
  1914 +set_op (op)
  1915 + int op;
  1916 +{
  1917 + op_index[op_ad] = op_ad;
  1918 + op_address[op_ad] = op;
  1919 +}
  1920 +
  1921 +static int
  1922 +OP_REG (code, aflag, dflag)
  1923 + int code;
  1924 + int aflag;
  1925 + int dflag;
  1926 +{
  1927 + char *s;
  1928 +
  1929 + switch (code)
  1930 + {
  1931 + case indir_dx_reg: s = "(%dx)"; break;
  1932 + case ax_reg: case cx_reg: case dx_reg: case bx_reg:
  1933 + case sp_reg: case bp_reg: case si_reg: case di_reg:
  1934 + s = names16[code - ax_reg];
  1935 + break;
  1936 + case es_reg: case ss_reg: case cs_reg:
  1937 + case ds_reg: case fs_reg: case gs_reg:
  1938 + s = names_seg[code - es_reg];
  1939 + break;
  1940 + case al_reg: case ah_reg: case cl_reg: case ch_reg:
  1941 + case dl_reg: case dh_reg: case bl_reg: case bh_reg:
  1942 + s = names8[code - al_reg];
  1943 + break;
  1944 + case eAX_reg: case eCX_reg: case eDX_reg: case eBX_reg:
  1945 + case eSP_reg: case eBP_reg: case eSI_reg: case eDI_reg:
  1946 + if (dflag)
  1947 + s = names32[code - eAX_reg];
  1948 + else
  1949 + s = names16[code - eAX_reg];
  1950 + break;
  1951 + default:
  1952 + s = "<internal disassembler error>";
  1953 + break;
  1954 + }
  1955 + oappend (s);
  1956 + return (0);
  1957 +}
  1958 +
  1959 +static int
  1960 +OP_I (bytemode, aflag, dflag)
  1961 + int bytemode;
  1962 + int aflag;
  1963 + int dflag;
  1964 +{
  1965 + int op;
  1966 +
  1967 + switch (bytemode)
  1968 + {
  1969 + case b_mode:
  1970 + FETCH_DATA (the_info, codep + 1);
  1971 + op = *codep++ & 0xff;
  1972 + break;
  1973 + case v_mode:
  1974 + if (dflag)
  1975 + op = get32 ();
  1976 + else
  1977 + op = get16 ();
  1978 + break;
  1979 + case w_mode:
  1980 + op = get16 ();
  1981 + break;
  1982 + default:
  1983 + oappend ("<internal disassembler error>");
  1984 + return (0);
  1985 + }
  1986 + sprintf (scratchbuf, "$0x%x", op);
  1987 + oappend (scratchbuf);
  1988 + return (0);
  1989 +}
  1990 +
  1991 +static int
  1992 +OP_sI (bytemode, aflag, dflag)
  1993 + int bytemode;
  1994 + int aflag;
  1995 + int dflag;
  1996 +{
  1997 + int op;
  1998 +
  1999 + switch (bytemode)
  2000 + {
  2001 + case b_mode:
  2002 + FETCH_DATA (the_info, codep + 1);
  2003 + op = *codep++;
  2004 + if ((op & 0x80) != 0)
  2005 + op -= 0x100;
  2006 + break;
  2007 + case v_mode:
  2008 + if (dflag)
  2009 + op = get32 ();
  2010 + else
  2011 + {
  2012 + op = get16();
  2013 + if ((op & 0x8000) != 0)
  2014 + op -= 0x10000;
  2015 + }
  2016 + break;
  2017 + case w_mode:
  2018 + op = get16 ();
  2019 + if ((op & 0x8000) != 0)
  2020 + op -= 0x10000;
  2021 + break;
  2022 + default:
  2023 + oappend ("<internal disassembler error>");
  2024 + return (0);
  2025 + }
  2026 + sprintf (scratchbuf, "$0x%x", op);
  2027 + oappend (scratchbuf);
  2028 + return (0);
  2029 +}
  2030 +
  2031 +static int
  2032 +OP_J (bytemode, aflag, dflag)
  2033 + int bytemode;
  2034 + int aflag;
  2035 + int dflag;
  2036 +{
  2037 + int disp;
  2038 + int mask = -1;
  2039 +
  2040 + switch (bytemode)
  2041 + {
  2042 + case b_mode:
  2043 + FETCH_DATA (the_info, codep + 1);
  2044 + disp = *codep++;
  2045 + if ((disp & 0x80) != 0)
  2046 + disp -= 0x100;
  2047 + break;
  2048 + case v_mode:
  2049 + if (dflag)
  2050 + disp = get32 ();
  2051 + else
  2052 + {
  2053 + disp = get16 ();
  2054 + if ((disp & 0x8000) != 0)
  2055 + disp -= 0x10000;
  2056 + /* for some reason, a data16 prefix on a jump instruction
  2057 + means that the pc is masked to 16 bits after the
  2058 + displacement is added! */
  2059 + mask = 0xffff;
  2060 + }
  2061 + break;
  2062 + default:
  2063 + oappend ("<internal disassembler error>");
  2064 + return (0);
  2065 + }
  2066 + disp = (start_pc + codep - start_codep + disp) & mask;
  2067 + set_op (disp);
  2068 + sprintf (scratchbuf, "0x%x", disp);
  2069 + oappend (scratchbuf);
  2070 + return (0);
  2071 +}
  2072 +
  2073 +/* ARGSUSED */
  2074 +static int
  2075 +OP_SEG (dummy, aflag, dflag)
  2076 + int dummy;
  2077 + int aflag;
  2078 + int dflag;
  2079 +{
  2080 + static char *sreg[] = {
  2081 + "%es","%cs","%ss","%ds","%fs","%gs","%?","%?",
  2082 + };
  2083 +
  2084 + oappend (sreg[reg]);
  2085 + return (0);
  2086 +}
  2087 +
  2088 +static int
  2089 +OP_DIR (size, aflag, dflag)
  2090 + int size;
  2091 + int aflag;
  2092 + int dflag;
  2093 +{
  2094 + int seg, offset;
  2095 +
  2096 + switch (size)
  2097 + {
  2098 + case lptr:
  2099 + if (aflag)
  2100 + {
  2101 + offset = get32 ();
  2102 + seg = get16 ();
  2103 + }
  2104 + else
  2105 + {
  2106 + offset = get16 ();
  2107 + seg = get16 ();
  2108 + }
  2109 + sprintf (scratchbuf, "0x%x,0x%x", seg, offset);
  2110 + oappend (scratchbuf);
  2111 + break;
  2112 + case v_mode:
  2113 + if (aflag)
  2114 + offset = get32 ();
  2115 + else
  2116 + {
  2117 + offset = get16 ();
  2118 + if ((offset & 0x8000) != 0)
  2119 + offset -= 0x10000;
  2120 + }
  2121 +
  2122 + offset = start_pc + codep - start_codep + offset;
  2123 + set_op (offset);
  2124 + sprintf (scratchbuf, "0x%x", offset);
  2125 + oappend (scratchbuf);
  2126 + break;
  2127 + default:
  2128 + oappend ("<internal disassembler error>");
  2129 + break;
  2130 + }
  2131 + return (0);
  2132 +}
  2133 +
  2134 +/* ARGSUSED */
  2135 +static int
  2136 +OP_OFF (bytemode, aflag, dflag)
  2137 + int bytemode;
  2138 + int aflag;
  2139 + int dflag;
  2140 +{
  2141 + int off;
  2142 +
  2143 + append_prefix ();
  2144 +
  2145 + if (aflag)
  2146 + off = get32 ();
  2147 + else
  2148 + off = get16 ();
  2149 +
  2150 + sprintf (scratchbuf, "0x%x", off);
  2151 + oappend (scratchbuf);
  2152 + return (0);
  2153 +}
  2154 +
  2155 +/* ARGSUSED */
  2156 +static int
  2157 +OP_ESDI (dummy, aflag, dflag)
  2158 + int dummy;
  2159 + int aflag;
  2160 + int dflag;
  2161 +{
  2162 + oappend ("%es:(");
  2163 + oappend (aflag ? "%edi" : "%di");
  2164 + oappend (")");
  2165 + return (0);
  2166 +}
  2167 +
  2168 +/* ARGSUSED */
  2169 +static int
  2170 +OP_DSSI (dummy, aflag, dflag)
  2171 + int dummy;
  2172 + int aflag;
  2173 + int dflag;
  2174 +{
  2175 + if ((prefixes
  2176 + & (PREFIX_CS
  2177 + | PREFIX_DS
  2178 + | PREFIX_SS
  2179 + | PREFIX_ES
  2180 + | PREFIX_FS
  2181 + | PREFIX_GS)) == 0)
  2182 + prefixes |= PREFIX_DS;
  2183 + append_prefix ();
  2184 + oappend ("(");
  2185 + oappend (aflag ? "%esi" : "%si");
  2186 + oappend (")");
  2187 + return (0);
  2188 +}
  2189 +
  2190 +#if 0
  2191 +/* Not used. */
  2192 +
  2193 +/* ARGSUSED */
  2194 +static int
  2195 +OP_ONE (dummy, aflag, dflag)
  2196 + int dummy;
  2197 + int aflag;
  2198 + int dflag;
  2199 +{
  2200 + oappend ("1");
  2201 + return (0);
  2202 +}
  2203 +
  2204 +#endif
  2205 +
  2206 +/* ARGSUSED */
  2207 +static int
  2208 +OP_C (dummy, aflag, dflag)
  2209 + int dummy;
  2210 + int aflag;
  2211 + int dflag;
  2212 +{
  2213 + codep++; /* skip mod/rm */
  2214 + sprintf (scratchbuf, "%%cr%d", reg);
  2215 + oappend (scratchbuf);
  2216 + return (0);
  2217 +}
  2218 +
  2219 +/* ARGSUSED */
  2220 +static int
  2221 +OP_D (dummy, aflag, dflag)
  2222 + int dummy;
  2223 + int aflag;
  2224 + int dflag;
  2225 +{
  2226 + codep++; /* skip mod/rm */
  2227 + sprintf (scratchbuf, "%%db%d", reg);
  2228 + oappend (scratchbuf);
  2229 + return (0);
  2230 +}
  2231 +
  2232 +/* ARGSUSED */
  2233 +static int
  2234 +OP_T (dummy, aflag, dflag)
  2235 + int dummy;
  2236 + int aflag;
  2237 + int dflag;
  2238 +{
  2239 + codep++; /* skip mod/rm */
  2240 + sprintf (scratchbuf, "%%tr%d", reg);
  2241 + oappend (scratchbuf);
  2242 + return (0);
  2243 +}
  2244 +
  2245 +static int
  2246 +OP_rm (bytemode, aflag, dflag)
  2247 + int bytemode;
  2248 + int aflag;
  2249 + int dflag;
  2250 +{
  2251 + switch (bytemode)
  2252 + {
  2253 + case d_mode:
  2254 + oappend (names32[rm]);
  2255 + break;
  2256 + case w_mode:
  2257 + oappend (names16[rm]);
  2258 + break;
  2259 + }
  2260 + return (0);
  2261 +}
  2262 +
  2263 +static int
  2264 +OP_MMX (bytemode, aflag, dflag)
  2265 + int bytemode;
  2266 + int aflag;
  2267 + int dflag;
  2268 +{
  2269 + sprintf (scratchbuf, "%%mm%d", reg);
  2270 + oappend (scratchbuf);
  2271 + return 0;
  2272 +}
  2273 +
  2274 +static int
  2275 +OP_EM (bytemode, aflag, dflag)
  2276 + int bytemode;
  2277 + int aflag;
  2278 + int dflag;
  2279 +{
  2280 + if (mod != 3)
  2281 + return OP_E (bytemode, aflag, dflag);
  2282 +
  2283 + codep++;
  2284 + sprintf (scratchbuf, "%%mm%d", rm);
  2285 + oappend (scratchbuf);
  2286 + return 0;
  2287 +}
  2288 +
  2289 +static int
  2290 +OP_MS (bytemode, aflag, dflag)
  2291 + int bytemode;
  2292 + int aflag;
  2293 + int dflag;
  2294 +{
  2295 + ++codep;
  2296 + sprintf (scratchbuf, "%%mm%d", rm);
  2297 + oappend (scratchbuf);
  2298 + return 0;
  2299 +}
... ...
linux-user/syscall.c
... ... @@ -1000,7 +1000,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
1000 1000 ret = get_errno(setsid());
1001 1001 break;
1002 1002 case TARGET_NR_sigaction:
1003   -#if 1
  1003 +#if 0
1004 1004 {
1005 1005 ret = 0;
1006 1006 }
... ...
op-i386.c
... ... @@ -177,7 +177,7 @@ void raise_exception(int exception_index)
177 177 #undef REG
178 178 #undef REGNAME
179 179  
180   -/* operations */
  180 +/* operations with flags */
181 181  
182 182 void OPPROTO op_addl_T0_T1_cc(void)
183 183 {
... ... @@ -217,11 +217,6 @@ void OPPROTO op_cmpl_T0_T1_cc(void)
217 217 CC_DST = T0 - T1;
218 218 }
219 219  
220   -void OPPROTO op_notl_T0(void)
221   -{
222   - T0 = ~T0;
223   -}
224   -
225 220 void OPPROTO op_negl_T0_cc(void)
226 221 {
227 222 CC_SRC = 0;
... ... @@ -248,6 +243,53 @@ void OPPROTO op_testl_T0_T1_cc(void)
248 243 CC_DST = T0 & T1;
249 244 }
250 245  
  246 +/* operations without flags */
  247 +
  248 +void OPPROTO op_addl_T0_T1(void)
  249 +{
  250 + T0 += T1;
  251 +}
  252 +
  253 +void OPPROTO op_orl_T0_T1(void)
  254 +{
  255 + T0 |= T1;
  256 +}
  257 +
  258 +void OPPROTO op_andl_T0_T1(void)
  259 +{
  260 + T0 &= T1;
  261 +}
  262 +
  263 +void OPPROTO op_subl_T0_T1(void)
  264 +{
  265 + T0 -= T1;
  266 +}
  267 +
  268 +void OPPROTO op_xorl_T0_T1(void)
  269 +{
  270 + T0 ^= T1;
  271 +}
  272 +
  273 +void OPPROTO op_negl_T0(void)
  274 +{
  275 + T0 = -T0;
  276 +}
  277 +
  278 +void OPPROTO op_incl_T0(void)
  279 +{
  280 + T0++;
  281 +}
  282 +
  283 +void OPPROTO op_decl_T0(void)
  284 +{
  285 + T0--;
  286 +}
  287 +
  288 +void OPPROTO op_notl_T0(void)
  289 +{
  290 + T0 = ~T0;
  291 +}
  292 +
251 293 void OPPROTO op_bswapl_T0(void)
252 294 {
253 295 T0 = bswap32(T0);
... ...
opc-i386.h 0 → 100644
  1 +DEF(end)
  2 +DEF(movl_A0_EAX)
  3 +DEF(addl_A0_EAX)
  4 +DEF(addl_A0_EAX_s1)
  5 +DEF(addl_A0_EAX_s2)
  6 +DEF(addl_A0_EAX_s3)
  7 +DEF(movl_T0_EAX)
  8 +DEF(movl_T1_EAX)
  9 +DEF(movh_T0_EAX)
  10 +DEF(movh_T1_EAX)
  11 +DEF(movl_EAX_T0)
  12 +DEF(movl_EAX_T1)
  13 +DEF(movl_EAX_A0)
  14 +DEF(cmovw_EAX_T1_T0)
  15 +DEF(cmovl_EAX_T1_T0)
  16 +DEF(movw_EAX_T0)
  17 +DEF(movw_EAX_T1)
  18 +DEF(movw_EAX_A0)
  19 +DEF(movb_EAX_T0)
  20 +DEF(movh_EAX_T0)
  21 +DEF(movb_EAX_T1)
  22 +DEF(movh_EAX_T1)
  23 +DEF(movl_A0_ECX)
  24 +DEF(addl_A0_ECX)
  25 +DEF(addl_A0_ECX_s1)
  26 +DEF(addl_A0_ECX_s2)
  27 +DEF(addl_A0_ECX_s3)
  28 +DEF(movl_T0_ECX)
  29 +DEF(movl_T1_ECX)
  30 +DEF(movh_T0_ECX)
  31 +DEF(movh_T1_ECX)
  32 +DEF(movl_ECX_T0)
  33 +DEF(movl_ECX_T1)
  34 +DEF(movl_ECX_A0)
  35 +DEF(cmovw_ECX_T1_T0)
  36 +DEF(cmovl_ECX_T1_T0)
  37 +DEF(movw_ECX_T0)
  38 +DEF(movw_ECX_T1)
  39 +DEF(movw_ECX_A0)
  40 +DEF(movb_ECX_T0)
  41 +DEF(movh_ECX_T0)
  42 +DEF(movb_ECX_T1)
  43 +DEF(movh_ECX_T1)
  44 +DEF(movl_A0_EDX)
  45 +DEF(addl_A0_EDX)
  46 +DEF(addl_A0_EDX_s1)
  47 +DEF(addl_A0_EDX_s2)
  48 +DEF(addl_A0_EDX_s3)
  49 +DEF(movl_T0_EDX)
  50 +DEF(movl_T1_EDX)
  51 +DEF(movh_T0_EDX)
  52 +DEF(movh_T1_EDX)
  53 +DEF(movl_EDX_T0)
  54 +DEF(movl_EDX_T1)
  55 +DEF(movl_EDX_A0)
  56 +DEF(cmovw_EDX_T1_T0)
  57 +DEF(cmovl_EDX_T1_T0)
  58 +DEF(movw_EDX_T0)
  59 +DEF(movw_EDX_T1)
  60 +DEF(movw_EDX_A0)
  61 +DEF(movb_EDX_T0)
  62 +DEF(movh_EDX_T0)
  63 +DEF(movb_EDX_T1)
  64 +DEF(movh_EDX_T1)
  65 +DEF(movl_A0_EBX)
  66 +DEF(addl_A0_EBX)
  67 +DEF(addl_A0_EBX_s1)
  68 +DEF(addl_A0_EBX_s2)
  69 +DEF(addl_A0_EBX_s3)
  70 +DEF(movl_T0_EBX)
  71 +DEF(movl_T1_EBX)
  72 +DEF(movh_T0_EBX)
  73 +DEF(movh_T1_EBX)
  74 +DEF(movl_EBX_T0)
  75 +DEF(movl_EBX_T1)
  76 +DEF(movl_EBX_A0)
  77 +DEF(cmovw_EBX_T1_T0)
  78 +DEF(cmovl_EBX_T1_T0)
  79 +DEF(movw_EBX_T0)
  80 +DEF(movw_EBX_T1)
  81 +DEF(movw_EBX_A0)
  82 +DEF(movb_EBX_T0)
  83 +DEF(movh_EBX_T0)
  84 +DEF(movb_EBX_T1)
  85 +DEF(movh_EBX_T1)
  86 +DEF(movl_A0_ESP)
  87 +DEF(addl_A0_ESP)
  88 +DEF(addl_A0_ESP_s1)
  89 +DEF(addl_A0_ESP_s2)
  90 +DEF(addl_A0_ESP_s3)
  91 +DEF(movl_T0_ESP)
  92 +DEF(movl_T1_ESP)
  93 +DEF(movh_T0_ESP)
  94 +DEF(movh_T1_ESP)
  95 +DEF(movl_ESP_T0)
  96 +DEF(movl_ESP_T1)
  97 +DEF(movl_ESP_A0)
  98 +DEF(cmovw_ESP_T1_T0)
  99 +DEF(cmovl_ESP_T1_T0)
  100 +DEF(movw_ESP_T0)
  101 +DEF(movw_ESP_T1)
  102 +DEF(movw_ESP_A0)
  103 +DEF(movb_ESP_T0)
  104 +DEF(movh_ESP_T0)
  105 +DEF(movb_ESP_T1)
  106 +DEF(movh_ESP_T1)
  107 +DEF(movl_A0_EBP)
  108 +DEF(addl_A0_EBP)
  109 +DEF(addl_A0_EBP_s1)
  110 +DEF(addl_A0_EBP_s2)
  111 +DEF(addl_A0_EBP_s3)
  112 +DEF(movl_T0_EBP)
  113 +DEF(movl_T1_EBP)
  114 +DEF(movh_T0_EBP)
  115 +DEF(movh_T1_EBP)
  116 +DEF(movl_EBP_T0)
  117 +DEF(movl_EBP_T1)
  118 +DEF(movl_EBP_A0)
  119 +DEF(cmovw_EBP_T1_T0)
  120 +DEF(cmovl_EBP_T1_T0)
  121 +DEF(movw_EBP_T0)
  122 +DEF(movw_EBP_T1)
  123 +DEF(movw_EBP_A0)
  124 +DEF(movb_EBP_T0)
  125 +DEF(movh_EBP_T0)
  126 +DEF(movb_EBP_T1)
  127 +DEF(movh_EBP_T1)
  128 +DEF(movl_A0_ESI)
  129 +DEF(addl_A0_ESI)
  130 +DEF(addl_A0_ESI_s1)
  131 +DEF(addl_A0_ESI_s2)
  132 +DEF(addl_A0_ESI_s3)
  133 +DEF(movl_T0_ESI)
  134 +DEF(movl_T1_ESI)
  135 +DEF(movh_T0_ESI)
  136 +DEF(movh_T1_ESI)
  137 +DEF(movl_ESI_T0)
  138 +DEF(movl_ESI_T1)
  139 +DEF(movl_ESI_A0)
  140 +DEF(cmovw_ESI_T1_T0)
  141 +DEF(cmovl_ESI_T1_T0)
  142 +DEF(movw_ESI_T0)
  143 +DEF(movw_ESI_T1)
  144 +DEF(movw_ESI_A0)
  145 +DEF(movb_ESI_T0)
  146 +DEF(movh_ESI_T0)
  147 +DEF(movb_ESI_T1)
  148 +DEF(movh_ESI_T1)
  149 +DEF(movl_A0_EDI)
  150 +DEF(addl_A0_EDI)
  151 +DEF(addl_A0_EDI_s1)
  152 +DEF(addl_A0_EDI_s2)
  153 +DEF(addl_A0_EDI_s3)
  154 +DEF(movl_T0_EDI)
  155 +DEF(movl_T1_EDI)
  156 +DEF(movh_T0_EDI)
  157 +DEF(movh_T1_EDI)
  158 +DEF(movl_EDI_T0)
  159 +DEF(movl_EDI_T1)
  160 +DEF(movl_EDI_A0)
  161 +DEF(cmovw_EDI_T1_T0)
  162 +DEF(cmovl_EDI_T1_T0)
  163 +DEF(movw_EDI_T0)
  164 +DEF(movw_EDI_T1)
  165 +DEF(movw_EDI_A0)
  166 +DEF(movb_EDI_T0)
  167 +DEF(movh_EDI_T0)
  168 +DEF(movb_EDI_T1)
  169 +DEF(movh_EDI_T1)
  170 +DEF(addl_T0_T1_cc)
  171 +DEF(orl_T0_T1_cc)
  172 +DEF(andl_T0_T1_cc)
  173 +DEF(subl_T0_T1_cc)
  174 +DEF(xorl_T0_T1_cc)
  175 +DEF(cmpl_T0_T1_cc)
  176 +DEF(negl_T0_cc)
  177 +DEF(incl_T0_cc)
  178 +DEF(decl_T0_cc)
  179 +DEF(testl_T0_T1_cc)
  180 +DEF(addl_T0_T1)
  181 +DEF(orl_T0_T1)
  182 +DEF(andl_T0_T1)
  183 +DEF(subl_T0_T1)
  184 +DEF(xorl_T0_T1)
  185 +DEF(negl_T0)
  186 +DEF(incl_T0)
  187 +DEF(decl_T0)
  188 +DEF(notl_T0)
  189 +DEF(bswapl_T0)
  190 +DEF(mulb_AL_T0)
  191 +DEF(imulb_AL_T0)
  192 +DEF(mulw_AX_T0)
  193 +DEF(imulw_AX_T0)
  194 +DEF(mull_EAX_T0)
  195 +DEF(imull_EAX_T0)
  196 +DEF(imulw_T0_T1)
  197 +DEF(imull_T0_T1)
  198 +DEF(divb_AL_T0)
  199 +DEF(idivb_AL_T0)
  200 +DEF(divw_AX_T0)
  201 +DEF(idivw_AX_T0)
  202 +DEF(divl_EAX_T0)
  203 +DEF(idivl_EAX_T0)
  204 +DEF(movl_T0_im)
  205 +DEF(movl_T1_im)
  206 +DEF(movl_A0_im)
  207 +DEF(addl_A0_im)
  208 +DEF(andl_A0_ffff)
  209 +DEF(ldub_T0_A0)
  210 +DEF(ldsb_T0_A0)
  211 +DEF(lduw_T0_A0)
  212 +DEF(ldsw_T0_A0)
  213 +DEF(ldl_T0_A0)
  214 +DEF(ldub_T1_A0)
  215 +DEF(ldsb_T1_A0)
  216 +DEF(lduw_T1_A0)
  217 +DEF(ldsw_T1_A0)
  218 +DEF(ldl_T1_A0)
  219 +DEF(stb_T0_A0)
  220 +DEF(stw_T0_A0)
  221 +DEF(stl_T0_A0)
  222 +DEF(add_bitw_A0_T1)
  223 +DEF(add_bitl_A0_T1)
  224 +DEF(jmp_T0)
  225 +DEF(jmp_im)
  226 +DEF(int_im)
  227 +DEF(int3)
  228 +DEF(into)
  229 +DEF(jb_subb)
  230 +DEF(jz_subb)
  231 +DEF(jbe_subb)
  232 +DEF(js_subb)
  233 +DEF(jl_subb)
  234 +DEF(jle_subb)
  235 +DEF(setb_T0_subb)
  236 +DEF(setz_T0_subb)
  237 +DEF(setbe_T0_subb)
  238 +DEF(sets_T0_subb)
  239 +DEF(setl_T0_subb)
  240 +DEF(setle_T0_subb)
  241 +DEF(rolb_T0_T1_cc)
  242 +DEF(rolb_T0_T1)
  243 +DEF(rorb_T0_T1_cc)
  244 +DEF(rorb_T0_T1)
  245 +DEF(rclb_T0_T1_cc)
  246 +DEF(rcrb_T0_T1_cc)
  247 +DEF(shlb_T0_T1_cc)
  248 +DEF(shlb_T0_T1)
  249 +DEF(shrb_T0_T1_cc)
  250 +DEF(shrb_T0_T1)
  251 +DEF(sarb_T0_T1_cc)
  252 +DEF(sarb_T0_T1)
  253 +DEF(adcb_T0_T1_cc)
  254 +DEF(sbbb_T0_T1_cc)
  255 +DEF(cmpxchgb_T0_T1_EAX_cc)
  256 +DEF(movsb)
  257 +DEF(rep_movsb)
  258 +DEF(stosb)
  259 +DEF(rep_stosb)
  260 +DEF(lodsb)
  261 +DEF(rep_lodsb)
  262 +DEF(scasb)
  263 +DEF(repz_scasb)
  264 +DEF(repnz_scasb)
  265 +DEF(cmpsb)
  266 +DEF(repz_cmpsb)
  267 +DEF(repnz_cmpsb)
  268 +DEF(outsb)
  269 +DEF(rep_outsb)
  270 +DEF(insb)
  271 +DEF(rep_insb)
  272 +DEF(outb_T0_T1)
  273 +DEF(inb_T0_T1)
  274 +DEF(jb_subw)
  275 +DEF(jz_subw)
  276 +DEF(jbe_subw)
  277 +DEF(js_subw)
  278 +DEF(jl_subw)
  279 +DEF(jle_subw)
  280 +DEF(loopnzw)
  281 +DEF(loopzw)
  282 +DEF(loopw)
  283 +DEF(jecxzw)
  284 +DEF(setb_T0_subw)
  285 +DEF(setz_T0_subw)
  286 +DEF(setbe_T0_subw)
  287 +DEF(sets_T0_subw)
  288 +DEF(setl_T0_subw)
  289 +DEF(setle_T0_subw)
  290 +DEF(rolw_T0_T1_cc)
  291 +DEF(rolw_T0_T1)
  292 +DEF(rorw_T0_T1_cc)
  293 +DEF(rorw_T0_T1)
  294 +DEF(rclw_T0_T1_cc)
  295 +DEF(rcrw_T0_T1_cc)
  296 +DEF(shlw_T0_T1_cc)
  297 +DEF(shlw_T0_T1)
  298 +DEF(shrw_T0_T1_cc)
  299 +DEF(shrw_T0_T1)
  300 +DEF(sarw_T0_T1_cc)
  301 +DEF(sarw_T0_T1)
  302 +DEF(shldw_T0_T1_im_cc)
  303 +DEF(shldw_T0_T1_ECX_cc)
  304 +DEF(shrdw_T0_T1_im_cc)
  305 +DEF(shrdw_T0_T1_ECX_cc)
  306 +DEF(adcw_T0_T1_cc)
  307 +DEF(sbbw_T0_T1_cc)
  308 +DEF(cmpxchgw_T0_T1_EAX_cc)
  309 +DEF(btw_T0_T1_cc)
  310 +DEF(btsw_T0_T1_cc)
  311 +DEF(btrw_T0_T1_cc)
  312 +DEF(btcw_T0_T1_cc)
  313 +DEF(bsfw_T0_cc)
  314 +DEF(bsrw_T0_cc)
  315 +DEF(movsw)
  316 +DEF(rep_movsw)
  317 +DEF(stosw)
  318 +DEF(rep_stosw)
  319 +DEF(lodsw)
  320 +DEF(rep_lodsw)
  321 +DEF(scasw)
  322 +DEF(repz_scasw)
  323 +DEF(repnz_scasw)
  324 +DEF(cmpsw)
  325 +DEF(repz_cmpsw)
  326 +DEF(repnz_cmpsw)
  327 +DEF(outsw)
  328 +DEF(rep_outsw)
  329 +DEF(insw)
  330 +DEF(rep_insw)
  331 +DEF(outw_T0_T1)
  332 +DEF(inw_T0_T1)
  333 +DEF(jb_subl)
  334 +DEF(jz_subl)
  335 +DEF(jbe_subl)
  336 +DEF(js_subl)
  337 +DEF(jl_subl)
  338 +DEF(jle_subl)
  339 +DEF(loopnzl)
  340 +DEF(loopzl)
  341 +DEF(loopl)
  342 +DEF(jecxzl)
  343 +DEF(setb_T0_subl)
  344 +DEF(setz_T0_subl)
  345 +DEF(setbe_T0_subl)
  346 +DEF(sets_T0_subl)
  347 +DEF(setl_T0_subl)
  348 +DEF(setle_T0_subl)
  349 +DEF(roll_T0_T1_cc)
  350 +DEF(roll_T0_T1)
  351 +DEF(rorl_T0_T1_cc)
  352 +DEF(rorl_T0_T1)
  353 +DEF(rcll_T0_T1_cc)
  354 +DEF(rcrl_T0_T1_cc)
  355 +DEF(shll_T0_T1_cc)
  356 +DEF(shll_T0_T1)
  357 +DEF(shrl_T0_T1_cc)
  358 +DEF(shrl_T0_T1)
  359 +DEF(sarl_T0_T1_cc)
  360 +DEF(sarl_T0_T1)
  361 +DEF(shldl_T0_T1_im_cc)
  362 +DEF(shldl_T0_T1_ECX_cc)
  363 +DEF(shrdl_T0_T1_im_cc)
  364 +DEF(shrdl_T0_T1_ECX_cc)
  365 +DEF(adcl_T0_T1_cc)
  366 +DEF(sbbl_T0_T1_cc)
  367 +DEF(cmpxchgl_T0_T1_EAX_cc)
  368 +DEF(btl_T0_T1_cc)
  369 +DEF(btsl_T0_T1_cc)
  370 +DEF(btrl_T0_T1_cc)
  371 +DEF(btcl_T0_T1_cc)
  372 +DEF(bsfl_T0_cc)
  373 +DEF(bsrl_T0_cc)
  374 +DEF(movsl)
  375 +DEF(rep_movsl)
  376 +DEF(stosl)
  377 +DEF(rep_stosl)
  378 +DEF(lodsl)
  379 +DEF(rep_lodsl)
  380 +DEF(scasl)
  381 +DEF(repz_scasl)
  382 +DEF(repnz_scasl)
  383 +DEF(cmpsl)
  384 +DEF(repz_cmpsl)
  385 +DEF(repnz_cmpsl)
  386 +DEF(outsl)
  387 +DEF(rep_outsl)
  388 +DEF(insl)
  389 +DEF(rep_insl)
  390 +DEF(outl_T0_T1)
  391 +DEF(inl_T0_T1)
  392 +DEF(movsbl_T0_T0)
  393 +DEF(movzbl_T0_T0)
  394 +DEF(movswl_T0_T0)
  395 +DEF(movzwl_T0_T0)
  396 +DEF(movswl_EAX_AX)
  397 +DEF(movsbw_AX_AL)
  398 +DEF(movslq_EDX_EAX)
  399 +DEF(movswl_DX_AX)
  400 +DEF(pushl_T0)
  401 +DEF(pushl_T1)
  402 +DEF(popl_T0)
  403 +DEF(addl_ESP_im)
  404 +DEF(pushal)
  405 +DEF(pushaw)
  406 +DEF(popal)
  407 +DEF(popaw)
  408 +DEF(enterl)
  409 +DEF(rdtsc)
  410 +DEF(aam)
  411 +DEF(aad)
  412 +DEF(aaa)
  413 +DEF(aas)
  414 +DEF(daa)
  415 +DEF(das)
  416 +DEF(movl_seg_T0)
  417 +DEF(movl_T0_seg)
  418 +DEF(addl_A0_seg)
  419 +DEF(jo_cc)
  420 +DEF(jb_cc)
  421 +DEF(jz_cc)
  422 +DEF(jbe_cc)
  423 +DEF(js_cc)
  424 +DEF(jp_cc)
  425 +DEF(jl_cc)
  426 +DEF(jle_cc)
  427 +DEF(seto_T0_cc)
  428 +DEF(setb_T0_cc)
  429 +DEF(setz_T0_cc)
  430 +DEF(setbe_T0_cc)
  431 +DEF(sets_T0_cc)
  432 +DEF(setp_T0_cc)
  433 +DEF(setl_T0_cc)
  434 +DEF(setle_T0_cc)
  435 +DEF(xor_T0_1)
  436 +DEF(set_cc_op)
  437 +DEF(movl_eflags_T0)
  438 +DEF(movb_eflags_T0)
  439 +DEF(movl_T0_eflags)
  440 +DEF(cld)
  441 +DEF(std)
  442 +DEF(clc)
  443 +DEF(stc)
  444 +DEF(cmc)
  445 +DEF(salc)
  446 +DEF(flds_FT0_A0)
  447 +DEF(fldl_FT0_A0)
  448 +DEF(fild_FT0_A0)
  449 +DEF(fildl_FT0_A0)
  450 +DEF(fildll_FT0_A0)
  451 +DEF(flds_ST0_A0)
  452 +DEF(fldl_ST0_A0)
  453 +DEF(fldt_ST0_A0)
  454 +DEF(fild_ST0_A0)
  455 +DEF(fildl_ST0_A0)
  456 +DEF(fildll_ST0_A0)
  457 +DEF(fsts_ST0_A0)
  458 +DEF(fstl_ST0_A0)
  459 +DEF(fstt_ST0_A0)
  460 +DEF(fist_ST0_A0)
  461 +DEF(fistl_ST0_A0)
  462 +DEF(fistll_ST0_A0)
  463 +DEF(fbld_ST0_A0)
  464 +DEF(fbst_ST0_A0)
  465 +DEF(fpush)
  466 +DEF(fpop)
  467 +DEF(fdecstp)
  468 +DEF(fincstp)
  469 +DEF(fmov_ST0_FT0)
  470 +DEF(fmov_FT0_STN)
  471 +DEF(fmov_ST0_STN)
  472 +DEF(fmov_STN_ST0)
  473 +DEF(fxchg_ST0_STN)
  474 +DEF(fcom_ST0_FT0)
  475 +DEF(fucom_ST0_FT0)
  476 +DEF(fadd_ST0_FT0)
  477 +DEF(fmul_ST0_FT0)
  478 +DEF(fsub_ST0_FT0)
  479 +DEF(fsubr_ST0_FT0)
  480 +DEF(fdiv_ST0_FT0)
  481 +DEF(fdivr_ST0_FT0)
  482 +DEF(fadd_STN_ST0)
  483 +DEF(fmul_STN_ST0)
  484 +DEF(fsub_STN_ST0)
  485 +DEF(fsubr_STN_ST0)
  486 +DEF(fdiv_STN_ST0)
  487 +DEF(fdivr_STN_ST0)
  488 +DEF(fchs_ST0)
  489 +DEF(fabs_ST0)
  490 +DEF(fxam_ST0)
  491 +DEF(fld1_ST0)
  492 +DEF(fldl2t_ST0)
  493 +DEF(fldl2e_ST0)
  494 +DEF(fldpi_ST0)
  495 +DEF(fldlg2_ST0)
  496 +DEF(fldln2_ST0)
  497 +DEF(fldz_ST0)
  498 +DEF(fldz_FT0)
  499 +DEF(f2xm1)
  500 +DEF(fyl2x)
  501 +DEF(fptan)
  502 +DEF(fpatan)
  503 +DEF(fxtract)
  504 +DEF(fprem1)
  505 +DEF(fprem)
  506 +DEF(fyl2xp1)
  507 +DEF(fsqrt)
  508 +DEF(fsincos)
  509 +DEF(frndint)
  510 +DEF(fscale)
  511 +DEF(fsin)
  512 +DEF(fcos)
  513 +DEF(fnstsw_A0)
  514 +DEF(fnstsw_EAX)
  515 +DEF(fnstcw_A0)
  516 +DEF(fldcw_A0)
  517 +DEF(fclex)
  518 +DEF(fninit)
... ...
ops_template.h
... ... @@ -385,7 +385,6 @@ void OPPROTO glue(op_setle_T0_sub, SUFFIX)(void)
385 385 void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
386 386 {
387 387 int count, src;
388   - /* XXX: testing */
389 388 count = T1 & SHIFT_MASK;
390 389 if (count) {
391 390 CC_SRC = cc_table[CC_OP].compute_all() & ~(CC_O | CC_C);
... ... @@ -399,6 +398,17 @@ void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1_cc)(void)
399 398 FORCE_RET();
400 399 }
401 400  
  401 +void OPPROTO glue(glue(op_rol, SUFFIX), _T0_T1)(void)
  402 +{
  403 + int count;
  404 + count = T1 & SHIFT_MASK;
  405 + if (count) {
  406 + T0 &= DATA_MASK;
  407 + T0 = (T0 << count) | (T0 >> (DATA_BITS - count));
  408 + }
  409 + FORCE_RET();
  410 +}
  411 +
402 412 void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
403 413 {
404 414 int count, src;
... ... @@ -415,6 +425,17 @@ void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1_cc)(void)
415 425 FORCE_RET();
416 426 }
417 427  
  428 +void OPPROTO glue(glue(op_ror, SUFFIX), _T0_T1)(void)
  429 +{
  430 + int count;
  431 + count = T1 & SHIFT_MASK;
  432 + if (count) {
  433 + T0 &= DATA_MASK;
  434 + T0 = (T0 >> count) | (T0 << (DATA_BITS - count));
  435 + }
  436 + FORCE_RET();
  437 +}
  438 +
418 439 void OPPROTO glue(glue(op_rcl, SUFFIX), _T0_T1_cc)(void)
419 440 {
420 441 int count, res, eflags;
... ... @@ -482,6 +503,14 @@ void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1_cc)(void)
482 503 FORCE_RET();
483 504 }
484 505  
  506 +void OPPROTO glue(glue(op_shl, SUFFIX), _T0_T1)(void)
  507 +{
  508 + int count;
  509 + count = T1 & 0x1f;
  510 + T0 = T0 << count;
  511 + FORCE_RET();
  512 +}
  513 +
485 514 void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
486 515 {
487 516 int count;
... ... @@ -496,6 +525,15 @@ void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1_cc)(void)
496 525 FORCE_RET();
497 526 }
498 527  
  528 +void OPPROTO glue(glue(op_shr, SUFFIX), _T0_T1)(void)
  529 +{
  530 + int count;
  531 + count = T1 & 0x1f;
  532 + T0 &= DATA_MASK;
  533 + T0 = T0 >> count;
  534 + FORCE_RET();
  535 +}
  536 +
499 537 void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
500 538 {
501 539 int count, src;
... ... @@ -510,6 +548,15 @@ void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1_cc)(void)
510 548 FORCE_RET();
511 549 }
512 550  
  551 +void OPPROTO glue(glue(op_sar, SUFFIX), _T0_T1)(void)
  552 +{
  553 + int count, src;
  554 + count = T1 & 0x1f;
  555 + src = (DATA_STYPE)T0;
  556 + T0 = src >> count;
  557 + FORCE_RET();
  558 +}
  559 +
513 560 #if DATA_BITS == 16
514 561 /* XXX: overflow flag might be incorrect in some cases in shldw */
515 562 void OPPROTO glue(glue(op_shld, SUFFIX), _T0_T1_im_cc)(void)
... ...
translate-i386.c
... ... @@ -38,7 +38,8 @@
38 38 #define offsetof(type, field) ((size_t) &((type *)0)->field)
39 39 #endif
40 40  
41   -static uint8_t *gen_code_ptr;
  41 +static uint16_t *gen_opc_ptr;
  42 +static uint32_t *gen_opparam_ptr;
42 43 int __op_param1, __op_param2, __op_param3;
43 44  
44 45 extern FILE *logfile;
... ... @@ -95,6 +96,13 @@ enum {
95 96 OP_SAR = 7,
96 97 };
97 98  
  99 +enum {
  100 +#define DEF(s) INDEX_op_ ## s,
  101 +#include "opc-i386.h"
  102 +#undef DEF
  103 + NB_OPS,
  104 +};
  105 +
98 106 #include "op-i386.h"
99 107  
100 108 /* operand size */
... ... @@ -1922,7 +1930,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
1922 1930 if (mod == 3)
1923 1931 goto illegal_op;
1924 1932 gen_op_ld_T1_A0[ot]();
1925   - op_addl_A0_im(1 << (ot - OT_WORD + 1));
  1933 + gen_op_addl_A0_im(1 << (ot - OT_WORD + 1));
1926 1934 /* load the segment first to handle exceptions properly */
1927 1935 gen_op_lduw_T0_A0();
1928 1936 gen_movl_seg_T0(s, op);
... ... @@ -2842,24 +2850,350 @@ long disas_insn(DisasContext *s, uint8_t *pc_start)
2842 2850 return -1;
2843 2851 }
2844 2852  
  2853 +#define CC_OSZAPC (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C)
  2854 +#define CC_OSZAP (CC_O | CC_S | CC_Z | CC_A | CC_P)
  2855 +
  2856 +/* flags read by an operation */
  2857 +static uint16_t opc_read_flags[NB_OPS] = {
  2858 + [INDEX_op_aas] = CC_A,
  2859 + [INDEX_op_aaa] = CC_A,
  2860 + [INDEX_op_das] = CC_A | CC_C,
  2861 + [INDEX_op_daa] = CC_A | CC_C,
  2862 +
  2863 + [INDEX_op_adcb_T0_T1_cc] = CC_C,
  2864 + [INDEX_op_adcw_T0_T1_cc] = CC_C,
  2865 + [INDEX_op_adcl_T0_T1_cc] = CC_C,
  2866 + [INDEX_op_sbbb_T0_T1_cc] = CC_C,
  2867 + [INDEX_op_sbbw_T0_T1_cc] = CC_C,
  2868 + [INDEX_op_sbbl_T0_T1_cc] = CC_C,
  2869 +
  2870 + [INDEX_op_into] = CC_O,
  2871 +
  2872 + [INDEX_op_jo_cc] = CC_O,
  2873 + [INDEX_op_jb_cc] = CC_C,
  2874 + [INDEX_op_jz_cc] = CC_Z,
  2875 + [INDEX_op_jbe_cc] = CC_Z | CC_C,
  2876 + [INDEX_op_js_cc] = CC_S,
  2877 + [INDEX_op_jp_cc] = CC_P,
  2878 + [INDEX_op_jl_cc] = CC_O | CC_S,
  2879 + [INDEX_op_jle_cc] = CC_O | CC_S | CC_Z,
  2880 +
  2881 + [INDEX_op_jb_subb] = CC_C,
  2882 + [INDEX_op_jb_subw] = CC_C,
  2883 + [INDEX_op_jb_subl] = CC_C,
  2884 +
  2885 + [INDEX_op_jz_subb] = CC_Z,
  2886 + [INDEX_op_jz_subw] = CC_Z,
  2887 + [INDEX_op_jz_subl] = CC_Z,
  2888 +
  2889 + [INDEX_op_jbe_subb] = CC_Z | CC_C,
  2890 + [INDEX_op_jbe_subw] = CC_Z | CC_C,
  2891 + [INDEX_op_jbe_subl] = CC_Z | CC_C,
  2892 +
  2893 + [INDEX_op_js_subb] = CC_S,
  2894 + [INDEX_op_js_subw] = CC_S,
  2895 + [INDEX_op_js_subl] = CC_S,
  2896 +
  2897 + [INDEX_op_jl_subb] = CC_O | CC_S,
  2898 + [INDEX_op_jl_subw] = CC_O | CC_S,
  2899 + [INDEX_op_jl_subl] = CC_O | CC_S,
  2900 +
  2901 + [INDEX_op_jle_subb] = CC_O | CC_S | CC_Z,
  2902 + [INDEX_op_jle_subw] = CC_O | CC_S | CC_Z,
  2903 + [INDEX_op_jle_subl] = CC_O | CC_S | CC_Z,
  2904 +
  2905 + [INDEX_op_loopnzw] = CC_Z,
  2906 + [INDEX_op_loopnzl] = CC_Z,
  2907 + [INDEX_op_loopzw] = CC_Z,
  2908 + [INDEX_op_loopzl] = CC_Z,
  2909 +
  2910 + [INDEX_op_seto_T0_cc] = CC_O,
  2911 + [INDEX_op_setb_T0_cc] = CC_C,
  2912 + [INDEX_op_setz_T0_cc] = CC_Z,
  2913 + [INDEX_op_setbe_T0_cc] = CC_Z | CC_C,
  2914 + [INDEX_op_sets_T0_cc] = CC_S,
  2915 + [INDEX_op_setp_T0_cc] = CC_P,
  2916 + [INDEX_op_setl_T0_cc] = CC_O | CC_S,
  2917 + [INDEX_op_setle_T0_cc] = CC_O | CC_S | CC_Z,
  2918 +
  2919 + [INDEX_op_setb_T0_subb] = CC_C,
  2920 + [INDEX_op_setb_T0_subw] = CC_C,
  2921 + [INDEX_op_setb_T0_subl] = CC_C,
  2922 +
  2923 + [INDEX_op_setz_T0_subb] = CC_Z,
  2924 + [INDEX_op_setz_T0_subw] = CC_Z,
  2925 + [INDEX_op_setz_T0_subl] = CC_Z,
  2926 +
  2927 + [INDEX_op_setbe_T0_subb] = CC_Z | CC_C,
  2928 + [INDEX_op_setbe_T0_subw] = CC_Z | CC_C,
  2929 + [INDEX_op_setbe_T0_subl] = CC_Z | CC_C,
  2930 +
  2931 + [INDEX_op_sets_T0_subb] = CC_S,
  2932 + [INDEX_op_sets_T0_subw] = CC_S,
  2933 + [INDEX_op_sets_T0_subl] = CC_S,
  2934 +
  2935 + [INDEX_op_setl_T0_subb] = CC_O | CC_S,
  2936 + [INDEX_op_setl_T0_subw] = CC_O | CC_S,
  2937 + [INDEX_op_setl_T0_subl] = CC_O | CC_S,
  2938 +
  2939 + [INDEX_op_setle_T0_subb] = CC_O | CC_S | CC_Z,
  2940 + [INDEX_op_setle_T0_subw] = CC_O | CC_S | CC_Z,
  2941 + [INDEX_op_setle_T0_subl] = CC_O | CC_S | CC_Z,
  2942 +
  2943 + [INDEX_op_movl_T0_eflags] = CC_OSZAPC,
  2944 + [INDEX_op_cmc] = CC_C,
  2945 + [INDEX_op_salc] = CC_C,
  2946 +
  2947 + [INDEX_op_rclb_T0_T1_cc] = CC_C,
  2948 + [INDEX_op_rclw_T0_T1_cc] = CC_C,
  2949 + [INDEX_op_rcll_T0_T1_cc] = CC_C,
  2950 + [INDEX_op_rcrb_T0_T1_cc] = CC_C,
  2951 + [INDEX_op_rcrw_T0_T1_cc] = CC_C,
  2952 + [INDEX_op_rcrl_T0_T1_cc] = CC_C,
  2953 +};
  2954 +
  2955 +/* flags written by an operation */
  2956 +static uint16_t opc_write_flags[NB_OPS] = {
  2957 + [INDEX_op_addl_T0_T1_cc] = CC_OSZAPC,
  2958 + [INDEX_op_orl_T0_T1_cc] = CC_OSZAPC,
  2959 + [INDEX_op_adcb_T0_T1_cc] = CC_OSZAPC,
  2960 + [INDEX_op_adcw_T0_T1_cc] = CC_OSZAPC,
  2961 + [INDEX_op_adcl_T0_T1_cc] = CC_OSZAPC,
  2962 + [INDEX_op_sbbb_T0_T1_cc] = CC_OSZAPC,
  2963 + [INDEX_op_sbbw_T0_T1_cc] = CC_OSZAPC,
  2964 + [INDEX_op_sbbl_T0_T1_cc] = CC_OSZAPC,
  2965 + [INDEX_op_andl_T0_T1_cc] = CC_OSZAPC,
  2966 + [INDEX_op_subl_T0_T1_cc] = CC_OSZAPC,
  2967 + [INDEX_op_xorl_T0_T1_cc] = CC_OSZAPC,
  2968 + [INDEX_op_cmpl_T0_T1_cc] = CC_OSZAPC,
  2969 + [INDEX_op_negl_T0_cc] = CC_OSZAPC,
  2970 + [INDEX_op_incl_T0_cc] = CC_OSZAP,
  2971 + [INDEX_op_decl_T0_cc] = CC_OSZAP,
  2972 + [INDEX_op_testl_T0_T1_cc] = CC_OSZAPC,
  2973 +
  2974 + [INDEX_op_mulb_AL_T0] = CC_OSZAPC,
  2975 + [INDEX_op_imulb_AL_T0] = CC_OSZAPC,
  2976 + [INDEX_op_mulw_AX_T0] = CC_OSZAPC,
  2977 + [INDEX_op_imulw_AX_T0] = CC_OSZAPC,
  2978 + [INDEX_op_mull_EAX_T0] = CC_OSZAPC,
  2979 + [INDEX_op_imull_EAX_T0] = CC_OSZAPC,
  2980 + [INDEX_op_imulw_T0_T1] = CC_OSZAPC,
  2981 + [INDEX_op_imull_T0_T1] = CC_OSZAPC,
  2982 +
  2983 + /* bcd */
  2984 + [INDEX_op_aam] = CC_OSZAPC,
  2985 + [INDEX_op_aad] = CC_OSZAPC,
  2986 + [INDEX_op_aas] = CC_OSZAPC,
  2987 + [INDEX_op_aaa] = CC_OSZAPC,
  2988 + [INDEX_op_das] = CC_OSZAPC,
  2989 + [INDEX_op_daa] = CC_OSZAPC,
  2990 +
  2991 + [INDEX_op_movb_eflags_T0] = CC_S | CC_Z | CC_A | CC_P | CC_C,
  2992 + [INDEX_op_movl_eflags_T0] = CC_OSZAPC,
  2993 + [INDEX_op_clc] = CC_C,
  2994 + [INDEX_op_stc] = CC_C,
  2995 + [INDEX_op_cmc] = CC_C,
  2996 +
  2997 + [INDEX_op_rolb_T0_T1_cc] = CC_O | CC_C,
  2998 + [INDEX_op_rolw_T0_T1_cc] = CC_O | CC_C,
  2999 + [INDEX_op_roll_T0_T1_cc] = CC_O | CC_C,
  3000 + [INDEX_op_rorb_T0_T1_cc] = CC_O | CC_C,
  3001 + [INDEX_op_rorw_T0_T1_cc] = CC_O | CC_C,
  3002 + [INDEX_op_rorl_T0_T1_cc] = CC_O | CC_C,
  3003 +
  3004 + [INDEX_op_rclb_T0_T1_cc] = CC_O | CC_C,
  3005 + [INDEX_op_rclw_T0_T1_cc] = CC_O | CC_C,
  3006 + [INDEX_op_rcll_T0_T1_cc] = CC_O | CC_C,
  3007 + [INDEX_op_rcrb_T0_T1_cc] = CC_O | CC_C,
  3008 + [INDEX_op_rcrw_T0_T1_cc] = CC_O | CC_C,
  3009 + [INDEX_op_rcrl_T0_T1_cc] = CC_O | CC_C,
  3010 +
  3011 + [INDEX_op_shlb_T0_T1_cc] = CC_OSZAPC,
  3012 + [INDEX_op_shlw_T0_T1_cc] = CC_OSZAPC,
  3013 + [INDEX_op_shll_T0_T1_cc] = CC_OSZAPC,
  3014 +
  3015 + [INDEX_op_shrb_T0_T1_cc] = CC_OSZAPC,
  3016 + [INDEX_op_shrw_T0_T1_cc] = CC_OSZAPC,
  3017 + [INDEX_op_shrl_T0_T1_cc] = CC_OSZAPC,
  3018 +
  3019 + [INDEX_op_sarb_T0_T1_cc] = CC_OSZAPC,
  3020 + [INDEX_op_sarw_T0_T1_cc] = CC_OSZAPC,
  3021 + [INDEX_op_sarl_T0_T1_cc] = CC_OSZAPC,
  3022 +
  3023 + [INDEX_op_shldw_T0_T1_ECX_cc] = CC_OSZAPC,
  3024 + [INDEX_op_shldl_T0_T1_ECX_cc] = CC_OSZAPC,
  3025 + [INDEX_op_shldw_T0_T1_im_cc] = CC_OSZAPC,
  3026 + [INDEX_op_shldl_T0_T1_im_cc] = CC_OSZAPC,
  3027 +
  3028 + [INDEX_op_shrdw_T0_T1_ECX_cc] = CC_OSZAPC,
  3029 + [INDEX_op_shrdl_T0_T1_ECX_cc] = CC_OSZAPC,
  3030 + [INDEX_op_shrdw_T0_T1_im_cc] = CC_OSZAPC,
  3031 + [INDEX_op_shrdl_T0_T1_im_cc] = CC_OSZAPC,
  3032 +
  3033 + [INDEX_op_btw_T0_T1_cc] = CC_OSZAPC,
  3034 + [INDEX_op_btl_T0_T1_cc] = CC_OSZAPC,
  3035 + [INDEX_op_btsw_T0_T1_cc] = CC_OSZAPC,
  3036 + [INDEX_op_btsl_T0_T1_cc] = CC_OSZAPC,
  3037 + [INDEX_op_btrw_T0_T1_cc] = CC_OSZAPC,
  3038 + [INDEX_op_btrl_T0_T1_cc] = CC_OSZAPC,
  3039 + [INDEX_op_btcw_T0_T1_cc] = CC_OSZAPC,
  3040 + [INDEX_op_btcl_T0_T1_cc] = CC_OSZAPC,
  3041 +
  3042 + [INDEX_op_bsfw_T0_cc] = CC_OSZAPC,
  3043 + [INDEX_op_bsfl_T0_cc] = CC_OSZAPC,
  3044 + [INDEX_op_bsrw_T0_cc] = CC_OSZAPC,
  3045 + [INDEX_op_bsrl_T0_cc] = CC_OSZAPC,
  3046 +
  3047 + [INDEX_op_scasb] = CC_OSZAPC,
  3048 + [INDEX_op_scasw] = CC_OSZAPC,
  3049 + [INDEX_op_scasl] = CC_OSZAPC,
  3050 + [INDEX_op_repz_scasb] = CC_OSZAPC,
  3051 + [INDEX_op_repz_scasw] = CC_OSZAPC,
  3052 + [INDEX_op_repz_scasl] = CC_OSZAPC,
  3053 + [INDEX_op_repnz_scasb] = CC_OSZAPC,
  3054 + [INDEX_op_repnz_scasw] = CC_OSZAPC,
  3055 + [INDEX_op_repnz_scasl] = CC_OSZAPC,
  3056 +
  3057 + [INDEX_op_cmpsb] = CC_OSZAPC,
  3058 + [INDEX_op_cmpsw] = CC_OSZAPC,
  3059 + [INDEX_op_cmpsl] = CC_OSZAPC,
  3060 + [INDEX_op_repz_cmpsb] = CC_OSZAPC,
  3061 + [INDEX_op_repz_cmpsw] = CC_OSZAPC,
  3062 + [INDEX_op_repz_cmpsl] = CC_OSZAPC,
  3063 + [INDEX_op_repnz_cmpsb] = CC_OSZAPC,
  3064 + [INDEX_op_repnz_cmpsw] = CC_OSZAPC,
  3065 + [INDEX_op_repnz_cmpsl] = CC_OSZAPC,
  3066 +
  3067 + [INDEX_op_cmpxchgw_T0_T1_EAX_cc] = CC_OSZAPC,
  3068 + [INDEX_op_cmpxchgl_T0_T1_EAX_cc] = CC_OSZAPC,
  3069 +};
  3070 +
  3071 +/* simpler form of an operation if no flags need to be generated */
  3072 +static uint16_t opc_simpler[NB_OPS] = {
  3073 + [INDEX_op_addl_T0_T1_cc] = INDEX_op_addl_T0_T1,
  3074 + [INDEX_op_orl_T0_T1_cc] = INDEX_op_orl_T0_T1,
  3075 + [INDEX_op_andl_T0_T1_cc] = INDEX_op_andl_T0_T1,
  3076 + [INDEX_op_subl_T0_T1_cc] = INDEX_op_subl_T0_T1,
  3077 + [INDEX_op_xorl_T0_T1_cc] = INDEX_op_xorl_T0_T1,
  3078 + [INDEX_op_negl_T0_cc] = INDEX_op_negl_T0,
  3079 + [INDEX_op_incl_T0_cc] = INDEX_op_incl_T0,
  3080 + [INDEX_op_decl_T0_cc] = INDEX_op_decl_T0,
  3081 +
  3082 + [INDEX_op_rolb_T0_T1_cc] = INDEX_op_rolb_T0_T1,
  3083 + [INDEX_op_rolw_T0_T1_cc] = INDEX_op_rolw_T0_T1,
  3084 + [INDEX_op_roll_T0_T1_cc] = INDEX_op_roll_T0_T1,
  3085 +
  3086 + [INDEX_op_rorb_T0_T1_cc] = INDEX_op_rorb_T0_T1,
  3087 + [INDEX_op_rorw_T0_T1_cc] = INDEX_op_rorw_T0_T1,
  3088 + [INDEX_op_rorl_T0_T1_cc] = INDEX_op_rorl_T0_T1,
  3089 +
  3090 + [INDEX_op_shlb_T0_T1_cc] = INDEX_op_shlb_T0_T1,
  3091 + [INDEX_op_shlw_T0_T1_cc] = INDEX_op_shlw_T0_T1,
  3092 + [INDEX_op_shll_T0_T1_cc] = INDEX_op_shll_T0_T1,
  3093 +
  3094 + [INDEX_op_shrb_T0_T1_cc] = INDEX_op_shrb_T0_T1,
  3095 + [INDEX_op_shrw_T0_T1_cc] = INDEX_op_shrw_T0_T1,
  3096 + [INDEX_op_shrl_T0_T1_cc] = INDEX_op_shrl_T0_T1,
  3097 +
  3098 + [INDEX_op_sarb_T0_T1_cc] = INDEX_op_sarb_T0_T1,
  3099 + [INDEX_op_sarw_T0_T1_cc] = INDEX_op_sarw_T0_T1,
  3100 + [INDEX_op_sarl_T0_T1_cc] = INDEX_op_sarl_T0_T1,
  3101 +};
  3102 +
  3103 +static void optimize_flags_init(void)
  3104 +{
  3105 + int i;
  3106 + /* put default values in arrays */
  3107 + for(i = 0; i < NB_OPS; i++) {
  3108 + if (opc_simpler[i] == 0)
  3109 + opc_simpler[i] = i;
  3110 + }
  3111 +}
  3112 +
  3113 +/* CPU flags computation optimization: we move backward thru the
  3114 + generated code to see which flags are needed. The operation is
  3115 + modified if suitable */
  3116 +static void optimize_flags(uint16_t *opc_buf, int opc_buf_len)
  3117 +{
  3118 + uint16_t *opc_ptr;
  3119 + int live_flags, write_flags, op;
  3120 +
  3121 + opc_ptr = opc_buf + opc_buf_len;
  3122 + /* live_flags contains the flags needed by the next instructions
  3123 + in the code. At the end of the bloc, we consider that all the
  3124 + flags are live. */
  3125 + live_flags = CC_OSZAPC;
  3126 + while (opc_ptr > opc_buf) {
  3127 + op = *--opc_ptr;
  3128 + /* if none of the flags written by the instruction is used,
  3129 + then we can try to find a simpler instruction */
  3130 + write_flags = opc_write_flags[op];
  3131 + if ((live_flags & write_flags) == 0) {
  3132 + *opc_ptr = opc_simpler[op];
  3133 + }
  3134 + /* compute the live flags before the instruction */
  3135 + live_flags &= ~write_flags;
  3136 + live_flags |= opc_read_flags[op];
  3137 + }
  3138 +}
  3139 +
  3140 +
  3141 +#ifdef DEBUG_DISAS
  3142 +static const char *op_str[] = {
  3143 +#define DEF(s) #s,
  3144 +#include "opc-i386.h"
  3145 +#undef DEF
  3146 +};
  3147 +
  3148 +static void dump_ops(const uint16_t *opc_buf)
  3149 +{
  3150 + const uint16_t *opc_ptr;
  3151 + int c;
  3152 + opc_ptr = opc_buf;
  3153 + for(;;) {
  3154 + c = *opc_ptr++;
  3155 + fprintf(logfile, "0x%04x: %s\n", opc_ptr - opc_buf - 1, op_str[c]);
  3156 + if (c == INDEX_op_end)
  3157 + break;
  3158 + }
  3159 +}
  3160 +
  3161 +#endif
  3162 +
  3163 +/* XXX: make this buffer thread safe */
  3164 +/* XXX: make safe guess about sizes */
  3165 +#define MAX_OP_PER_INSTR 32
  3166 +#define OPC_BUF_SIZE 512
  3167 +#define OPC_MAX_SIZE (OPC_BUF_SIZE - MAX_OP_PER_INSTR)
  3168 +
  3169 +#define OPPARAM_BUF_SIZE (OPC_BUF_SIZE * 3)
  3170 +
  3171 +static uint16_t gen_opc_buf[OPC_BUF_SIZE];
  3172 +static uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
  3173 +
2845 3174 /* return the next pc */
2846 3175 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
2847 3176 int *gen_code_size_ptr, uint8_t *pc_start,
2848 3177 int flags)
2849 3178 {
2850 3179 DisasContext dc1, *dc = &dc1;
2851   - uint8_t *gen_code_end, *pc_ptr;
  3180 + uint8_t *pc_ptr;
  3181 + uint16_t *gen_opc_end;
2852 3182 long ret;
2853 3183 #ifdef DEBUG_DISAS
2854 3184 struct disassemble_info disasm_info;
2855 3185 #endif
  3186 +
  3187 + /* generate intermediate code */
  3188 +
2856 3189 dc->code32 = (flags >> GEN_FLAG_CODE32_SHIFT) & 1;
2857 3190 dc->addseg = (flags >> GEN_FLAG_ADDSEG_SHIFT) & 1;
2858 3191 dc->f_st = (flags >> GEN_FLAG_ST_SHIFT) & 7;
2859 3192 dc->cc_op = CC_OP_DYNAMIC;
2860   - gen_code_ptr = gen_code_buf;
2861   - gen_code_end = gen_code_buf + max_code_size - 4096;
2862   - gen_start();
  3193 +
  3194 + gen_opc_ptr = gen_opc_buf;
  3195 + gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
  3196 + gen_opparam_ptr = gen_opparam_buf;
2863 3197  
2864 3198 dc->is_jmp = 0;
2865 3199 pc_ptr = pc_start;
... ... @@ -2871,7 +3205,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
2871 3205 abort();
2872 3206 }
2873 3207 pc_ptr = (void *)ret;
2874   - } while (!dc->is_jmp && gen_code_ptr < gen_code_end);
  3208 + } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end);
2875 3209 /* we must store the eflags state if it is not already done */
2876 3210 if (dc->cc_op != CC_OP_DYNAMIC)
2877 3211 gen_op_set_cc_op(dc->cc_op);
... ... @@ -2879,9 +3213,9 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
2879 3213 /* we add an additionnal jmp to update the simulated PC */
2880 3214 gen_op_jmp_im(ret);
2881 3215 }
2882   - gen_end();
2883   - *gen_code_size_ptr = gen_code_ptr - gen_code_buf;
  3216 + *gen_opc_ptr = INDEX_op_end;
2884 3217  
  3218 + /* optimize flag computations */
2885 3219 #ifdef DEBUG_DISAS
2886 3220 if (loglevel) {
2887 3221 uint8_t *pc;
... ... @@ -2898,6 +3232,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
2898 3232 #else
2899 3233 disasm_info.endian = BFD_ENDIAN_LITTLE;
2900 3234 #endif
  3235 + fprintf(logfile, "----------------\n");
2901 3236 fprintf(logfile, "IN:\n");
2902 3237 disasm_info.buffer = pc_start;
2903 3238 disasm_info.buffer_vma = (unsigned long)pc_start;
... ... @@ -2911,12 +3246,37 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
2911 3246 }
2912 3247 fprintf(logfile, "\n");
2913 3248  
  3249 + fprintf(logfile, "OP:\n");
  3250 + dump_ops(gen_opc_buf);
  3251 + fprintf(logfile, "\n");
  3252 + }
  3253 +#endif
  3254 +
  3255 + /* optimize flag computations */
  3256 + optimize_flags(gen_opc_buf, gen_opc_ptr - gen_opc_buf);
  3257 +
  3258 +#ifdef DEBUG_DISAS
  3259 + if (loglevel) {
  3260 + fprintf(logfile, "AFTER FLAGS OPT:\n");
  3261 + dump_ops(gen_opc_buf);
  3262 + fprintf(logfile, "\n");
  3263 + }
  3264 +#endif
  3265 +
  3266 + /* generate machine code */
  3267 + *gen_code_size_ptr = dyngen_code(gen_code_buf, gen_opc_buf, gen_opparam_buf);
  3268 +
  3269 +#ifdef DEBUG_DISAS
  3270 + if (loglevel) {
  3271 + uint8_t *pc;
  3272 + int count;
  3273 +
2914 3274 pc = gen_code_buf;
2915 3275 disasm_info.buffer = pc;
2916 3276 disasm_info.buffer_vma = (unsigned long)pc;
2917 3277 disasm_info.buffer_length = *gen_code_size_ptr;
2918 3278 fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
2919   - while (pc < gen_code_ptr) {
  3279 + while (pc < gen_code_buf + *gen_code_size_ptr) {
2920 3280 fprintf(logfile, "0x%08lx: ", (long)pc);
2921 3281 count = print_insn_i386((unsigned long)pc, &disasm_info);
2922 3282 fprintf(logfile, "\n");
... ... @@ -2932,6 +3292,7 @@ CPUX86State *cpu_x86_init(void)
2932 3292 {
2933 3293 CPUX86State *env;
2934 3294 int i;
  3295 + static int inited;
2935 3296  
2936 3297 cpu_x86_tblocks_init();
2937 3298  
... ... @@ -2946,6 +3307,12 @@ CPUX86State *cpu_x86_init(void)
2946 3307 /* flags setup */
2947 3308 env->cc_op = CC_OP_EFLAGS;
2948 3309 env->df = 1;
  3310 +
  3311 + /* init various static tables */
  3312 + if (!inited) {
  3313 + inited = 1;
  3314 + optimize_flags_init();
  3315 + }
2949 3316 return env;
2950 3317 }
2951 3318  
... ...