Commit 04369ff2f525ea510b6ddeaa2e3ed6aedde8bbb4

Authored by bellard
1 parent 68decc7c

ppc port


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@36 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile
@@ -90,7 +90,7 @@ i386.ld ppc.ld exec-i386.h exec-i386.c configure VERSION \ @@ -90,7 +90,7 @@ i386.ld ppc.ld exec-i386.h exec-i386.c configure VERSION \
90 tests/Makefile\ 90 tests/Makefile\
91 tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\ 91 tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
92 tests/test-i386-muldiv.h\ 92 tests/test-i386-muldiv.h\
93 -tests/test2.c tests/hello.c tests/sha1.c 93 +tests/test2.c tests/hello.c tests/hello tests/sha1.c
94 94
95 FILE=gemu-$(VERSION) 95 FILE=gemu-$(VERSION)
96 96
configure
@@ -11,11 +11,11 @@ else @@ -11,11 +11,11 @@ else
11 TMPDIR1="/tmp" 11 TMPDIR1="/tmp"
12 fi 12 fi
13 13
14 -TMPC="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.c"  
15 -TMPO="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.o"  
16 -TMPE="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}"  
17 -TMPS="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.S"  
18 -TMPH="${TMPDIR1}/qemacs-conf-${RANDOM}-$$-${RANDOM}.h" 14 +TMPC="${TMPDIR1}/gemu-conf-${RANDOM}-$$-${RANDOM}.c"
  15 +TMPO="${TMPDIR1}/gemu-conf-${RANDOM}-$$-${RANDOM}.o"
  16 +TMPE="${TMPDIR1}/gemu-conf-${RANDOM}-$$-${RANDOM}"
  17 +TMPS="${TMPDIR1}/gemu-conf-${RANDOM}-$$-${RANDOM}.S"
  18 +TMPH="${TMPDIR1}/gemu-conf-${RANDOM}-$$-${RANDOM}.h"
19 19
20 # default parameters 20 # default parameters
21 prefix="/usr/local" 21 prefix="/usr/local"
@@ -144,12 +144,20 @@ fi @@ -144,12 +144,20 @@ fi
144 fi 144 fi
145 145
146 # check gcc version 146 # check gcc version
  147 +cat > $TMPC <<EOF
  148 +int main(void) {
  149 +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 2)
  150 +return 0;
  151 +#else
  152 +#error gcc < 3.2
  153 +#endif
  154 +}
  155 +EOF
  156 +
147 gcc_major="2" 157 gcc_major="2"
148 -gcc_version="$($cc -v 2>&1 | grep version | cut -d ' ' -f3-)"  
149 -case "$gcc_version" in  
150 -3.*) gcc_major="3";  
151 -;;  
152 -esac 158 +if $cc -o $TMPO $TMPC 2> /dev/null ; then
  159 + gcc_major="3"
  160 +fi
153 161
154 if test x"$1" = x"-h" -o x"$1" = x"--help" ; then 162 if test x"$1" = x"-h" -o x"$1" = x"--help" ; then
155 cat << EOF 163 cat << EOF
@@ -201,9 +209,9 @@ if test &quot;$cpu&quot; = &quot;x86&quot; ; then @@ -201,9 +209,9 @@ if test &quot;$cpu&quot; = &quot;x86&quot; ; then
201 elif test "$cpu" = "armv4l" ; then 209 elif test "$cpu" = "armv4l" ; then
202 echo "ARCH=arm" >> config.mak 210 echo "ARCH=arm" >> config.mak
203 elif test "$cpu" = "powerpc" ; then 211 elif test "$cpu" = "powerpc" ; then
204 - echo "ARCH=ppc" > config.mak 212 + echo "ARCH=ppc" >> config.mak
205 elif test "$cpu" = "mips" ; then 213 elif test "$cpu" = "mips" ; then
206 - echo "ARCH=mips" > config.mak 214 + echo "ARCH=mips" >> config.mak
207 else 215 else
208 echo "Unsupported CPU" 216 echo "Unsupported CPU"
209 exit 1 217 exit 1
cpu-i386.h
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 #ifndef CPU_I386_H 4 #ifndef CPU_I386_H
5 #define CPU_I386_H 5 #define CPU_I386_H
6 6
  7 +#include "config.h"
7 #include <setjmp.h> 8 #include <setjmp.h>
8 9
9 #define R_EAX 0 10 #define R_EAX 0
@@ -174,6 +175,7 @@ typedef struct CPUX86State { @@ -174,6 +175,7 @@ typedef struct CPUX86State {
174 int exception_index; 175 int exception_index;
175 } CPUX86State; 176 } CPUX86State;
176 177
  178 +/* all CPU memory access use these macros */
