Revision 7d13299d
b/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 | 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 | 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\ |
b/TODO | ||
---|---|---|
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 |
b/configure | ||
---|---|---|
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 |
b/cpu-i386.h | ||
---|---|---|
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 */ |
b/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> |
b/exec-i386.c | ||
---|---|---|
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 |
} |
b/exec-i386.h | ||
---|---|---|
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[]; |
b/linux-user/main.c | ||
---|---|---|
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 |
); |
b/linux-user/syscall.c | ||
---|---|---|
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; |
b/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 | 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 |
} |
b/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 | 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 | 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) |
b/thunk.h | ||
---|---|---|
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 | 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 |
b/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 | 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; |
Also available in: Unified diff