qemu-devel
[Top][All Lists]
Advanced

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

qemu + gcc4 (Was: [Qemu-devel] [RFC/experimental patch] qemu (x86_64 on


From: Gwenole Beauchesne
Subject: qemu + gcc4 (Was: [Qemu-devel] [RFC/experimental patch] qemu (x86_64 on x86_64 -no-kqemu) compiles with gcc4 and works)
Date: Fri, 20 Apr 2007 18:57:34 +0200 (CEST)

Hi,

By adding some GCC4 fixes on top of your patch, I was able to get qemu for i386 (on i386) to compile and run. So far, I've only tested a win2k guest.

For op_pshufw(), please keep the temporary destination register as S and D may reference the same register.

FYI, I am experimenting with an alternate gcc4 patch (inlined hereunder).
<http://svn.mandriva.com/svn/packages/cooker/qemu/current/SOURCES/qemu-0.9.0-gcc4.patch>

I have only tested the following configurations with -no-kvm -no-kqemu
- compiler: gcc 4.1.2-1mdv
- guest OS: { winXPsp2, linux }
- guest CPU: { i386, x86_64 (linux-only) }
- host CPU (compiled as): { i386, x86_64 }

PS: I have not tested yet on MacOS X.

Regards,
Gwenole

2007-04-20  Gwenole Beauchesne  <address@hidden>

        * gcc4 host support.

--- qemu-0.9.0/target-i386/ops_template.h.gcc4  2005-02-21 20:23:59.000000000 
+0000
+++ qemu-0.9.0/target-i386/ops_template.h       2007-04-20 14:53:32.000000000 
+0000
@@ -268,7 +268,7 @@ static int glue(compute_all_mul, SUFFIX)

 /* various optimized jumps cases */

-void OPPROTO glue(op_jb_sub, SUFFIX)(void)
+DEFINE_OP(glue(op_jb_sub, SUFFIX),
 {
     target_long src1, src2;
     src1 = CC_DST + CC_SRC;
@@ -277,23 +277,23 @@ void OPPROTO glue(op_jb_sub, SUFFIX)(voi
     if ((DATA_TYPE)src1 < (DATA_TYPE)src2)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_jz_sub, SUFFIX)(void)
+DEFINE_OP(glue(op_jz_sub, SUFFIX),
 {
     if ((DATA_TYPE)CC_DST == 0)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_jnz_sub, SUFFIX)(void)
+DEFINE_OP(glue(op_jnz_sub, SUFFIX),
 {
     if ((DATA_TYPE)CC_DST != 0)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_jbe_sub, SUFFIX)(void)
+DEFINE_OP(glue(op_jbe_sub, SUFFIX),
 {
     target_long src1, src2;
     src1 = CC_DST + CC_SRC;
@@ -302,16 +302,16 @@ void OPPROTO glue(op_jbe_sub, SUFFIX)(vo
     if ((DATA_TYPE)src1 <= (DATA_TYPE)src2)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_js_sub, SUFFIX)(void)
+DEFINE_OP(glue(op_js_sub, SUFFIX),
 {
     if (CC_DST & SIGN_MASK)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_jl_sub, SUFFIX)(void)
+DEFINE_OP(glue(op_jl_sub, SUFFIX),
 {
     target_long src1, src2;
     src1 = CC_DST + CC_SRC;
@@ -320,10 +320,9 @@ void OPPROTO glue(op_jl_sub, SUFFIX)(voi
     if ((DATA_STYPE)src1 < (DATA_STYPE)src2)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_jle_sub, SUFFIX)(void)
-{
+DEFINE_OP(glue(op_jle_sub, SUFFIX), {
     target_long src1, src2;
     src1 = CC_DST + CC_SRC;
     src2 = CC_SRC;
@@ -331,39 +330,39 @@ void OPPROTO glue(op_jle_sub, SUFFIX)(vo
     if ((DATA_STYPE)src1 <= (DATA_STYPE)src2)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

 /* oldies */

 #if DATA_BITS >= 16

-void OPPROTO glue(op_loopnz, SUFFIX)(void)
+DEFINE_OP(glue(op_loopnz, SUFFIX),
 {
     if ((DATA_TYPE)ECX != 0 && !(T0 & CC_Z))
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_loopz, SUFFIX)(void)
+DEFINE_OP(glue(op_loopz, SUFFIX),
 {
     if ((DATA_TYPE)ECX != 0 && (T0 & CC_Z))
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_jz_ecx, SUFFIX)(void)
+DEFINE_OP(glue(op_jz_ecx, SUFFIX),
 {
     if ((DATA_TYPE)ECX == 0)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

-void OPPROTO glue(op_jnz_ecx, SUFFIX)(void)
+DEFINE_OP(glue(op_jnz_ecx, SUFFIX),
 {
     if ((DATA_TYPE)ECX != 0)
         GOTO_LABEL_PARAM(1);
     FORCE_RET();
-}
+})

 #endif

--- qemu-0.9.0/target-i386/op.c.gcc4    2007-02-02 12:45:51.000000000 +0000
+++ qemu-0.9.0/target-i386/op.c 2007-04-20 15:20:55.000000000 +0000
@@ -18,7 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */

+#if __GNUC__ < 4
 #define ASM_SOFTMMU
+#endif
 #include "exec.h"

 /* n must be a constant to be efficient */
@@ -250,6 +252,7 @@ void OPPROTO op_imulb_AL_T0(void)
     EAX = (EAX & ~0xffff) | (res & 0xffff);
     CC_DST = res;
     CC_SRC = (res != (int8_t)res);
+    FORCE_RET();
 }

 void OPPROTO op_mulw_AX_T0(void)
@@ -270,6 +273,7 @@ void OPPROTO op_imulw_AX_T0(void)
     EDX = (EDX & ~0xffff) | ((res >> 16) & 0xffff);
     CC_DST = res;
     CC_SRC = (res != (int16_t)res);
+    FORCE_RET();
 }

 void OPPROTO op_mull_EAX_T0(void)
@@ -290,6 +294,7 @@ void OPPROTO op_imull_EAX_T0(void)
     EDX = (uint32_t)(res >> 32);
     CC_DST = res;
     CC_SRC = (res != (int32_t)res);
+    FORCE_RET();
 }

 void OPPROTO op_imulw_T0_T1(void)
@@ -299,6 +304,7 @@ void OPPROTO op_imulw_T0_T1(void)
     T0 = res;
     CC_DST = res;
     CC_SRC = (res != (int16_t)res);
+    FORCE_RET();
 }

 void OPPROTO op_imull_T0_T1(void)
@@ -308,6 +314,7 @@ void OPPROTO op_imull_T0_T1(void)
     T0 = res;
     CC_DST = res;
     CC_SRC = (res != (int32_t)res);
+    FORCE_RET();
 }

 #ifdef TARGET_X86_64
--- qemu-0.9.0/target-i386/exec.h.gcc4  2006-09-24 18:40:46.000000000 +0000
+++ qemu-0.9.0/target-i386/exec.h       2007-04-20 15:14:38.000000000 +0000
@@ -501,6 +501,7 @@ void update_fp_status(void);
 void helper_hlt(void);
 void helper_monitor(void);
 void helper_mwait(void);
+void helper_pshufw(MMXReg *dst, MMXReg *src, int order);

 extern const uint8_t parity_table[256];
 extern const uint8_t rclw_table[32];
--- qemu-0.9.0/target-i386/helper.c.gcc4        2007-04-20 14:49:44.000000000 
+0000
+++ qemu-0.9.0/target-i386/helper.c     2007-04-20 15:00:02.000000000 +0000
@@ -3522,8 +3522,15 @@ void helper_fxrstor(target_ulong ptr, in
         nb_xmm_regs = 8 << data64;
         addr = ptr + 0xa0;
         for(i = 0; i < nb_xmm_regs; i++) {
+#if __GNUC__ < 4
             env->xmm_regs[i].XMM_Q(0) = ldq(addr);
             env->xmm_regs[i].XMM_Q(1) = ldq(addr + 8);
+#else
+            env->xmm_regs[i].XMM_L(0) = ldl(addr);
+            env->xmm_regs[i].XMM_L(1) = ldl(addr + 4);
+            env->xmm_regs[i].XMM_L(2) = ldl(addr + 8);
+            env->xmm_regs[i].XMM_L(3) = ldl(addr + 12);
+#endif
             addr += 16;
         }
     }
--- qemu-0.9.0/target-i386/ops_sse.h.gcc4       2007-01-16 19:28:58.000000000 
+0000
+++ qemu-0.9.0/target-i386/ops_sse.h    2007-04-20 15:11:19.000000000 +0000
@@ -581,14 +581,9 @@ void OPPROTO glue(op_movq_T0_mm, SUFFIX)
 void OPPROTO glue(op_pshufw, SUFFIX) (void)
 {
     Reg r, *d, *s;
-    int order;
     d = (Reg *)((char *)env + PARAM1);
     s = (Reg *)((char *)env + PARAM2);
-    order = PARAM3;
-    r.W(0) = s->W(order & 3);
-    r.W(1) = s->W((order >> 2) & 3);
-    r.W(2) = s->W((order >> 4) & 3);
-    r.W(3) = s->W((order >> 6) & 3);
+    helper_pshufw(&r, s, PARAM3);
     *d = r;
 }
 #else
--- qemu-0.9.0/target-i386/helper2.c.gcc4       2007-04-20 14:49:44.000000000 
+0000
+++ qemu-0.9.0/target-i386/helper2.c    2007-04-20 15:15:22.000000000 +0000
@@ -1038,3 +1038,11 @@ void save_native_fp_state(CPUState *env)
     env->native_fp_regs = 0;
 }
 #endif
+
+void helper_pshufw(MMXReg *dst, MMXReg *src, int order)
+{
+    dst->MMX_W(0) = src->MMX_W(order & 3);
+    dst->MMX_W(1) = src->MMX_W((order >> 2) & 3);
+    dst->MMX_W(2) = src->MMX_W((order >> 4) & 3);
+    dst->MMX_W(3) = src->MMX_W((order >> 6) & 3);
+}
--- qemu-0.9.0/dyngen-exec.h.gcc4       2007-04-20 14:49:44.000000000 +0000
+++ qemu-0.9.0/dyngen-exec.h    2007-04-20 14:54:50.000000000 +0000
@@ -279,4 +279,24 @@ extern int __op_jmp0, __op_jmp1, __op_jm
 #define EXIT_TB() asm volatile ("rts")
 #endif

+#if defined __i386__ || defined __x86_64__
+#define DEFINE_OP(NAME, ...)                                           \
+static void OPPROTO glue(impl_, NAME)(void) __attribute__((used));     \
+void OPPROTO glue(impl_, NAME)(void)                                   \
+{                                                                      \
+    asm volatile (".globl " ASM_NAME(NAME));                         \
+    asm volatile (".type " ASM_NAME(NAME) ", @function");          \
+    asm volatile (ASM_NAME(NAME) ":");                                       \
+    __VA_ARGS__;                                                       \
+    asm volatile ("ret");                                            \
+    asm volatile (".size " ASM_NAME(NAME) ", .-" ASM_NAME(NAME));  \
+}
+#else
+#define DEFINE_OP(NAME, ...)                   \
+void OPPROTO NAME(void)                                \
+{                                              \
+    __VA_ARGS__;                               \
+}
+#endif
+
 #endif /* !defined(__DYNGEN_EXEC_H__) */
--- qemu-0.9.0/cpu-all.h.gcc4   2007-04-20 14:49:44.000000000 +0000
+++ qemu-0.9.0/cpu-all.h        2007-04-20 14:58:38.000000000 +0000
@@ -339,7 +339,13 @@ static inline void stl_le_p(void *ptr, i

 static inline void stq_le_p(void *ptr, uint64_t v)
 {
+#if __GNUC__ < 4
     *(uint64_t *)ptr = v;
+#else
+    uint8_t *p = ptr;
+    stl_le_p(p, (uint32_t)v);
+    stl_le_p(p + 4, v >> 32);
+#endif
 }

 /* float access */
--- qemu-0.9.0/cpu-exec.c.gcc4  2007-04-20 15:43:06.000000000 +0000
+++ qemu-0.9.0/cpu-exec.c       2007-04-20 15:50:20.000000000 +0000
@@ -737,6 +737,18 @@ int cpu_exec(CPUState *env1)
             );
     }
 }
+#elif defined(__i386__) || defined(__x86_64__)
+               asm volatile ("call *%0"
+                             : /* no outputs */
+                             : "r" (gen_func)
+                             : AREG0, AREG1, AREG2, AREG3
+#ifdef AREG4
+                             , AREG4
+#endif
+#ifdef AREG5
+                             , AREG5
+#endif
+                             );
 #elif defined(__ia64)
                struct fptr {
                        void *ip;




reply via email to

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