177 static inline int ldub(void *ptr) 179 static inline int ldub(void *ptr)
178 { 180 {
179 return *(uint8_t *)ptr; 181 return *(uint8_t *)ptr;
@@ -184,6 +186,134 @@ static inline int ldsb(void *ptr) @@ -184,6 +186,134 @@ static inline int ldsb(void *ptr)
184 return *(int8_t *)ptr; 186 return *(int8_t *)ptr;
185 } 187 }
186 188
  189 +static inline void stb(void *ptr, int v)
  190 +{
  191 + *(uint8_t *)ptr = v;
  192 +}
  193 +
  194 +#ifdef WORDS_BIGENDIAN
  195 +
  196 +/* conservative code for little endian unaligned accesses */
  197 +static inline int lduw(void *ptr)
  198 +{
  199 +#ifdef __powerpc__
  200 + int val;
  201 + __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
  202 + return val;
  203 +#else
  204 + uint8_t *p = ptr;
  205 + return p[0] | (p[1] << 8);
  206 +#endif
  207 +}
  208 +
  209 +static inline int ldsw(void *ptr)
  210 +{
  211 +#ifdef __powerpc__
  212 + int val;
  213 + __asm__ __volatile__ ("lhbrx %0,0,%1" : "=r" (val) : "r" (ptr));
  214 + return (int16_t)val;
  215 +#else
  216 + uint8_t *p = ptr;
  217 + return (int16_t)(p[0] | (p[1] << 8));
  218 +#endif
  219 +}
  220 +
  221 +static inline int ldl(void *ptr)
  222 +{
  223 +#ifdef __powerpc__
  224 + int val;
  225 + __asm__ __volatile__ ("lwbrx %0,0,%1" : "=r" (val) : "r" (ptr));
  226 + return val;
  227 +#else
  228 + uint8_t *p = ptr;
  229 + return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24);
  230 +#endif
  231 +}
  232 +
  233 +static inline uint64_t ldq(void *ptr)
  234 +{
  235 + uint8_t *p = ptr;
  236 + uint32_t v1, v2;
  237 + v1 = ldl(p);
  238 + v2 = ldl(p + 4);
  239 + return v1 | ((uint64_t)v2 << 32);
  240 +}
  241 +
  242 +static inline void stw(void *ptr, int v)
  243 +{
  244 +#ifdef __powerpc__
  245 + __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*(uint16_t *)ptr) : "r" (v), "r" (ptr));
  246 +#else
  247 + uint8_t *p = ptr;
  248 + p[0] = v;
  249 + p[1] = v >> 8;
  250 +#endif
  251 +}
  252 +
  253 +static inline void stl(void *ptr, int v)
  254 +{
  255 +#ifdef __powerpc__
  256 + __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*(uint32_t *)ptr) : "r" (v), "r" (ptr));
  257 +#else
  258 + uint8_t *p = ptr;
  259 + p[0] = v;
  260 + p[1] = v >> 8;
  261 + p[2] = v >> 16;
  262 + p[3] = v >> 24;
  263 +#endif
  264 +}
  265 +
  266 +static inline void stq(void *ptr, uint64_t v)
  267 +{
  268 + uint8_t *p = ptr;
  269 + stl(p, (uint32_t)v);
  270 + stl(p + 4, v >> 32);
  271 +}
  272 +
  273 +/* float access */
  274 +
  275 +static inline float ldfl(void *ptr)
  276 +{
  277 + union {
  278 + float f;
  279 + uint32_t i;
  280 + } u;
  281 + u.i = ldl(ptr);
  282 + return u.f;
  283 +}
  284 +
  285 +static inline double ldfq(void *ptr)
  286 +{
  287 + union {
  288 + double d;
  289 + uint64_t i;
  290 + } u;
  291 + u.i = ldq(ptr);
  292 + return u.d;
  293 +}
  294 +
  295 +static inline void stfl(void *ptr, float v)
  296 +{
  297 + union {
  298 + float f;
  299 + uint32_t i;
  300 + } u;
  301 + u.f = v;
  302 + stl(ptr, u.i);
  303 +}
  304 +
  305 +static inline void stfq(void *ptr, double v)
  306 +{
  307 + union {
  308 + double d;
  309 + uint64_t i;
  310 + } u;
  311 + u.d = v;
  312 + stq(ptr, u.i);
  313 +}
  314 +
  315 +#else
  316 +
187 static inline int lduw(void *ptr) 317 static inline int lduw(void *ptr)
188 { 318 {
189 return *(uint16_t *)ptr; 319 return *(uint16_t *)ptr;
@@ -204,11 +334,6 @@ static inline uint64_t ldq(void *ptr) @@ -204,11 +334,6 @@ static inline uint64_t ldq(void *ptr)
204 return *(uint64_t *)ptr; 334 return *(uint64_t *)ptr;
205 } 335 }
206 336
207 -static inline void stb(void *ptr, int v)  
208 -{  
209 - *(uint8_t *)ptr = v;  
210 -}  
211 -  
212 static inline void stw(void *ptr, int v) 337 static inline void stw(void *ptr, int v)
213 { 338 {
214 *(uint16_t *)ptr = v; 339 *(uint16_t *)ptr = v;
@@ -245,6 +370,7 @@ static inline void stfq(void *ptr, double v) @@ -245,6 +370,7 @@ static inline void stfq(void *ptr, double v)
245 { 370 {
246 *(double *)ptr = v; 371 *(double *)ptr = v;
247 } 372 }
  373 +#endif
248 374
249 #ifndef IN_OP_I386 375 #ifndef IN_OP_I386
250 void cpu_x86_outb(int addr, int val); 376 void cpu_x86_outb(int addr, int val);
dis-asm.h
@@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
10 #define DIS_ASM_H 10 #define DIS_ASM_H
11 11
12 #include <stdio.h> 12 #include <stdio.h>
  13 +#include <string.h>
13 #include "bfd.h" 14 #include "bfd.h"
14 15
15 typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...)); 16 typedef int (*fprintf_ftype) PARAMS((FILE*, const char*, ...));
dyngen.c
@@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
19 */ 19 */
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include <stdio.h> 21 #include <stdio.h>
  22 +#include <string.h>
