Commit 7d13299d07a9c3c42277207ae7a691f0501a70b2

Authored by bellard
1 parent 1017ebe9

added translation cache


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@25 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
1   -ARCH=i386
2   -#ARCH=ppc
3   -HOST_CC=gcc
  1 +include config.mak
4 2  
5   -ifeq ($(ARCH),i386)
6   -CFLAGS=-Wall -O2 -g -fomit-frame-pointer
  3 +CFLAGS=-Wall -O2 -g
7 4 LDFLAGS=-g
8 5 LIBS=
9   -CC=gcc
10 6 DEFINES=-DHAVE_BYTESWAP_H
  7 +
  8 +ifeq ($(ARCH),i386)
  9 +CFLAGS+=-fomit-frame-pointer
11 10 OP_CFLAGS=$(CFLAGS) -malign-functions=0 -mpreferred-stack-boundary=2
12 11 endif
13 12  
14 13 ifeq ($(ARCH),ppc)
15   -GCC_LIBS_DIR=/usr/netgem/tools/lib/gcc-lib/powerpc-linux/2.95.2
16   -DIST=/home/fbe/nsv/dist/hw/n6-dtt
17   -CC=powerpc-linux-gcc -msoft-float
18   -CFLAGS=-Wall -pipe -O2 -mcpu=405 -mbig -nostdinc -g -I$(GCC_LIBS_DIR)/include -I$(DIST)/include
19   -LIBS_DIR=$(DIST)/lib
20   -CRT1=$(LIBS_DIR)/crt1.o
21   -CRTI=$(LIBS_DIR)/crti.o
22   -CRTN=$(LIBS_DIR)/crtn.o
23   -CRTBEGIN=$(GCC_LIBS_DIR)/crtbegin.o
24   -CRTEND=$(GCC_LIBS_DIR)/crtend.o
25   -LDFLAGS=-static -g -nostdlib $(CRT1) $(CRTI) $(CRTBEGIN)
26   -LIBS=-L$(LIBS_DIR) -ltinyc -lgcc $(CRTEND) $(CRTN)
27   -DEFINES=-Dsocklen_t=int
28 14 OP_CFLAGS=$(CFLAGS)
29 15 endif
30 16  
31 17 #########################################################
32 18  
33 19 DEFINES+=-D_GNU_SOURCE
34   -DEFINES+=-DCONFIG_PREFIX=\"/usr/local\"
35 20 LDSCRIPT=$(ARCH).ld
36 21 LIBS+=-ldl -lm
37   -VERSION=0.1
  22 +
  23 +# profiling code
  24 +ifdef TARGET_GPROF
  25 +LDFLAGS+=-p
  26 +CFLAGS+=-p
  27 +endif
38 28  
39 29 OBJS= elfload.o main.o thunk.o syscall.o
40   -OBJS+=translate-i386.o op-i386.o
  30 +OBJS+=translate-i386.o op-i386.o exec-i386.o
