From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1HWk5i-00076b-Ud for qemu-devel@nongnu.org; Wed, 28 Mar 2007 22:10:18 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1HWk5f-00076L-9x for qemu-devel@nongnu.org; Wed, 28 Mar 2007 22:10:17 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1HWk5f-00076I-6d for qemu-devel@nongnu.org; Wed, 28 Mar 2007 21:10:15 -0500 Received: from wx-out-0506.google.com ([66.249.82.236]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1HWk37-0002Ha-OY for qemu-devel@nongnu.org; Wed, 28 Mar 2007 22:07:37 -0400 Received: by wx-out-0506.google.com with SMTP id i30so63747wxd for ; Wed, 28 Mar 2007 19:07:36 -0700 (PDT) Message-ID: <460B1F65.6040308@codemonkey.ws> Date: Wed, 28 Mar 2007 21:07:33 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [RFC/experimental patch] qemu (x86_64 on x86_64 -no-kqemu) compiles with gcc4 and works References: <200703241850.03116.axel.zeuner@gmx.de> <200703251412.07039.Axel.Zeuner@gmx.de> <4607094F.7000704@codemonkey.ws> <200703260816.00508.axel.zeuner@gmx.de> In-Reply-To: <200703260816.00508.axel.zeuner@gmx.de> Content-Type: multipart/mixed; boundary="------------010301060904050107080006" Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Axel Zeuner Cc: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------010301060904050107080006 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Axel Zeuner wrote: > Hi Anthony, > > On Monday 26 March 2007 01:44, you wrote: > >> Axel Zeuner wrote: >> >>> On Saturday 24 March 2007 21:15, Anthony Liguori wrote: >>> >>>> The tricky thing I still can't figure out is how to get ASM_SOFTMMU >>>> working. The problem is GLUE(st, SUFFIX) function. First GCC cannot >>>> deal with the register pressure. The problem I can't seem to fix though >>>> is that GCC sticks %1 in %esi because we're only using an "r" >>>> constraint, not a "q" constraint. This results in the generation of >>>> %sib which is an invalid register. However, refactoring the code to not >>>> require a "q" constraint doesn't seem to help either. >>>> >>> Hi Anthony, >>> could you please try the attached patch for softmmu_header.h? Allows >>> compiling with gcc4 and ASM_SOFTMMU. >>> >> That did the trick. Could you explain what your changes did? >> > > QEMU/i386 has only 3 three available registers if TARGET_I386 is selected > because ebx,ebp,esi,edi are used by the environment and T0, T1, T3( AKA A0). > This makes inline assembly really ugly. The called external C functions in > ASM_SOFTMMU are REGPARM(1,2), i.e. require their first arguments in eax, edx. > Based on some feedback from Paul Brook, I wrote another patch that just disables the use of register variables for GCC4. I think this is a considerably less hackish way to go about this. The generated code won't be as nice of course but at least it works. The patch applies against your cvtasm patches. Regards, Anthony Liguori > In the two ld functions three registers (eax, edx, ecx) are required and > destroyed because an external C function may be called. We relax the register > pressure a little bit by forcing the return value (res) into eax , because > the return value is returned in a destroyed register. Furthermore the called > C function returns its value in eax anyway (call %7). > > The st functions are a little more tricky: we need three registers and the > assembly code requires a reload of %0 (ptr) after the check if the external > function must be called. In the external function the three remaining > registers are destroyed. After the call a need also to reload of %1 (v) into > register is needed, i.e. we need more registers. Register saving on the stack > does not work, because there exist already 2 "m" constraints: if the code is > compiled with -fomit-frame-pointers these are expressed as offsets relative > to %esp, i.e X(%esp) and would become invalid after pushes onto the stack. > > One solution was to force all inputs to the asm block onto the stack, thats > what the replacement of the "r" constraints into "m" constraints do: they > force a memory reference. Because i386 can not do direct memory memory moves > one has to reload "m"(v) into ecx again, otherwise the generated assembler > code is invalid. > It must be mentioned, that the generated code is a little bit slower than the > original one. > > Kind Regards > Axel > >> Regards, >> >> Anthony Liguori >> >> >>> Kind regards >>> Axel >>> > > --------------010301060904050107080006 Content-Type: text/x-patch; name="gcc4-register-pressure.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="gcc4-register-pressure.diff" diff -r d19a5903d749 softmmu_header.h --- a/softmmu_header.h Tue Mar 27 13:23:10 2007 -0500 +++ b/softmmu_header.h Tue Mar 27 13:23:21 2007 -0500 @@ -240,9 +240,13 @@ static inline void glue(glue(st, SUFFIX) "2:\n" : : "r" (ptr), +#ifdef USE_REGISTER_VARIABLES /* NOTE: 'q' would be needed as constraint, but we could not use it with T1 ! */ "r" (v), +#else + "q" (v), +#endif "i" ((CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS), "i" (TARGET_PAGE_MASK | (DATA_SIZE - 1)), diff -r d19a5903d749 target-i386/cpu.h --- a/target-i386/cpu.h Tue Mar 27 13:23:10 2007 -0500 +++ b/target-i386/cpu.h Tue Mar 27 13:23:21 2007 -0500 @@ -26,6 +26,10 @@ #define TARGET_LONG_BITS 64 #else #define TARGET_LONG_BITS 32 +#endif + +#if TARGET_LONG_BITS <= HOST_LONG_BITS && __GNUC__ < 4 +#define USE_REGISTER_VARIABLES #endif /* target supports implicit self modifying code */ @@ -424,7 +428,7 @@ typedef union { #endif typedef struct CPUX86State { -#if TARGET_LONG_BITS > HOST_LONG_BITS +#ifndef USE_REGISTER_VARIABLES /* temporaries if we cannot store them in host registers */ target_ulong t0, t1, t2; #endif diff -r d19a5903d749 target-i386/exec.h --- a/target-i386/exec.h Tue Mar 27 13:23:10 2007 -0500 +++ b/target-i386/exec.h Tue Mar 27 13:23:21 2007 -0500 @@ -27,12 +27,16 @@ #define TARGET_LONG_BITS 32 #endif +#if TARGET_LONG_BITS <= HOST_LONG_BITS && __GNUC__ < 4 +#define USE_REGISTER_VARIABLES +#endif + #include "cpu-defs.h" /* at least 4 register variables are defined */ register struct CPUX86State *env asm(AREG0); -#if TARGET_LONG_BITS > HOST_LONG_BITS +#ifndef USE_REGISTER_VARIABLES /* no registers can be used */ #define T0 (env->t0) @@ -88,7 +92,7 @@ register target_ulong EDI asm(AREG11); #define reg_EDI #endif -#endif /* ! (TARGET_LONG_BITS > HOST_LONG_BITS) */ +#endif /* ! USE_REGISTER_VARIABLES */ #define A0 T2 --------------010301060904050107080006--