22 #include <stdarg.h> 23 #include <stdarg.h>
23 #include <inttypes.h> 24 #include <inttypes.h>
24 #include <elf.h> 25 #include <elf.h>
@@ -228,14 +229,10 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -228,14 +229,10 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
228 { 229 {
229 uint8_t *p; 230 uint8_t *p;
230 p = (void *)(p_end - 4); 231 p = (void *)(p_end - 4);
231 - /* find ret */  
232 - while (p > p_start && get32((uint32_t *)p) != 0x4e800020)  
233 - p -= 4;  
234 - /* skip double ret */  
235 - if (p > p_start && get32((uint32_t *)(p - 4)) == 0x4e800020)  
236 - p -= 4;  
237 if (p == p_start) 232 if (p == p_start)
238 error("empty code for %s", name); 233 error("empty code for %s", name);
  234 + if (get32((uint32_t *)p) != 0x4e800020)
  235 + error("blr expected at the end of %s", name);
239 copy_size = p - p_start; 236 copy_size = p - p_start;
240 } 237 }
241 break; 238 break;
@@ -361,6 +358,51 @@ void gen_code(const char *name, unsigned long offset, unsigned long size, @@ -361,6 +358,51 @@ void gen_code(const char *name, unsigned long offset, unsigned long size,
361 } 358 }
362 } 359 }
363 break; 360 break;
  361 + case EM_PPC:
  362 + {
  363 + Elf32_Rela *rel;
  364 + char name[256];
  365 + int type;
  366 + long addend;
  367 + for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
  368 + if (rel->r_offset >= offset && rel->r_offset < offset + copy_size) {
  369 + sym_name = strtab + symtab[ELF32_R_SYM(rel->r_info)].st_name;
  370 + if (strstart(sym_name, "__op_param", &p)) {
  371 + snprintf(name, sizeof(name), "param%s", p);
  372 + } else {
  373 + snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
  374 + }
  375 + type = ELF32_R_TYPE(rel->r_info);
  376 + addend = rel->r_addend;
  377 + switch(type) {
  378 + case R_PPC_ADDR32:
  379 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = %s + %ld;\n",
  380 + rel->r_offset - offset, name, addend);
  381 + break;
  382 + case R_PPC_ADDR16_LO:
  383 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld);\n",
  384 + rel->r_offset - offset, name, addend);
  385 + break;
  386 + case R_PPC_ADDR16_HI:
  387 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld) >> 16;\n",
  388 + rel->r_offset - offset, name, addend);
  389 + break;
  390 + case R_PPC_ADDR16_HA:
  391 + fprintf(outfile, " *(uint16_t *)(gen_code_ptr + %ld) = (%s + %ld + 0x8000) >> 16;\n",
  392 + rel->r_offset - offset, name, addend);
  393 + break;
  394 + case R_PPC_REL24:
  395 + /* warning: must be at 32 MB distancy */
  396 + fprintf(outfile, " *(uint32_t *)(gen_code_ptr + %ld) = (*(uint32_t *)(gen_code_ptr + %ld) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %ld) + %ld) & 0x03fffffc);\n",
  397 + rel->r_offset - offset, rel->r_offset - offset, name, rel->r_offset - offset, addend);
  398 + break;
  399 + default:
  400 + error("unsupported powerpc relocation (%d)", type);
  401 + }
  402 + }
  403 + }
  404 + }
  405 + break;
