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