On Sat, 2005-07-23 at 19:14 +0200, Karel Gardas wrote: > Interesting! What's the performance of x86 on ARM? I would guess something > like 386/16-25MHz? Also are you running on stock nslu2 or have you done > un-underclocking and now running on 266MHz?
Yes, this an un-underclocked nslu2. I haven't run any benchmarks yet - the real world app I was interested in (gnu prolog) was usably fast, though. I attach the patches I needed to build a qemu-i386 linux-user emulator for armeb. I've split them into several patches, as the changes are a little fiddily, and I think they will be more comprehensible split up and given some explanation. I'd like to see all of these incorporated into the mainline qemu sources if possible. There is only one issue not addressed by the patches: it seems that when compiling for an arm host with -O2, gcc versions 3.3.5 and 3.3.6 at least will generate incorrect code for translate-op.c. I think it is to do with the very large switch/case construct included from op.h in that file. The solution is to compile that file with -fno-schedule-insns, but as this is apparently a gcc bug, I've not tried to fix it here. Some explanation of the patches: arm-bigendian-host.patch modifies arm.ld to allow linking a bigendian binary if and only if a bigendian host was detected at compile time. arm-build-fixes.patch brings some of the arm host code up to date with the rest of qemu. This would be needed to build for an arm little- endian host too. dyngen.patch corrects a bug in dyngen.c that resulted in incorrect generation of op.h where the build system has a different byte order from the host. Not strictly armeb related, but as I am cross-compiling for armeb on a i386 system, I needed it to build. op-gen-label.patch addresses a qemu bug that occurs on arm systems, but is not arm specific. The trouble is the generated code in op.c that includes "dummy" calls to __op_gen_label1 and friends. Because __op_gen_label1 is defined in dyngen.h as a global variable, not a function, it may be assigned an address at link time that is too far away from the code in op.c for a relocation to generated. The result is a linker error. I've fixed this by using the gcc section attribute to cause __op_gen_label[1-3] to be located in the text section, where they can be guaranteed to be close enough to the code in op.c. I'm not sure if this is the best solution, but it works for me. Maybe it would be more portable to define the __op_gen_label symbols as functions, rather than variables. -- Josh Parsons Philosophy Department 1238 Social Sciences and Humanities Bldg. University of California Davis, CA 95616-8673 USA Please avoid sending me Word or PowerPoint attachments. See http://www.gnu.org/philosophy/no-word-attachments.html
--- qemu/Makefile.target~ 2005-04-27 13:52:05.000000000 -0700 +++ qemu/Makefile.target 2005-07-20 13:41:46.000000000 -0700 @@ -191,8 +191,12 @@ ifeq ($(ARCH),arm) OP_CFLAGS=$(CFLAGS) -mno-sched-prolog -fno-omit-frame-pointer +ifeq ($(WORDS_BIGENDIAN),yes) +LDFLAGS+=-Wl,-EB -Wl,-T,$(SRC_PATH)/arm.ld +else LDFLAGS+=-Wl,-T,$(SRC_PATH)/arm.ld endif +endif ifeq ($(ARCH),m68k) OP_CFLAGS=$(CFLAGS) -fomit-frame-pointer --- qemu/arm.ld~ 2005-07-24 11:52:08.000000000 -0700 +++ qemu/arm.ld 2005-07-24 23:21:29.000000000 -0700 @@ -1,4 +1,4 @@ -OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", +OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") OUTPUT_ARCH(arm) ENTRY(_start)
--- qemu/cpu-exec.c~ 2005-04-27 13:52:05.000000000 -0700 +++ qemu/cpu-exec.c 2005-07-20 11:39:18.000000000 -0700 @@ -1124,7 +1124,7 @@ is_write = 0; return handle_cpu_signal(pc, (unsigned long)info->si_addr, is_write, - &uc->uc_sigmask); + &uc->uc_sigmask,puc); } #elif defined(__mc68000) --- qemu/disas.c~ 2005-04-27 13:52:05.000000000 -0700 +++ qemu/disas.c 2005-07-20 11:42:30.000000000 -0700 @@ -226,7 +226,7 @@ #endif for (pc = (unsigned long)code; pc < (unsigned long)code + size; pc += count) { fprintf(out, "0x%08lx: ", pc); -#ifdef __arm__ +#if 0 /*def __arm__ - this code no longer works as is_host is not around */ /* since data are included in the code, it is better to display code data too */ if (is_host) {
--- qemu-0.7.0/dyngen.c 2005-04-27 13:52:05.000000000 -0700 +++ qemu/dyngen.c 2005-07-21 13:19:30.000000000 -0700 @@ -1656,7 +1656,11 @@ #ifdef CONFIG_FORMAT_MACH offset -= section_hdr[sym->n_sect-1].addr; #endif - val = *(unsigned long *)(ptr + offset); + /* the line below formerly read + val = *(unsigned long)(ptr+offset); + which breaks when cross compiling for + a host with different byte order */ + val = get32((uint32_t *)(ptr + offset)); #ifdef ELF_USES_RELOCA { int reloc_shndx, nb_relocs1, j;
--- qemu/dyngen.h~ 2005-04-27 13:52:05.000000000 -0700 +++ qemu/dyngen.h 2005-07-24 23:03:15.000000000 -0700 @@ -19,7 +19,9 @@ */ int __op_param1, __op_param2, __op_param3; -int __op_gen_label1, __op_gen_label2, __op_gen_label3; +int __op_gen_label1 __attribute__ ((section ("text"))) =0; +int __op_gen_label2 __attribute__ ((section ("text"))) =0; +int __op_gen_label3 __attribute__ ((section ("text"))) =0; int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; #ifdef __i386__
_______________________________________________ Qemu-devel mailing list Qemu-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/qemu-devel