364 default: 406 default:
365 error("unsupported CPU for relocations (%d)", e_machine); 407 error("unsupported CPU for relocations (%d)", e_machine);
366 } 408 }
@@ -569,6 +611,9 @@ fprintf(outfile, @@ -569,6 +611,9 @@ fprintf(outfile,
569 case EM_386: 611 case EM_386:
570 fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n"); 612 fprintf(outfile, "*gen_code_ptr++ = 0xc3; /* ret */\n");
571 break; 613 break;
  614 + case EM_PPC:
  615 + fprintf(outfile, "*((uint32_t *)gen_code_ptr)++ = 0x4e800020; /* blr */\n");
  616 + break;
572 default: 617 default:
573 error("no return generation for cpu '%s'", cpu_name); 618 error("no return generation for cpu '%s'", cpu_name);
574 } 619 }
exec-i386.c
@@ -171,6 +171,30 @@ int cpu_x86_exec(CPUX86State *env1) @@ -171,6 +171,30 @@ int cpu_x86_exec(CPUX86State *env1)
171 { 171 {
172 int saved_T0, saved_T1, saved_A0; 172 int saved_T0, saved_T1, saved_A0;
173 CPUX86State *saved_env; 173 CPUX86State *saved_env;
  174 +#ifdef reg_EAX
  175 + int saved_EAX;
  176 +#endif
  177 +#ifdef reg_ECX
  178 + int saved_ECX;
  179 +#endif
  180 +#ifdef reg_EDX
  181 + int saved_EDX;
  182 +#endif
  183 +#ifdef reg_EBX
  184 + int saved_EBX;
  185 +#endif
  186 +#ifdef reg_ESP
  187 + int saved_ESP;
  188 +#endif
  189 +#ifdef reg_EBP
  190 + int saved_EBP;
  191 +#endif
  192 +#ifdef reg_ESI
  193 + int saved_ESI;
  194 +#endif
  195 +#ifdef reg_EDI
  196 + int saved_EDI;
  197 +#endif
174 int code_gen_size, ret; 198 int code_gen_size, ret;
175 void (*gen_func)(void); 199 void (*gen_func)(void);
176 TranslationBlock *tb; 200 TranslationBlock *tb;
@@ -183,6 +207,38 @@ int cpu_x86_exec(CPUX86State *env1) @@ -183,6 +207,38 @@ int cpu_x86_exec(CPUX86State *env1)
183 saved_A0 = A0; 207 saved_A0 = A0;
184 saved_env = env; 208 saved_env = env;
185 env = env1; 209 env = env1;
  210 +#ifdef reg_EAX
  211 + saved_EAX = EAX;
  212 + EAX = env->regs[R_EAX];
  213 +#endif
  214 +#ifdef reg_ECX
  215 + saved_ECX = ECX;
  216 + ECX = env->regs[R_ECX];
  217 +#endif
  218 +#ifdef reg_EDX
  219 + saved_EDX = EDX;
  220 + EDX = env->regs[R_EDX];
  221 +#endif
  222 +#ifdef reg_EBX
  223 + saved_EBX = EBX;
  224 + EBX = env->regs[R_EBX];
  225 +#endif
  226 +#ifdef reg_ESP
  227 + saved_ESP = ESP;
  228 + ESP = env->regs[R_ESP];
  229 +#endif
  230 +#ifdef reg_EBP
  231 + saved_EBP = EBP;
  232 + EBP = env->regs[R_EBP];
  233 +#endif
  234 +#ifdef reg_ESI
  235 + saved_ESI = ESI;
  236 + ESI = env->regs[R_ESI];
  237 +#endif
  238 +#ifdef reg_EDI
  239 + saved_EDI = EDI;
  240 + EDI = env->regs[R_EDI];
  241 +#endif
186 242
187 /* prepare setjmp context for exception handling */ 243 /* prepare setjmp context for exception handling */
188 if (setjmp(env->jmp_env) == 0) { 244 if (setjmp(env->jmp_env) == 0) {
@@ -217,6 +273,30 @@ int cpu_x86_exec(CPUX86State *env1) @@ -217,6 +273,30 @@ int cpu_x86_exec(CPUX86State *env1)
217 ret = env->exception_index; 273 ret = env->exception_index;
218 274
219 /* restore global registers */ 275 /* restore global registers */
  276 +#ifdef reg_EAX
  277 + EAX = saved_EAX;
  278 +#endif
  279 +#ifdef reg_ECX
  280 + ECX = saved_ECX;
  281 +#endif
  282 +#ifdef reg_EDX
  283 + EDX = saved_EDX;
  284 +#endif
  285 +#ifdef reg_EBX
  286 + EBX = saved_EBX;
  287 +#endif
  288 +#ifdef reg_ESP
  289 + ESP = saved_ESP;
  290 +#endif
  291 +#ifdef reg_EBP
  292 + EBP = saved_EBP;
  293 +#endif
  294 +#ifdef reg_ESI
  295 + ESI = saved_ESI;
  296 +#endif
  297 +#ifdef reg_EDI
  298 + EDI = saved_EDI;
  299 +#endif
220 T0 = saved_T0; 300 T0 = saved_T0;
221 T1 = saved_T1; 301 T1 = saved_T1;
222 A0 = saved_A0; 302 A0 = saved_A0;
exec-i386.h
@@ -36,10 +36,27 @@ register unsigned int A0 asm(&quot;edi&quot;); @@ -36,10 +36,27 @@ register unsigned int A0 asm(&quot;edi&quot;);
36 register struct CPUX86State *env asm("ebp"); 36 register struct CPUX86State *env asm("ebp");
37 #endif 37 #endif
38 #ifdef __powerpc__ 38 #ifdef __powerpc__
  39 +register unsigned int EAX asm("r16");
  40 +register unsigned int ECX asm("r17");
  41 +register unsigned int EDX asm("r18");
  42 +register unsigned int EBX asm("r19");
  43 +register unsigned int ESP asm("r20");
  44 +register unsigned int EBP asm("r21");
  45 +register unsigned int ESI asm("r22");
  46 +register unsigned int EDI asm("r23");
39 register unsigned int T0 asm("r24"); 47 register unsigned int T0 asm("r24");
40 register unsigned int T1 asm("r25"); 48 register unsigned int T1 asm("r25");
41 register unsigned int A0 asm("r26"); 49 register unsigned int A0 asm("r26");
42 register struct CPUX86State *env asm("r27"); 50 register struct CPUX86State *env asm("r27");
  51 +#define USE_INT_TO_FLOAT_HELPERS
  52 +#define reg_EAX
  53 +#define reg_ECX
  54 +#define reg_EDX
  55 +#define reg_EBX
  56 +#define reg_ESP
  57 +#define reg_EBP
  58 +#define reg_ESI
  59 +#define reg_EDI
43 #endif 60 #endif
44 #ifdef __arm__ 61 #ifdef __arm__
45 register unsigned int T0 asm("r4"); 62 register unsigned int T0 asm("r4");
@@ -70,14 +87,30 @@ register struct CPUX86State *env asm(&quot;l3&quot;); @@ -70,14 +87,30 @@ register struct CPUX86State *env asm(&quot;l3&quot;);
70 #define xglue(x, y) x ## y 87 #define xglue(x, y) x ## y
71 #define glue(x, y) xglue(x, y) 88 #define glue(x, y) xglue(x, y)
72 89
  90 +#ifndef reg_EAX
73 #define EAX (env->regs[R_EAX]) 91 #define EAX (env->regs[R_EAX])
  92 +#endif
  93 +#ifndef reg_ECX
74 #define ECX (env->regs[R_ECX]) 94 #define ECX (env->regs[R_ECX])
  95 +#endif
  96 +#ifndef reg_EDX
75 #define EDX (env->regs[R_EDX]) 97 #define EDX (env->regs[R_EDX])
  98 +#endif
  99 +#ifndef reg_EBX
76 #define EBX (env->regs[R_EBX]) 100 #define EBX (env->regs[R_EBX])
  101 +#endif
  102 +#ifndef reg_ESP
77 #define ESP (env->regs[R_ESP]) 103 #define ESP (env->regs[R_ESP])
  104 +#endif
  105 +#ifndef reg_EBP
78 #define EBP (env->regs[R_EBP]) 106 #define EBP (env->regs[R_EBP])
  107 +#endif
  108 +#ifndef reg_ESI
79 #define ESI (env->regs[R_ESI]) 109 #define ESI (env->regs[R_ESI])
  110 +#endif
  111 +#ifndef reg_EDI
80 #define EDI (env->regs[R_EDI]) 112 #define EDI (env->regs[R_EDI])
  113 +#endif
81 #define PC (env->pc) 114 #define PC (env->pc)
82 #define DF (env->df) 115 #define DF (env->df)
83 116
linux-user/main.c
@@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include <stdio.h> 21 #include <stdio.h>
22 #include <stdarg.h> 22 #include <stdarg.h>
  23 +#include <string.h>
23 #include <errno.h> 24 #include <errno.h>
24 #include <unistd.h> 25 #include <unistd.h>
25 26
linux-user/syscall.c
@@ -20,6 +20,7 @@ @@ -20,6 +20,7 @@
20 #include <stdlib.h> 20 #include <stdlib.h>
21 #include <stdio.h> 21 #include <stdio.h>
22 #include <stdarg.h> 22 #include <stdarg.h>
  23 +#include <string.h>
23 #include <elf.h> 24 #include <elf.h>
24 #include <endian.h> 25 #include <endian.h>
25 #include <errno.h> 26 #include <errno.h>
@@ -42,6 +43,9 @@ @@ -42,6 +43,9 @@
42 #define termios host_termios 43 #define termios host_termios
43 #define winsize host_winsize 44 #define winsize host_winsize
44 #define termio host_termio 45 #define termio host_termio
  46 +#define sgttyb host_sgttyb /* same as target */
  47 +#define tchars host_tchars /* same as target */
  48 +#define ltchars host_ltchars /* same as target */
45 49
46 #include <linux/termios.h> 50 #include <linux/termios.h>
47 #include <linux/unistd.h> 51 #include <linux/unistd.h>
@@ -904,7 +908,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, @@ -904,7 +908,8 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
904 case TARGET_NR_ftime: 908 case TARGET_NR_ftime:
905 goto unimplemented; 909 goto unimplemented;
906 case TARGET_NR_sync: 910 case TARGET_NR_sync:
907 - ret = get_errno(sync()); 911 + sync();
  912 + ret = 0;
908 break; 913 break;
909 case TARGET_NR_kill: 914 case TARGET_NR_kill:
910 ret = get_errno(kill(arg1, arg2)); 915 ret = get_errno(kill(arg1, arg2));
op-i386.c
@@ -123,6 +123,32 @@ static inline int lshift(int x, int n) @@ -123,6 +123,32 @@ static inline int lshift(int x, int n)
123 /* NOTE: not static to force relocation generation by GCC */ 123 /* NOTE: not static to force relocation generation by GCC */
124 void raise_exception(int exception_index) 124 void raise_exception(int exception_index)
125 { 125 {
  126 + /* NOTE: the register at this point must be saved by hand because
  127 + longjmp restore them */
  128 +#ifdef reg_EAX
  129 + env->regs[R_EAX] = EAX;
  130 +#endif
  131 +#ifdef reg_ECX
  132 + env->regs[R_ECX] = ECX;
  133 +#endif
  134 +#ifdef reg_EDX
  135 + env->regs[R_EDX] = EDX;
  136 +#endif
  137 +#ifdef reg_EBX
  138 + env->regs[R_EBX] = EBX;
  139 +#endif
  140 +#ifdef reg_ESP
  141 + env->regs[R_ESP] = ESP;
  142 +#endif
  143 +#ifdef reg_EBP
  144 + env->regs[R_EBP] = EBP;
  145 +#endif
  146 +#ifdef reg_ESI
  147 + env->regs[R_ESI] = ESI;
  148 +#endif
  149 +#ifdef reg_EDI
  150 + env->regs[R_EDI] = EDI;
  151 +#endif
126 env->exception_index = exception_index; 152 env->exception_index = exception_index;
127 longjmp(env->jmp_env, 1); 153 longjmp(env->jmp_env, 1);
128 } 154 }
@@ -1341,6 +1367,41 @@ void OPPROTO op_fldl_FT0_A0(void) @@ -1341,6 +1367,41 @@ void OPPROTO op_fldl_FT0_A0(void)
1341 FT0 = ldfq((void *)A0); 1367 FT0 = ldfq((void *)A0);
1342 } 1368 }
1343 1369
  1370 +/* helpers are needed to avoid static constant reference. XXX: find a better way */
  1371 +#ifdef USE_INT_TO_FLOAT_HELPERS
  1372 +
  1373 +void helper_fild_FT0_A0(void)
  1374 +{
  1375 + FT0 = (CPU86_LDouble)ldsw((void *)A0);
  1376 +}
  1377 +
  1378 +void helper_fildl_FT0_A0(void)
  1379 +{
  1380 + FT0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1381 +}
  1382 +
  1383 +void helper_fildll_FT0_A0(void)
  1384 +{
  1385 + FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1386 +}
  1387 +
  1388 +void OPPROTO op_fild_FT0_A0(void)
  1389 +{
  1390 + helper_fild_FT0_A0();
  1391 +}
  1392 +
  1393 +void OPPROTO op_fildl_FT0_A0(void)
  1394 +{
  1395 + helper_fildl_FT0_A0();
  1396 +}
  1397 +
  1398 +void OPPROTO op_fildll_FT0_A0(void)
  1399 +{
  1400 + helper_fildll_FT0_A0();
  1401 +}
  1402 +
  1403 +#else
  1404 +
1344 void OPPROTO op_fild_FT0_A0(void) 1405 void OPPROTO op_fild_FT0_A0(void)
1345 { 1406 {
1346 FT0 = (CPU86_LDouble)ldsw((void *)A0); 1407 FT0 = (CPU86_LDouble)ldsw((void *)A0);
@@ -1355,6 +1416,7 @@ void OPPROTO op_fildll_FT0_A0(void) @@ -1355,6 +1416,7 @@ void OPPROTO op_fildll_FT0_A0(void)
1355 { 1416 {
1356 FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); 1417 FT0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1357 } 1418 }
  1419 +#endif
1358 1420
1359 /* fp load ST0 */ 1421 /* fp load ST0 */
1360 1422
@@ -1393,6 +1455,41 @@ void OPPROTO op_fldt_ST0_A0(void) @@ -1393,6 +1455,41 @@ void OPPROTO op_fldt_ST0_A0(void)
1393 } 1455 }
1394 #endif 1456 #endif
1395 1457
  1458 +/* helpers are needed to avoid static constant reference. XXX: find a better way */
  1459 +#ifdef USE_INT_TO_FLOAT_HELPERS
  1460 +
  1461 +void helper_fild_ST0_A0(void)
  1462 +{
  1463 + ST0 = (CPU86_LDouble)ldsw((void *)A0);
  1464 +}
  1465 +
  1466 +void helper_fildl_ST0_A0(void)
  1467 +{
  1468 + ST0 = (CPU86_LDouble)((int32_t)ldl((void *)A0));
  1469 +}
  1470 +
  1471 +void helper_fildll_ST0_A0(void)
  1472 +{
  1473 + ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
  1474 +}
  1475 +
  1476 +void OPPROTO op_fild_ST0_A0(void)
  1477 +{
  1478 + helper_fild_ST0_A0();
  1479 +}
  1480 +
  1481 +void OPPROTO op_fildl_ST0_A0(void)
  1482 +{
  1483 + helper_fildl_ST0_A0();
  1484 +}
  1485 +
  1486 +void OPPROTO op_fildll_ST0_A0(void)
  1487 +{
  1488 + helper_fildll_ST0_A0();
  1489 +}
  1490 +
  1491 +#else
  1492 +
1396 void OPPROTO op_fild_ST0_A0(void) 1493 void OPPROTO op_fild_ST0_A0(void)
1397 { 1494 {
1398 ST0 = (CPU86_LDouble)ldsw((void *)A0); 1495 ST0 = (CPU86_LDouble)ldsw((void *)A0);
@@ -1408,6 +1505,8 @@ void OPPROTO op_fildll_ST0_A0(void) @@ -1408,6 +1505,8 @@ void OPPROTO op_fildll_ST0_A0(void)
1408 ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0)); 1505 ST0 = (CPU86_LDouble)((int64_t)ldq((void *)A0));
1409 } 1506 }
1410 1507
  1508 +#endif
  1509 +