41 31 # NOTE: the disassembler code is only needed for debugging
42 32 OBJS+=i386-dis.o dis-buf.o
43 33 SRCS = $(OBJS:.o=.c)
... ... @@ -66,8 +56,12 @@ op-i386.o: op-i386.c opreg_template.h ops_template.h
66 56 $(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<
67 57  
68 58 clean:
  59 + $(MAKE) -C tests clean
69 60 rm -f *.o *~ gemu dyngen TAGS
70 61  
  62 +distclean: clean
  63 + rm -f config.mak config.h
  64 +
71 65 # various test targets
72 66 test speed: gemu
73 67 make -C tests $@
... ... @@ -82,7 +76,7 @@ TODO elfload.c main.c signal.c thunk.h\
82 76 cpu-i386.h gemu.h op-i386.c syscall-i386.h translate-i386.c\
83 77 dis-asm.h gen-i386.h op-i386.h syscall.c\
84 78 dis-buf.c i386-dis.c opreg_template.h syscall_defs.h\
85   -i386.ld ppc.ld\
  79 +i386.ld ppc.ld exec-i386.h exec-i386.c configure VERSION \
86 80 tests/Makefile\
87 81 tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
88 82 tests/test-i386-muldiv.h\
... ...
1   -- tests
  1 +- optimize translated cache chaining (DLL PLT like system)
  2 +- optimize inverse flags propagation (easy by generating intermediate
  3 + micro operation array).
2 4 - signals
3 5 - threads
4   -- fix printf for doubles (fp87.c bug ?)
5 6 - make it self runnable (use same trick as ld.so : include its own relocator and libc)
6 7 - fix FPU exceptions (in particular: gen_op_fpush not before mem load)
  8 +- tests
... ...
configure 0 → 100755
  1 +#!/bin/sh
  2 +#
  3 +# gemu configure script (c) 2003 Fabrice Bellard
  4 +#
  5 +# set temporary file name
  6 +if test ! -z "$TMPDIR" ; then
  7 + TMPDIR1="${TMPDIR}"
  8 +elif test ! -z "$TEMPDIR" ; then
  9 + TMPDIR1="${TEMPDIR}"
  10 +else
  11 + TMPDIR1="/tmp"
  12 +fi
  13 +
  14 +TMPC="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.c"
  15 +TMPO="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.o"
  16 +TMPS="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.S"
  17 +TMPH="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.h"
  18 +
  19 +# default parameters
  20 +prefix="/usr/local"
  21 +cross_prefix=""
  22 +cc="gcc"
  23 +host_cc="gcc"
  24 +ar="ar"
  25 +make="make"
  26 +strip="strip"
  27 +cpu=`uname -m`
  28 +case "$cpu" in
  29 + i386|i486|i586|i686|i86pc|BePC)
  30 + cpu="x86"
  31 + ;;
  32 + armv4l)
  33 + cpu="armv4l"
  34 + ;;
  35 + alpha)
  36 + cpu="alpha"
  37 + ;;
  38 + "Power Macintosh"|ppc)
  39 + cpu="powerpc"
  40 + ;;
  41 + mips)
  42 + cpu="mips"
  43 + ;;
  44 + *)
  45 + cpu="unknown"
  46 + ;;
  47 +esac
  48 +gprof="no"
  49 +bigendian="no"
  50 +
  51 +# OS specific
  52 +targetos=`uname -s`
  53 +case $targetos in
  54 +BeOS)
  55 +prefix="/boot/home/config"
  56 +# helps building libavcodec
  57 +CFLAGS="-O2 -DPIC"
  58 +# no need for libm, but the inet stuff
  59 +# Check for BONE
  60 +if (echo $BEINCLUDES|grep 'headers/be/bone' >/dev/null); then
  61 +extralibs="-lbind -lsocket"
  62 +else
  63 +echo "Not sure building for net_server will succeed... good luck."
  64 +extralibs="-lsocket"
  65 +fi ;;
  66 +BSD/OS)
  67 +extralibs="-lpoll -lgnugetopt -lm"
  68 +make="gmake"
  69 +;;
  70 +*) ;;
  71 +esac
  72 +
  73 +# find source path
  74 +# XXX: we assume an absolute path is given when launching configure,
  75 +# except in './configure' case.
  76 +source_path=${0%configure}
  77 +source_path=${source_path%/}
  78 +source_path_used="yes"
  79 +if test -z "$source_path" -o "$source_path" = "." ; then
  80 + source_path=`pwd`
  81 + source_path_used="no"
  82 +fi
  83 +
  84 +for opt do
  85 + case "$opt" in
  86 + --prefix=*) prefix=`echo $opt | cut -d '=' -f 2`
  87 + ;;
  88 + --source-path=*) source_path=`echo $opt | cut -d '=' -f 2`
  89 + ;;
  90 + --cross-prefix=*) cross_prefix=`echo $opt | cut -d '=' -f 2`
  91 + ;;
  92 + --cc=*) cc=`echo $opt | cut -d '=' -f 2`
  93 + ;;
  94 + --make=*) make=`echo $opt | cut -d '=' -f 2`
  95 + ;;
  96 + --extra-cflags=*) CFLAGS="${opt#--extra-cflags=}"
  97 + ;;
  98 + --extra-ldflags=*) LDFLAGS="${opt#--extra-ldflags=}"
  99 + ;;
  100 + --extra-libs=*) extralibs=${opt#--extra-libs=}
  101 + ;;
  102 + --cpu=*) cpu=`echo $opt | cut -d '=' -f 2`
  103 + ;;
  104 + --enable-gprof) gprof="yes"
  105 + ;;
  106 + esac
  107 +done
  108 +
  109 +# Checking for CFLAGS
  110 +if test -z "$CFLAGS"; then
  111 + CFLAGS="-O2"
  112 +fi
  113 +
  114 +cc="${cross_prefix}${cc}"
  115 +ar="${cross_prefix}${ar}"
  116 +strip="${cross_prefix}${strip}"
  117 +
  118 +if test -z "$cross_prefix" ; then
  119 +
  120 +# ---
  121 +# big/little endian test
  122 +cat > $TMPC << EOF
  123 +#include <inttypes.h>
  124 +int main(int argc, char ** argv){
  125 + volatile uint32_t i=0x01234567;
  126 + return (*((uint8_t*)(&i))) == 0x67;
  127 +}
  128 +EOF
  129 +
  130 +if $cc -o $TMPE $TMPC 2>/dev/null ; then
  131 +$TMPE && bigendian="yes"
  132 +else
  133 +echo big/little test failed
  134 +fi
  135 +
  136 +else
  137 +
  138 +# if cross compiling, cannot launch a program, so make a static guess
  139 +if test "$cpu" = "powerpc" -o "$cpu" = "mips" ; then
  140 + bigendian="yes"
  141 +fi
  142 +
  143 +fi
  144 +
  145 +if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
  146 +cat << EOF
  147 +
  148 +Usage: configure [options]
  149 +Options: [defaults in brackets after descriptions]
  150 +
  151 +EOF
  152 +echo "Standard options:"
  153 +echo " --help print this message"
  154 +echo " --prefix=PREFIX install in PREFIX [$prefix]"
  155 +echo " for audio/video/image support"
  156 +echo ""
  157 +echo "Advanced options (experts only):"
  158 +echo " --source-path=PATH path of source code [$source_path]"
  159 +echo " --cross-prefix=PREFIX use PREFIX for compile tools [$cross_prefix]"
  160 +echo " --cc=CC use C compiler CC [$cc]"
  161 +echo " --make=MAKE use specified make [$make]"
  162 +echo ""
  163 +echo "NOTE: The object files are build at the place where configure is launched"
  164 +exit 1
  165 +fi
  166 +
  167 +echo "Install prefix $prefix"
  168 +echo "Source path $source_path"
  169 +echo "C compiler $cc"
  170 +echo "make $make"
  171 +echo "CPU $cpu"
  172 +echo "Big Endian $bigendian"
  173 +echo "gprof enabled $gprof"
  174 +
  175 +echo "Creating config.mak and config.h"
  176 +
  177 +echo "# Automatically generated by configure - do not modify" > config.mak
  178 +echo "/* Automatically generated by configure - do not modify */" > $TMPH
  179 +
  180 +echo "prefix=$prefix" >> config.mak
  181 +echo "#define CONFIG_GEMU_PREFIX \"$prefix\"" >> $TMPH
  182 +echo "MAKE=$make" >> config.mak
  183 +echo "CC=$cc" >> config.mak
  184 +echo "HOST_CC=$host_cc" >> config.mak
  185 +echo "AR=$ar" >> config.mak
  186 +echo "STRIP=$strip -s -R .comment -R .note" >> config.mak
  187 +echo "CFLAGS=$CFLAGS" >> config.mak
  188 +echo "LDFLAGS=$LDFLAGS" >> config.mak
  189 +if test "$cpu" = "x86" ; then
  190 + echo "ARCH=i386" >> config.mak
  191 +elif test "$cpu" = "armv4l" ; then
  192 + echo "ARCH=arm" >> config.mak
  193 +elif test "$cpu" = "powerpc" ; then
  194 + echo "ARCH=ppc" > config.mak
  195 +elif test "$cpu" = "mips" ; then
  196 + echo "ARCH=mips" > config.mak
  197 +else
  198 + echo "Unsupported CPU"
  199 + exit 1
  200 +fi
  201 +if test "$bigendian" = "yes" ; then
  202 + echo "WORDS_BIGENDIAN=yes" >> config.mak
  203 + echo "#define WORDS_BIGENDIAN 1" >> $TMPH
  204 +fi
  205 +if test "$gprof" = "yes" ; then
  206 + echo "TARGET_GPROF=yes" >> config.mak
  207 + echo "#define HAVE_GPROF 1" >> $TMPH
  208 +fi
  209 +echo -n "VERSION=" >>config.mak
  210 +head $source_path/VERSION >>config.mak
  211 +echo "" >>config.mak
  212 +echo -n "#define GEMU_VERSION \"" >> $TMPH
  213 +head $source_path/VERSION >> $TMPH
  214 +echo "\"" >> $TMPH
  215 +if test "$network" = "yes" ; then
  216 + echo "#define CONFIG_NETWORK 1" >> $TMPH
  217 + echo "CONFIG_NETWORK=yes" >> config.mak
  218 +fi
  219 +
  220 +# build tree in object directory if source path is different from current one
  221 +if test "$source_path_used" = "yes" ; then
  222 + DIRS="tests"
  223 + FILES="Makefile tests/Makefile"
  224 + for dir in $DIRS ; do
  225 + mkdir -p $dir
  226 + done
  227 + for f in $FILES ; do
  228 + ln -sf $source_path/$f $f
  229 + done
  230 +fi
  231 +echo "SRC_PATH=$source_path" >> config.mak
  232 +
  233 +diff $TMPH config.h >/dev/null 2>&1
  234 +if test $? -ne 0 ; then
  235 + mv -f $TMPH config.h
  236 +else
  237 + echo "config.h is unchanged"
  238 +fi
  239 +
  240 +rm -f $TMPH
