qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC/experimental patch] qemu (x86_64 on x86_64 -no-kqemu)


From: Axel Zeuner
Subject: [Qemu-devel] [RFC/experimental patch] qemu (x86_64 on x86_64 -no-kqemu) compiles with gcc4 and works
Date: Sat, 24 Mar 2007 18:50:02 +0100
User-agent: KMail/1.9.5

Hi,

there were a lot of discussions about compiling qemu with gcc4 or higher. The 
summary of the discussions were, as I understood, that compiling qemu with 
gcc4 requires changing the code generation engine of the most of the 
supported targets. These changes require a lot of work and time.

How about splitting the current static code generation process further? 
Today gcc produces object code and dyngen adapts it for the purposes of qemu, 
i.e produces the generation function, patches in parameters ..:
gcc -c op.o op.c ;dyngen -o op.h ... op.o . 
The op_XXX functions generated by gcc may not contain more than one exit
and this exit must be at the end, no not intended jumps to external
functions may occur.

It is possible to split the transformation into the following steps: 
Generate assembly output from the C-Sources: gcc -S -o op-0.s op.c.
Convert the assembly output: cvtasm op.s op-0.s. 
Assemble the converted assembler sources: as -o op.o op.s. 
Use dyngen as before: dyngen -o op.h ... op.o. 
Nothing will change if cvtasm copies only the input to the output, i.e. this 
additional pass will not break existing code.

A full featured converter (cvtasm) has a lot of dependencies: it has to 
support all hosts (M) (with all assembler dialects M') and all targets N, 
i.e. in the worst case one would end with M'x N variants of it, or M x N if 
one supports only one assembler dialect per host.  It is clear, that the 
number of variants is one of the biggest disadvantages of such an approach.

Now I will focus on x86_64 host and x86_64-softmmu target.
cvtasm has to do the following tasks in this case:
0) convert repXXX; ret to ret only. (Not done yet, x86_64 only, but does not 
harm).
1) append to all functions, where the last instruction is not a return a ret 
instruction.
2) add a label to all functions with more than one return before the last  
return.
3) replace all returns not at the end of a function with an unconditional jump 
to the generated end label. Avoid touching op_exit_tb here.
4) check all jump instructions if they contain jumps to external labels,  
replace jumps to external labels with calls to the labels.

The task 0-2 are easy, task 3 may, task 4 is definitely target/host dependent, 
because there exist intentionally some jumps to external labels, i.e. outside 
of the function, for instance op_goto_tb. 
Please correct me, if I am wrong or something is not mentioned above. 

The attached cvtasm.c allows compiling op.c/op.s/op.o without any disabled 
optimisations in Makefile.target (patches for Makefile and Makefile.target are 
attached). The program itself definitely needs a rewrite, is not failsafe and 
produces to much output on stdout. 

The macro OP_GOTO_TB from exec-all.h in the general case contains two nice 
variables and label definitions to force a reference from a variable into the 
op_goto_tbXXX functions. Unfortunately gcc4 detects that these variables and 
lables are unused and suppresses their generation, as result dyngen does not 
generate two lines in op.h:
case INDEX_op_goto_tb0: 
        ...
        label_offsets[0] = 8 + (gen_code_ptr - gen_code_buf); // <--
        ...
case INDEX_op_goto_tb1: 
        ...
        label_offsets[1] = 8 + (gen_code_ptr - gen_code_buf); // <-- 
        ...
and qemu produces a SIGSEGV on the first jump from one buffer to the next.
I was not able to force gcc4 to generate the two variables, therefore I had to 
replace the general macro with a host dependent one for x86_64 similar to x86 
but using the indirect branch method. 
After the replacement qemu worked when compiled with gcc4.

I made my checks with the following compilers using Debian testing amd64: gcc 
version 3.4.6 (Debian 3.4.6-5) and gcc version 4.1.2 20061115 (prerelease) 
(Debian 4.1.1-21).

Please note: These patches work only for x86_64 hosts and x86_64 targets. They 
will break all other architectures. I did not check i386-softmmu. It works 
for me. 

I apologise for the size of the attachments.

Kind regards
Axel

Attachment: exec-all.h.diff.zip
Description: Zip archive

Attachment: Makefile.diff.zip
Description: Zip archive

Attachment: Makefile.target.diff.zip
Description: Zip archive

Attachment: cvtasm.c.zip
Description: Zip archive


reply via email to

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