1411 /* fp store */ 1510 /* fp store */
1412 1511
1413 void OPPROTO op_fsts_ST0_A0(void) 1512 void OPPROTO op_fsts_ST0_A0(void)
ops_template.h
@@ -809,6 +809,7 @@ void OPPROTO glue(op_rep_movs, SUFFIX)(void) @@ -809,6 +809,7 @@ void OPPROTO glue(op_rep_movs, SUFFIX)(void)
809 EDI += inc; 809 EDI += inc;
810 ECX--; 810 ECX--;
811 } 811 }
  812 + FORCE_RET();
812 } 813 }
813 814
814 void OPPROTO glue(op_stos, SUFFIX)(void) 815 void OPPROTO glue(op_stos, SUFFIX)(void)
@@ -826,6 +827,7 @@ void OPPROTO glue(op_rep_stos, SUFFIX)(void) @@ -826,6 +827,7 @@ void OPPROTO glue(op_rep_stos, SUFFIX)(void)
826 EDI += inc; 827 EDI += inc;
827 ECX--; 828 ECX--;
828 } 829 }
  830 + FORCE_RET();
829 } 831 }
830 832
831 void OPPROTO glue(op_lods, SUFFIX)(void) 833 void OPPROTO glue(op_lods, SUFFIX)(void)
@@ -859,6 +861,7 @@ void OPPROTO glue(op_rep_lods, SUFFIX)(void) @@ -859,6 +861,7 @@ void OPPROTO glue(op_rep_lods, SUFFIX)(void)
859 ESI += inc; 861 ESI += inc;
860 ECX--; 862 ECX--;
861 } 863 }
  864 + FORCE_RET();
