qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RESEND] TCG breakage if TARGET_LONG_BITS > HOST_LONG_BITS


From: Alexander Graf
Subject: [Qemu-devel] [RESEND] TCG breakage if TARGET_LONG_BITS > HOST_LONG_BITS
Date: Tue, 12 Feb 2008 12:33:49 +0100

This is a resend of a mail I sent to the list on 2008/02/06. I felt it rather disturbing, yet normal that nobody cared about Mac OS X host support, but this concerns all x86 host OSs, so I believe this deserves some discussion.

Hi,

I've been trying to get the new TCG approach running on an i386 host. It works when I use gcc3 (miraculously as I will explain later), but fails on gcc4.

On boot the very first instruction that gets issued is the ljmp to the bios:

IN:
0x00000000fffffff0:  ljmp   $0xf000,$0xe05b

This translates to

OP:
movi_i32 T0_0,$0xf000
movi_i32 T0_1,$0x0
movi_i32 T1_0,$0xe05b
movi_i32 T1_1,$0x0
[...]

and results in

OUT: [size=83]
0x08e38f40:  mov    $0xf000,%eax
0x08e38f45:  xor    %edx,%edx
0x08e38f47:  mov    $0xe05b,%ecx
0x08e38f4c:  xor    %ebx,%ebx
[...]

This is perfectly fine if you assume, that these registers get clobbered and save/restore them or define them as global register variables. Unfortunately on TARGET_LONG_BITS==64 this does not happen, as T0 and T1 are supposed to be in memory, not in registers.

As can be seen in the gcc4 generated assembly, gcc thinks that ebx is just fine after the function call:

0x80e1449 <cpu_x86_exec+1545>:  mov    %ebp,%ebx
0x80e144b <cpu_x86_exec+1547>:  mov    %esi,0x510(%ebp)
0x80e1451 <cpu_x86_exec+1553>:  call   *%eax
0x80e1453 <cpu_x86_exec+1555>:  mov    %eax,%edx
0x80e1455 <cpu_x86_exec+1557>:  sar    $0x1f,%edx
0x80e1458 <cpu_x86_exec+1560>:  mov    %eax,(%ebx)

and qemu segfaults here.

So basically there are two things puzzling me here.

1. Why is gcc3 generating code, that does not use ebx?
2. Why does movi_i64 generate code that only accesses registers? I have not been able to find any branch in the tcg code generator for movi_ixx that generates movs to memory addresses.

The whole issue could be easily fixed by using registers, but putting the call into inline assembly, telling gcc that this call clobbers all the registers. I do not know if this is the expected behavior though, so I think I'd rather ask before doing any patches.

I hope this helps,

Alex





reply via email to

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