... ...
cpu-i386.h
... ... @@ -244,5 +244,6 @@ void cpu_x86_close(CPUX86State *s);
244 244 /* internal functions */
245 245 int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
246 246 int *gen_code_size_ptr, uint8_t *pc_start);
  247 +void cpu_x86_tblocks_init(void);
247 248  
248 249 #endif /* CPU_I386_H */
... ...
dyngen.c
  1 +/*
  2 + * Generic Dynamic compiler generator
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU General Public License
  17 + * along with this program; if not, write to the Free Software
  18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 + */
1 20 #include <stdlib.h>
2 21 #include <stdio.h>
3 22 #include <stdarg.h>
... ...
exec-i386.c 0 → 100644
  1 +/*
  2 + * i386 emulator main execution loop
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU General Public License
  17 + * along with this program; if not, write to the Free Software
  18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 + */
  20 +#include "exec-i386.h"
  21 +
  22 +#define DEBUG_EXEC
  23 +#define DEBUG_FLUSH
  24 +
  25 +/* main execution loop */
  26 +
  27 +/* maximum total translate dcode allocated */
  28 +#define CODE_GEN_BUFFER_SIZE (2048 * 1024)
  29 +//#define CODE_GEN_BUFFER_SIZE (128 * 1024)
  30 +#define CODE_GEN_MAX_SIZE 65536
  31 +#define CODE_GEN_ALIGN 16 /* must be >= of the size of a icache line */
  32 +
  33 +/* threshold to flush the translated code buffer */
  34 +#define CODE_GEN_BUFFER_MAX_SIZE (CODE_GEN_BUFFER_SIZE - CODE_GEN_MAX_SIZE)
  35 +
  36 +#define CODE_GEN_MAX_BLOCKS (CODE_GEN_BUFFER_SIZE / 64)
  37 +#define CODE_GEN_HASH_BITS 15
  38 +#define CODE_GEN_HASH_SIZE (1 << CODE_GEN_HASH_BITS)
  39 +typedef struct TranslationBlock {
  40 + unsigned long pc; /* simulated PC corresponding to this block */
  41 + uint8_t *tc_ptr; /* pointer to the translated code */
  42 + struct TranslationBlock *hash_next; /* next matching block */
  43 +} TranslationBlock;
  44 +
  45 +TranslationBlock tbs[CODE_GEN_MAX_BLOCKS];
  46 +TranslationBlock *tb_hash[CODE_GEN_HASH_SIZE];
  47 +int nb_tbs;
  48 +
  49 +uint8_t code_gen_buffer[CODE_GEN_BUFFER_SIZE];
  50 +uint8_t *code_gen_ptr;
  51 +
  52 +#ifdef DEBUG_EXEC
  53 +static const char *cc_op_str[] = {
  54 + "DYNAMIC",
  55 + "EFLAGS",
  56 + "MUL",
  57 + "ADDB",
  58 + "ADDW",
  59 + "ADDL",
  60 + "ADCB",
  61 + "ADCW",
  62 + "ADCL",
  63 + "SUBB",
  64 + "SUBW",
  65 + "SUBL",
  66 + "SBBB",
  67 + "SBBW",
  68 + "SBBL",
  69 + "LOGICB",
  70 + "LOGICW",
  71 + "LOGICL",
  72 + "INCB",
  73 + "INCW",
  74 + "INCL",
  75 + "DECB",
  76 + "DECW",
  77 + "DECL",
  78 + "SHLB",
  79 + "SHLW",
  80 + "SHLL",
  81 + "SARB",
  82 + "SARW",
  83 + "SARL",
  84 +};
  85 +
  86 +static void cpu_x86_dump_state(void)
  87 +{
  88 + int eflags;
  89 + eflags = cc_table[CC_OP].compute_all();
  90 + eflags |= (DF & DIRECTION_FLAG);
  91 + fprintf(logfile,
  92 + "EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
  93 + "ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n"
  94 + "CCS=%08x CCD=%08x CCO=%-8s EFL=%c%c%c%c%c%c%c\n",
  95 + env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX],
  96 + env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP],
  97 + env->cc_src, env->cc_dst, cc_op_str[env->cc_op],
  98 + eflags & DIRECTION_FLAG ? 'D' : '-',
  99 + eflags & CC_O ? 'O' : '-',
  100 + eflags & CC_S ? 'S' : '-',
  101 + eflags & CC_Z ? 'Z' : '-',
  102 + eflags & CC_A ? 'A' : '-',
  103 + eflags & CC_P ? 'P' : '-',
  104 + eflags & CC_C ? 'C' : '-'
  105 + );
  106 +#if 1
  107 + fprintf(logfile, "ST0=%f ST1=%f ST2=%f ST3=%f\n",
  108 + (double)ST0, (double)ST1, (double)ST(2), (double)ST(3));
  109 +#endif
  110 +}
  111 +
  112 +#endif
  113 +
  114 +void cpu_x86_tblocks_init(void)
  115 +{
  116 + if (!code_gen_ptr) {
  117 + code_gen_ptr = code_gen_buffer;
  118 + }
  119 +}
  120 +
  121 +/* flush all the translation blocks */
  122 +static void tb_flush(void)
  123 +{
  124 + int i;
  125 +#ifdef DEBUG_FLUSH
  126 + printf("gemu: flush code_size=%d nb_tbs=%d avg_tb_size=%d\n",
  127 + code_gen_ptr - code_gen_buffer,
  128 + nb_tbs,
  129 + (code_gen_ptr - code_gen_buffer) / nb_tbs);
  130 +#endif
  131 + nb_tbs = 0;
  132 + for(i = 0;i < CODE_GEN_HASH_SIZE; i++)
  133 + tb_hash[i] = NULL;
  134 + code_gen_ptr = code_gen_buffer;
  135 + /* XXX: flush processor icache at this point */
  136 +}
  137 +
  138 +/* find a translation block in the translation cache. If not found,
  139 + allocate a new one */
  140 +static inline TranslationBlock *tb_find_and_alloc(unsigned long pc)
  141 +{
  142 + TranslationBlock **ptb, *tb;
  143 + unsigned int h;
  144 +
  145 + h = pc & (CODE_GEN_HASH_SIZE - 1);
  146 + ptb = &tb_hash[h];
  147 + for(;;) {
  148 + tb = *ptb;
  149 + if (!tb)
  150 + break;
  151 + if (tb->pc == pc)
  152 + return tb;
  153 + ptb = &tb->hash_next;
  154 + }
  155 + if (nb_tbs >= CODE_GEN_MAX_BLOCKS ||
  156 + (code_gen_ptr - code_gen_buffer) >= CODE_GEN_BUFFER_MAX_SIZE)
  157 + tb_flush();
  158 + tb = &tbs[nb_tbs++];
  159 + *ptb = tb;
  160 + tb->pc = pc;
  161 + tb->tc_ptr = NULL;
  162 + tb->hash_next = NULL;
  163 + return tb;
  164 +}
  165 +
  166 +int cpu_x86_exec(CPUX86State *env1)
  167 +{
  168 + int saved_T0, saved_T1, saved_A0;
  169 + CPUX86State *saved_env;
  170 + int code_gen_size, ret;
  171 + void (*gen_func)(void);
  172 + TranslationBlock *tb;
  173 + uint8_t *tc_ptr;
  174 +
  175 + /* first we save global registers */
  176 + saved_T0 = T0;
  177 + saved_T1 = T1;
  178 + saved_A0 = A0;
  179 + saved_env = env;
  180 + env = env1;
  181 +
  182 + /* prepare setjmp context for exception handling */
  183 + if (setjmp(env->jmp_env) == 0) {
  184 + for(;;) {
  185 +#ifdef DEBUG_EXEC
  186 + if (loglevel) {
  187 + cpu_x86_dump_state();
  188 + }
  189 +#endif
  190 + tb = tb_find_and_alloc((unsigned long)env->pc);
  191 + tc_ptr = tb->tc_ptr;
  192 + if (!tb->tc_ptr) {
  193 + /* if no translated code available, then translate it now */
  194 + tc_ptr = code_gen_ptr;
  195 + cpu_x86_gen_code(code_gen_ptr, CODE_GEN_MAX_SIZE,
  196 + &code_gen_size, (uint8_t *)env->pc);
  197 + tb->tc_ptr = tc_ptr;
  198 + code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1));
  199 + }
  200 + /* execute the generated code */
  201 + gen_func = (void *)tc_ptr;
  202 + gen_func();
  203 + }
  204 + }
  205 + ret = env->exception_index;
  206 +
  207 + /* restore global registers */
  208 + T0 = saved_T0;
  209 + T1 = saved_T1;
  210 + A0 = saved_A0;
  211 + env = saved_env;
  212 + return ret;
  213 +}