862 } 865 }
863 866
864 void OPPROTO glue(op_scas, SUFFIX)(void) 867 void OPPROTO glue(op_scas, SUFFIX)(void)
@@ -890,6 +893,7 @@ void OPPROTO glue(op_repz_scas, SUFFIX)(void) @@ -890,6 +893,7 @@ void OPPROTO glue(op_repz_scas, SUFFIX)(void)
890 CC_DST = v1 - v2; 893 CC_DST = v1 - v2;
891 CC_OP = CC_OP_SUBB + SHIFT; 894 CC_OP = CC_OP_SUBB + SHIFT;
892 } 895 }
  896 + FORCE_RET();
893 } 897 }
894 898
895 void OPPROTO glue(op_repnz_scas, SUFFIX)(void) 899 void OPPROTO glue(op_repnz_scas, SUFFIX)(void)
@@ -911,6 +915,7 @@ void OPPROTO glue(op_repnz_scas, SUFFIX)(void) @@ -911,6 +915,7 @@ void OPPROTO glue(op_repnz_scas, SUFFIX)(void)
911 CC_DST = v1 - v2; 915 CC_DST = v1 - v2;
912 CC_OP = CC_OP_SUBB + SHIFT; 916 CC_OP = CC_OP_SUBB + SHIFT;
913 } 917 }
  918 + FORCE_RET();
