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