diff mbox

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

Message ID 4B770B02.4030409@gnu.org
State New
Headers show

Commit Message

Paolo Bonzini Feb. 13, 2010, 8:26 p.m. UTC
On 02/13/2010 06:58 PM, Blue Swirl wrote:
> V9 ABI gives more registers to application use.

Except that glibc uses those---in theory, as I see it, it should be 
compiled with fixed g2 and g3 to leave them to the application.  I get 
it now.

It may be possible to make the workaround a big less ugly (I'm thinking 
of avoiding #undef/#define by using assembly).  I made a patch (see 
attachment, just FYI), maybe sometime I'll try it using self-virtualized 
qemu.

Paolo
commit 59ca12838278bed97ce5cc311f90ddfec7953047
Author: Paolo Bonzini <pbonzini@redhat.com>
Date:   Sat Feb 13 21:13:12 2010 +0100

    make sparc workaround less ugly
    
    Not-quite-signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Comments

Blue Swirl Feb. 13, 2010, 8:57 p.m. UTC | #1
On Sat, Feb 13, 2010 at 10:26 PM, Paolo Bonzini <bonzini@gnu.org> wrote:
> On 02/13/2010 06:58 PM, Blue Swirl wrote:
>>
>> V9 ABI gives more registers to application use.
>
> Except that glibc uses those---in theory, as I see it, it should be compiled
> with fixed g2 and g3 to leave them to the application.  I get it now.
>
> It may be possible to make the workaround a big less ugly (I'm thinking of
> avoiding #undef/#define by using assembly).  I made a patch (see attachment,
> just FYI), maybe sometime I'll try it using self-virtualized qemu.

Yes, that's much better.
Paolo Bonzini Feb. 13, 2010, 8:58 p.m. UTC | #2
On 02/13/2010 09:57 PM, Blue Swirl wrote:
> On Sat, Feb 13, 2010 at 10:26 PM, Paolo Bonzini<bonzini@gnu.org>  wrote:
>> On 02/13/2010 06:58 PM, Blue Swirl wrote:
>>>
>>> V9 ABI gives more registers to application use.
>>
>> Except that glibc uses those---in theory, as I see it, it should be compiled
>> with fixed g2 and g3 to leave them to the application.  I get it now.
>>
>> It may be possible to make the workaround a big less ugly (I'm thinking of
>> avoiding #undef/#define by using assembly).  I made a patch (see attachment,
>> just FYI), maybe sometime I'll try it using self-virtualized qemu.
>
> Yes, that's much better.

If it works. :-)

Paolo
diff mbox

Patch

diff --git a/cpu-exec.c b/cpu-exec.c
index badd5d7..01b7143 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -39,9 +39,14 @@ 
 #endif
 
 #if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-// Work around ugly bugs in glibc that mangle global register contents
-#undef env
+/* glibc will mangle global register contents.  To work around this,
+ * we avoid using the global register in this file, and place back
+ * cpu_single_env in AREG0 before giving control to target-* routines.
+ */
+#define export_env()	asm ("mov %0, %%" AREG0 : : "r" (cpu_single_env) : AREG0); 
 #define env cpu_single_env
+#else
+#define export_env()
 #endif
 
 int tb_invalidated_flag;
@@ -257,11 +262,7 @@  int cpu_exec(CPUState *env1)
     /* prepare setjmp context for exception handling */
     for(;;) {
         if (setjmp(env->jmp_env) == 0) {
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
-                    env = cpu_single_env;
-#define env cpu_single_env
-#endif
+            export_env();
             /* if an exception is pending, we execute it here */
             if (env->exception_index >= 0) {
                 if (env->exception_index >= EXCP_INTERRUPT) {
@@ -387,11 +388,7 @@  int cpu_exec(CPUState *env1)
                             env->interrupt_request &= ~(CPU_INTERRUPT_HARD | CPU_INTERRUPT_VIRQ);
                             intno = cpu_get_pic_interrupt(env);
                             qemu_log_mask(CPU_LOG_TB_IN_ASM, "Servicing hardware INT=0x%02x\n", intno);
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
-                    env = cpu_single_env;
-#define env cpu_single_env
-#endif
+                            export_env();
                             do_interrupt(intno, 0, 0, 0, 1);
                             /* ensure that no TB jump will be modified as
                                the program flow was changed */
@@ -603,12 +600,8 @@  int cpu_exec(CPUState *env1)
                 if (!unlikely (env->exit_request)) {
                     env->current_tb = tb;
                     tc_ptr = tb->tc_ptr;
-                /* execute the generated code */
-#if defined(__sparc__) && !defined(CONFIG_SOLARIS)
-#undef env
-                    env = cpu_single_env;
-#define env cpu_single_env
-#endif
+                    /* execute the generated code */
+                    export_env();
                     next_tb = tcg_qemu_tb_exec(tc_ptr);
                     env->current_tb = NULL;
                     if ((next_tb & 3) == 2) {