914 } 919 }
915 920
916 void OPPROTO glue(op_cmps, SUFFIX)(void) 921 void OPPROTO glue(op_cmps, SUFFIX)(void)
@@ -942,6 +947,7 @@ void OPPROTO glue(op_repz_cmps, SUFFIX)(void) @@ -942,6 +947,7 @@ void OPPROTO glue(op_repz_cmps, SUFFIX)(void)
942 CC_DST = v1 - v2; 947 CC_DST = v1 - v2;
943 CC_OP = CC_OP_SUBB + SHIFT; 948 CC_OP = CC_OP_SUBB + SHIFT;
944 } 949 }
  950 + FORCE_RET();
945 } 951 }
946 952
947 void OPPROTO glue(op_repnz_cmps, SUFFIX)(void) 953 void OPPROTO glue(op_repnz_cmps, SUFFIX)(void)
@@ -962,6 +968,7 @@ void OPPROTO glue(op_repnz_cmps, SUFFIX)(void) @@ -962,6 +968,7 @@ void OPPROTO glue(op_repnz_cmps, SUFFIX)(void)
962 CC_DST = v1 - v2; 968 CC_DST = v1 - v2;
963 CC_OP = CC_OP_SUBB + SHIFT; 969 CC_OP = CC_OP_SUBB + SHIFT;
964 } 970 }
  971 + FORCE_RET();
965 } 972 }
966 973
967 /* port I/O */ 974 /* port I/O */
@@ -986,6 +993,7 @@ void OPPROTO glue(op_rep_outs, SUFFIX)(void) @@ -986,6 +993,7 @@ void OPPROTO glue(op_rep_outs, SUFFIX)(void)
986 ESI += inc; 993 ESI += inc;
987 ECX--; 994 ECX--;
988 } 995 }
  996 + FORCE_RET();
989 } 997 }
990 998
991 void OPPROTO glue(op_ins, SUFFIX)(void) 999 void OPPROTO glue(op_ins, SUFFIX)(void)
@@ -1008,6 +1016,7 @@ void OPPROTO glue(op_rep_ins, SUFFIX)(void) @@ -1008,6 +1016,7 @@ void OPPROTO glue(op_rep_ins, SUFFIX)(void)
1008 EDI += (DF << SHIFT); 1016 EDI += (DF << SHIFT);
1009 ECX--; 1017 ECX--;
1010 } 1018 }
  1019 + FORCE_RET();
1011 } 1020 }
1012 1021
1013 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void) 1022 void OPPROTO glue(glue(op_out, SUFFIX), _T0_T1)(void)
tests/Makefile
@@ -4,8 +4,9 @@ CFLAGS=-Wall -O2 -g @@ -4,8 +4,9 @@ CFLAGS=-Wall -O2 -g
4 LDFLAGS= 4 LDFLAGS=
5 5
6 ifeq ($(ARCH),i386) 6 ifeq ($(ARCH),i386)
7 -TESTS=hello test2 sha1 test-i386 7 +TESTS=test2 sha1-i386 test-i386
8 endif 8 endif
  9 +TESTS+=sha1