... ...
exec-i386.h 0 → 100644
  1 +/* i386 execution defines */
  2 +
  3 +typedef unsigned char uint8_t;
  4 +typedef unsigned short uint16_t;
  5 +typedef unsigned int uint32_t;
  6 +typedef unsigned long long uint64_t;
  7 +
  8 +typedef signed char int8_t;
  9 +typedef signed short int16_t;
  10 +typedef signed int int32_t;
  11 +typedef signed long long int64_t;
  12 +
  13 +#define bswap32(x) \
  14 +({ \
  15 + uint32_t __x = (x); \
  16 + ((uint32_t)( \
  17 + (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
  18 + (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
  19 + (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
  20 + (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
  21 +})
  22 +
  23 +#define NULL 0
  24 +#include <fenv.h>
  25 +
  26 +typedef struct FILE FILE;
  27 +extern FILE *logfile;
  28 +extern int loglevel;
  29 +extern int fprintf(FILE *, const char *, ...);
  30 +
  31 +#ifdef __i386__
  32 +register unsigned int T0 asm("ebx");
  33 +register unsigned int T1 asm("esi");
  34 +register unsigned int A0 asm("edi");
  35 +register struct CPUX86State *env asm("ebp");
  36 +#endif
  37 +#ifdef __powerpc__
  38 +register unsigned int T0 asm("r24");
  39 +register unsigned int T1 asm("r25");
  40 +register unsigned int A0 asm("r26");
  41 +register struct CPUX86State *env asm("r27");
  42 +#endif
  43 +#ifdef __arm__
  44 +register unsigned int T0 asm("r4");
  45 +register unsigned int T1 asm("r5");
  46 +register unsigned int A0 asm("r6");
  47 +register struct CPUX86State *env asm("r7");
  48 +#endif
  49 +#ifdef __mips__
  50 +register unsigned int T0 asm("s0");
  51 +register unsigned int T1 asm("s1");
  52 +register unsigned int A0 asm("s2");
  53 +register struct CPUX86State *env asm("s3");
  54 +#endif
  55 +#ifdef __sparc__
  56 +register unsigned int T0 asm("l0");
  57 +register unsigned int T1 asm("l1");
  58 +register unsigned int A0 asm("l2");
  59 +register struct CPUX86State *env asm("l3");
  60 +#endif
  61 +
  62 +/* force GCC to generate only one epilog at the end of the function */
  63 +#define FORCE_RET() asm volatile ("");
  64 +
  65 +#ifndef OPPROTO
  66 +#define OPPROTO
  67 +#endif
  68 +
  69 +#define xglue(x, y) x ## y
  70 +#define glue(x, y) xglue(x, y)
  71 +
  72 +#define EAX (env->regs[R_EAX])
  73 +#define ECX (env->regs[R_ECX])
  74 +#define EDX (env->regs[R_EDX])
  75 +#define EBX (env->regs[R_EBX])
  76 +#define ESP (env->regs[R_ESP])
  77 +#define EBP (env->regs[R_EBP])
  78 +#define ESI (env->regs[R_ESI])
  79 +#define EDI (env->regs[R_EDI])
  80 +#define PC (env->pc)
  81 +#define DF (env->df)
  82 +
  83 +#define CC_SRC (env->cc_src)
  84 +#define CC_DST (env->cc_dst)
  85 +#define CC_OP (env->cc_op)
  86 +
  87 +/* float macros */
  88 +#define FT0 (env->ft0)
  89 +#define ST0 (env->fpregs[env->fpstt])
  90 +#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])
  91 +#define ST1 ST(1)
  92 +
  93 +extern int __op_param1, __op_param2, __op_param3;
  94 +#define PARAM1 ((long)(&__op_param1))
  95 +#define PARAM2 ((long)(&__op_param2))
  96 +#define PARAM3 ((long)(&__op_param3))
  97 +
  98 +#include "cpu-i386.h"
  99 +
  100 +typedef struct CCTable {
  101 + int (*compute_all)(void); /* return all the flags */
  102 + int (*compute_c)(void); /* return the C flag */
  103 +} CCTable;
  104 +
  105 +extern CCTable cc_table[];
... ...
linux-user/main.c
... ... @@ -87,7 +87,7 @@ int cpu_x86_inl(int addr)
87 87  
88 88 void usage(void)
89 89 {
90   - printf("gemu version 0.1, Copyright (c) 2003 Fabrice Bellard\n"
  90 + printf("gemu version" GEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
91 91 "usage: gemu [-d] program [arguments...]\n"
92 92 "Linux x86 emulator\n"
93 93 );
... ...
linux-user/syscall.c
... ... @@ -628,6 +628,9 @@ long do_syscall(int num, long arg1, long arg2, long arg3,
628 628 #endif
629 629 switch(num) {
630 630 case TARGET_NR_exit:
  631 +#ifdef HAVE_GPROF
  632 + _mcleanup();
  633 +#endif
631 634 _exit(arg1);
632 635 ret = 0; /* avoid warning */
633 636 break;
... ...
op-i386.c
1   -#define DEBUG_EXEC
2   -
3   -typedef unsigned char uint8_t;
4   -typedef unsigned short uint16_t;
5   -typedef unsigned int uint32_t;
6   -typedef unsigned long long uint64_t;
7   -
8   -typedef signed char int8_t;
9   -typedef signed short int16_t;
10   -typedef signed int int32_t;
11   -typedef signed long long int64_t;
12   -
13   -#define bswap32(x) \
14   -({ \
15   - uint32_t __x = (x); \
16   - ((uint32_t)( \
17   - (((uint32_t)(__x) & (uint32_t)0x000000ffUL) << 24) | \
18   - (((uint32_t)(__x) & (uint32_t)0x0000ff00UL) << 8) | \
19   - (((uint32_t)(__x) & (uint32_t)0x00ff0000UL) >> 8) | \
20   - (((uint32_t)(__x) & (uint32_t)0xff000000UL) >> 24) )); \
21   -})
22   -
23   -#define NULL 0
24   -#include <fenv.h>
25   -
26   -typedef struct FILE FILE;
27   -extern FILE *logfile;
28   -extern int loglevel;
29   -extern int fprintf(FILE *, const char *, ...);
30   -
31   -#ifdef __i386__
32   -register unsigned int T0 asm("ebx");
33   -register unsigned int T1 asm("esi");
34   -register unsigned int A0 asm("edi");
35   -register struct CPUX86State *env asm("ebp");
36   -#endif
37   -#ifdef __powerpc__
38   -register unsigned int T0 asm("r24");
39   -register unsigned int T1 asm("r25");
40   -register unsigned int A0 asm("r26");
41   -register struct CPUX86State *env asm("r27");
42   -#endif
43   -#ifdef __arm__
44   -register unsigned int T0 asm("r4");
45   -register unsigned int T1 asm("r5");
46   -register unsigned int A0 asm("r6");
47   -register struct CPUX86State *env asm("r7");
48   -#endif
49   -#ifdef __mips__
50   -register unsigned int T0 asm("s0");
51   -register unsigned int T1 asm("s1");
52   -register unsigned int A0 asm("s2");
53   -register struct CPUX86State *env asm("s3");
54   -#endif
55   -#ifdef __sparc__
56   -register unsigned int T0 asm("l0");
57   -register unsigned int T1 asm("l1");
58   -register unsigned int A0 asm("l2");
59   -register struct CPUX86State *env asm("l3");
60   -#endif
61   -
62   -/* force GCC to generate only one epilog at the end of the function */
63   -#define FORCE_RET() asm volatile ("");
64   -
65   -#ifndef OPPROTO
66   -#define OPPROTO
67   -#endif
68   -
69   -#define xglue(x, y) x ## y
70   -#define glue(x, y) xglue(x, y)
71   -
72   -#define EAX (env->regs[R_EAX])
73   -#define ECX (env->regs[R_ECX])
74   -#define EDX (env->regs[R_EDX])
75   -#define EBX (env->regs[R_EBX])
76   -#define ESP (env->regs[R_ESP])
77   -#define EBP (env->regs[R_EBP])
78   -#define ESI (env->regs[R_ESI])
79   -#define EDI (env->regs[R_EDI])
80   -#define PC (env->pc)
81   -#define DF (env->df)
82   -
83   -#define CC_SRC (env->cc_src)
84   -#define CC_DST (env->cc_dst)
85   -#define CC_OP (env->cc_op)
86   -
87   -/* float macros */
88   -#define FT0 (env->ft0)
89   -#define ST0 (env->fpregs[env->fpstt])
90   -#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7])
91   -#define ST1 ST(1)
92   -
93   -extern int __op_param1, __op_param2, __op_param3;
94   -#define PARAM1 ((long)(&__op_param1))
95   -#define PARAM2 ((long)(&__op_param2))
96   -#define PARAM3 ((long)(&__op_param3))
97   -
98   -#include "cpu-i386.h"
99   -
100   -typedef struct CCTable {
101   - int (*compute_all)(void); /* return all the flags */
102   - int (*compute_c)(void); /* return the C flag */
103   -} CCTable;
  1 +/*
  2 + * i386 micro operations
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU General Public License
  17 + * along with this program; if not, write to the Free Software
  18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 + */
  20 +#include "exec-i386.h"
104 21  
105 22 /* NOTE: data are not static to force relocation generation by GCC */
106   -extern CCTable cc_table[];
107 23  
108 24 uint8_t parity_table[256] = {
109 25 CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
... ... @@ -1878,100 +1794,3 @@ void OPPROTO op_fldcw_A0(void)
1878 1794 fesetround(rnd_type);
1879 1795 }
1880 1796  
1881   -/* main execution loop */
1882   -uint8_t code_gen_buffer[65536];
1883   -
1884   -#ifdef DEBUG_EXEC
1885   -static const char *cc_op_str[] = {
1886   - "DYNAMIC",
1887   - "EFLAGS",
1888   - "MUL",
1889   - "ADDB",
1890   - "ADDW",
1891   - "ADDL",
1892   - "ADCB",
1893   - "ADCW",
1894   - "ADCL",
1895   - "SUBB",
1896   - "SUBW",
1897   - "SUBL",
1898   - "SBBB",
1899   - "SBBW",
1900   - "SBBL",
1901   - "LOGICB",
1902   - "LOGICW",
1903   - "LOGICL",
1904   - "INCB",
1905   - "INCW",
1906   - "INCL",
1907   - "DECB",
1908   - "DECW",
1909   - "DECL",
1910   - "SHLB",
1911   - "SHLW",
1912   - "SHLL",
1913   - "SARB",
1914   - "SARW",
1915   - "SARL",
1916   -};
1917   -#endif
1918   -
1919   -int cpu_x86_exec(CPUX86State *env1)
1920   -{
1921   - int saved_T0, saved_T1, saved_A0;
1922   - CPUX86State *saved_env;
1923   - int code_gen_size, ret;
1924   - void (*gen_func)(void);
1925   -
1926   - /* first we save global registers */
1927   - saved_T0 = T0;
1928   - saved_T1 = T1;
1929   - saved_A0 = A0;
1930   - saved_env = env;
1931   - env = env1;
1932   -
1933   - /* prepare setjmp context for exception handling */
1934   - if (setjmp(env->jmp_env) == 0) {
1935   - for(;;) {
1936   -#ifdef DEBUG_EXEC
1937   - if (loglevel) {
1938   - int eflags;
1939   - eflags = cc_table[CC_OP].compute_all();
1940   - eflags |= (DF & DIRECTION_FLAG);
1941   - fprintf(logfile,
1942   - "EAX=%08x EBX=%08X ECX=%08x EDX=%08x\n"
1943   - "ESI=%08x EDI=%08X EBP=%08x ESP=%08x\n"
1944   - "CCS=%08x CCD=%08x CCO=%-8s EFL=%c%c%c%c%c%c%c\n",
1945   - env->regs[R_EAX], env->regs[R_EBX], env->regs[R_ECX], env->regs[R_EDX],
1946   - env->regs[R_ESI], env->regs[R_EDI], env->regs[R_EBP], env->regs[R_ESP],
1947   - env->cc_src, env->cc_dst, cc_op_str[env->cc_op],
1948   - eflags & DIRECTION_FLAG ? 'D' : '-',
1949   - eflags & CC_O ? 'O' : '-',
1950   - eflags & CC_S ? 'S' : '-',
1951   - eflags & CC_Z ? 'Z' : '-',
1952   - eflags & CC_A ? 'A' : '-',
1953   - eflags & CC_P ? 'P' : '-',
1954   - eflags & CC_C ? 'C' : '-'
1955   - );
1956   -#if 1
1957   - fprintf(logfile, "ST0=%f ST1=%f ST2=%f ST3=%f\n",
1958   - (double)ST0, (double)ST1, (double)ST(2), (double)ST(3));
1959   -#endif
1960   - }
1961   -#endif
1962   - cpu_x86_gen_code(code_gen_buffer, sizeof(code_gen_buffer),
1963   - &code_gen_size, (uint8_t *)env->pc);
1964   - /* execute the generated code */
1965   - gen_func = (void *)code_gen_buffer;
1966   - gen_func();
1967   - }
1968   - }
1969   - ret = env->exception_index;
1970   -
1971   - /* restore global registers */
1972   - T0 = saved_T0;
1973   - T1 = saved_T1;
1974   - A0 = saved_A0;
1975   - env = saved_env;
1976   - return ret;
1977   -}
... ...
tests/Makefile
1   -CC=gcc
  1 +include ../config.mak
  2 +
2 3 CFLAGS=-Wall -O2 -g
3 4 LDFLAGS=
4 5  
  6 +ifeq ($(ARCH),i386)
5 7 TESTS=hello test2 sha1 test-i386
6   -TESTS+=op-i386.o #op-i386.o op-ppc.o op-arm.o op-mips.o op-sparc.o
  8 +endif
7 9  
8 10 GEMU=../gemu
9 11  
... ... @@ -24,22 +26,6 @@ test: test-i386
24 26 $(GEMU) test-i386 > test-i386.out
25 27 @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
26 28  
27   -# dyngen tests
28   -op-i386.o: op.c
29   - gcc $(CFLAGS) -c -o $@ $<
30   -
31   -op-ppc.o: op.c
32   - powerpc-linux-gcc $(CFLAGS) -c -o $@ $<
33   -
34   -op-arm.o: op.c
35   - arm-linux-gcc $(CFLAGS) -c -o $@ $<
36   -
37   -op-mips.o: op.c
38   - mips-linux-gcc $(CFLAGS) -mno-abicalls -c -o $@ $<
39   -
40   -op-sparc.o: op.c
41   - sparc-linux-gcc $(CFLAGS) -mflat -c -o $@ $<
42   -
43 29 # speed test
44 30 sha1: sha1.c
45 31 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
... ... @@ -48,6 +34,5 @@ speed: sha1
48 34 time ./sha1
49 35 time $(GEMU) sha1
50 36  
51   -# interpreter test
52   -interp: interp.c interploop.c
53   - $(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -o $@ $^
  37 +clean:
  38 + rm -f *~ *.o $(TESTS)
... ...
... ... @@ -2,7 +2,7 @@
2 2 #define THUNK_H
3 3  
4 4 #include <inttypes.h>
5   -#include <endian.h>
  5 +#include "config.h"
6 6  
7 7 #ifdef HAVE_BYTESWAP_H
8 8 #include <byteswap.h>
... ... @@ -42,11 +42,6 @@
42 42  
43 43 #endif
44 44  
45   -#undef WORDS_BIGENDIAN
46   -#if __BYTE_ORDER == __BIG_ENDIAN
47   -#define WORDS_BIGENDIAN
48   -#endif
49   -
50 45 #ifdef WORDS_BIGENDIAN
51 46 #define BSWAP_NEEDED
52 47 #endif
... ...
translate-i386.c
  1 +/*
  2 + * i386 translation
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + *
  11 + * This program is distributed in the hope that it will be useful,
  12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14 + * GNU General Public License for more details.
  15 + *
  16 + * You should have received a copy of the GNU General Public License
  17 + * along with this program; if not, write to the Free Software
  18 + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 + */
1 20 #include <stdarg.h>
2 21 #include <stdlib.h>
3 22 #include <stdio.h>
... ... @@ -2591,6 +2610,8 @@ CPUX86State *cpu_x86_init(void)
2591 2610 CPUX86State *env;
2592 2611 int i;
2593 2612  
  2613 + cpu_x86_tblocks_init();
  2614 +
2594 2615 env = malloc(sizeof(CPUX86State));
2595 2616 if (!env)
2596 2617 return NULL;
... ...