qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 0/2] simplify global register save/restore


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 0/2] simplify global register save/restore
Date: Sat, 13 Feb 2010 19:58:41 +0200

On Thu, Feb 11, 2010 at 1:26 AM, Paolo Bonzini <address@hidden> wrote:
> Since b567b38 (target-arm: remove T0 and T1, 2009-10-16) the only global
> register that is actually used is AREG0, so the complexity of
> hostregs_helper.h is unwarranted.
>
> Let's just say that env should be the only global register.  AREG1 and
> AREG2 in principle could still be used to work around bad register
> allocation in GCC, so I'm leaving them in dyngen-exec.h.
>
> Blue Swirl, can you check whether changing AREG0 to another register
> in dyngen-exec.h would fix the "annoying glibc bugs mangling global
> register variables"?  Or maybe we can remove the workaround altogether,
> considering the bug was fixed in version 2.3 of glibc dated 2001-11-29
> (at least that's what I'd guess from the history)?

The problem is with global register use by the system libraries. Sparc
V8 ABI reserves %g5 to %g7 for system. System may not use %g2 to %g4.
V9 ABI gives more registers to application use. For more information
see for example this page at Oracle:
http://developers.sun.com/solaris/articles/sparcv9abi.html

One part of the problem is that libraries are not compiled with
appropriate CFLAGS so that they avoid using global registers. The
second part is that the libraries may contain assembly language code
which directly uses the registers (especially setjmp/longjmp, which
are critical for QEMU).

Here are some statistics on Debian Lenny, with libc6 version 2.7-18lenny2:

$ objdump -d /lib/libc.so.6 |grep %g1|wc -l
73753
$ objdump -d /lib/libc.so.6 |grep %g2|wc -l
37571
$ objdump -d /lib/libc.so.6 |grep %g3|wc -l
23205
$ objdump -d /lib/libc.so.6 |grep %g4|wc -l
12267
$ objdump -d /lib/libc.so.6 |grep %g5|wc -l
444
$ objdump -d /lib/libc.so.6 |grep %g6|wc -l
150
$ objdump -d /lib/libc.so.6 |grep %g7|wc -l
2776

Same for OpenBSD 4.6, which is pure Sparc V9.

$ objdump -d /usr/lib/libc.so.51.0 |grep %g1|wc -l
   41040
$ objdump -d /usr/lib/libc.so.51.0 |grep %g2|wc -l
   21115
$ objdump -d /usr/lib/libc.so.51.0 |grep %g3|wc -l
   10945
$ objdump -d /usr/lib/libc.so.51.0 |grep %g4|wc -l
    6682
$ objdump -d /usr/lib/libc.so.51.0 |grep %g5|wc -l
    3712
$ objdump -d /usr/lib/libc.so.51.0 |grep %g6|wc -l
       4
$ objdump -d /usr/lib/libc.so.51.0 |grep %g7|wc -l
      20

So I guess changing the global register would not benefit Linux much.

If I remove the workaround from cpu-exec.c, a bus error is generated
almost immediately. Otherwise on Linux, sparc-softmmu can boot Linux
(sparc-test) image, but QEMU crashes just before command line. On
OpenBSD, the same test reaches command prompt.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]