9 10
10 GEMU=../gemu 11 GEMU=../gemu
11 12
@@ -13,26 +14,32 @@ all: $(TESTS) @@ -13,26 +14,32 @@ all: $(TESTS)
13 14
14 hello: hello.c 15 hello: hello.c
15 $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $< 16 $(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
  17 + strip hello
16 18
17 test2: test2.c 19 test2: test2.c
18 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< 20 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
19 21
20 -# i386 emulation test (dump various opcodes) */ 22 +# i386 emulation test (test various opcodes) */
21 test-i386: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h 23 test-i386: test-i386.c test-i386.h test-i386-shift.h test-i386-muldiv.h
22 $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ $< -lm 24 $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ $< -lm
23 25
24 test: test-i386 26 test: test-i386
  27 +ifeq ($(ARCH),i386)
25 ./test-i386 > test-i386.ref 28 ./test-i386 > test-i386.ref
  29 +endif
26 $(GEMU) test-i386 > test-i386.out 30 $(GEMU) test-i386 > test-i386.out
27 @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi 31 @if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
28 32
29 # speed test 33 # speed test
30 -sha1: sha1.c 34 +sha1-i386: sha1.c
31 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< 35 $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
32 36
33 -speed: sha1 37 +sha1: sha1.c
  38 + $(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
  39 +
  40 +speed: sha1 sha1-i386
34 time ./sha1 41 time ./sha1
35 - time $(GEMU) sha1 42 + time $(GEMU) ./sha1-i386
36 43
37 clean: 44 clean:
38 rm -f *~ *.o $(TESTS) 45 rm -f *~ *.o $(TESTS)
tests/test-i386.c
@@ -653,7 +653,7 @@ void test_segs(void) @@ -653,7 +653,7 @@ void test_segs(void)
653 { 653 {
654 struct modify_ldt_ldt_s ldt; 654 struct modify_ldt_ldt_s ldt;
655 long long ldt_table[3]; 655 long long ldt_table[3];
656 - int i, res, res2; 656 + int res, res2;
657 char tmp; 657 char tmp;
658 658
659 ldt.entry_number = 1; 659 ldt.entry_number = 1;
@@ -679,9 +679,13 @@ void test_segs(void) @@ -679,9 +679,13 @@ void test_segs(void)
679 modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ 679 modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */
680 680
681 modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */ 681 modify_ldt(0, &ldt_table, sizeof(ldt_table)); /* read ldt entries */
682 - for(i=0;i<3;i++)  
683 - printf("%d: %016Lx\n", i, ldt_table[i]);  
684 - 682 +#if 0
  683 + {
  684 + int i;
  685 + for(i=0;i<3;i++)
  686 + printf("%d: %016Lx\n", i, ldt_table[i]);
  687 + }
  688 +#endif
685 /* do some tests with fs or gs */ 689 /* do some tests with fs or gs */
686 asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); 690 asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1)));
687 asm volatile ("movl %0, %%gs" : : "r" (MK_SEL(2))); 691 asm volatile ("movl %0, %%gs" : : "r" (MK_SEL(2)));
translate-i386.c
@@ -38,10 +38,40 @@ @@ -38,10 +38,40 @@
38 #define offsetof(type, field) ((size_t) &((type *)0)->field) 38 #define offsetof(type, field) ((size_t) &((type *)0)->field)
39 #endif 39 #endif
40 40
  41 +/* XXX: move that elsewhere */
41 static uint16_t *gen_opc_ptr; 42 static uint16_t *gen_opc_ptr;
42 static uint32_t *gen_opparam_ptr; 43 static uint32_t *gen_opparam_ptr;
43 int __op_param1, __op_param2, __op_param3; 44 int __op_param1, __op_param2, __op_param3;
44 45
  46 +#ifdef __i386__
  47 +static inline void flush_icache_range(unsigned long start, unsigned long stop)
  48 +{
  49 +}
  50 +#endif
  51 +
  52 +#ifdef __powerpc__
  53 +
  54 +#define MIN_CACHE_LINE_SIZE 8 /* conservative value */
  55 +
  56 +static void inline flush_icache_range(unsigned long start, unsigned long stop)
  57 +{
  58 + unsigned long p;
  59 +
  60 + p = start & ~(MIN_CACHE_LINE_SIZE - 1);
  61 + stop = (stop + MIN_CACHE_LINE_SIZE - 1) & ~(MIN_CACHE_LINE_SIZE - 1);
  62 +
  63 + for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
  64 + asm ("dcbst 0,%0;" : : "r"(p) : "memory");
  65 + }
  66 + asm ("sync");
  67 + for (p = start; p < stop; p += MIN_CACHE_LINE_SIZE) {
  68 + asm ("icbi 0,%0; sync;" : : "r"(p) : "memory");
  69 + }
  70 + asm ("sync");
  71 + asm ("isync");
  72 +}
  73 +#endif
  74 +
45 extern FILE *logfile; 75 extern FILE *logfile;
46 extern int loglevel; 76 extern int loglevel;
47 77
@@ -3179,6 +3209,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, @@ -3179,6 +3209,7 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
3179 DisasContext dc1, *dc = &dc1; 3209 DisasContext dc1, *dc = &dc1;
3180 uint8_t *pc_ptr; 3210 uint8_t *pc_ptr;
3181 uint16_t *gen_opc_end; 3211 uint16_t *gen_opc_end;
  3212 + int gen_code_size;
3182 long ret; 3213 long ret;
3183 #ifdef DEBUG_DISAS 3214 #ifdef DEBUG_DISAS
3184 struct disassemble_info disasm_info; 3215 struct disassemble_info disasm_info;
@@ -3264,7 +3295,9 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, @@ -3264,7 +3295,9 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
3264 #endif 3295 #endif
3265 3296
3266 /* generate machine code */ 3297 /* generate machine code */
3267 - *gen_code_size_ptr = dyngen_code(gen_code_buf, gen_opc_buf, gen_opparam_buf); 3298 + gen_code_size = dyngen_code(gen_code_buf, gen_opc_buf, gen_opparam_buf);
  3299 + flush_icache_range((unsigned long)gen_code_buf, (unsigned long)(gen_code_buf + gen_code_size));
  3300 + *gen_code_size_ptr = gen_code_size;
3268 3301
3269 #ifdef DEBUG_DISAS 3302 #ifdef DEBUG_DISAS
3270 if (loglevel) { 3303 if (loglevel) {