[Top][All Lists]
[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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- qemu + gcc4 (Was: [Qemu-devel] [RFC/experimental patch] qemu (x86_64 on x86_64 -no-kqemu) compiles with gcc4 and works),
Gwenole Beauchesne <=