Axel Zeuner wrote: > Hi, > Hi Axel, 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. The big problem (which pbrook helped me with) was GCC4 freaking out over some stq's. Splitting up the 64bit ops into 32bit ops seemed to address most of the problems. The tricky thing I still can't figure out is how to get ASM_SOFTMMU working. The problem is GLUE(st, SUFFIX) function. First GCC cannot deal with the register pressure. The problem I can't seem to fix though is that GCC sticks %1 in %esi because we're only using an "r" constraint, not a "q" constraint. This results in the generation of %sib which is an invalid register. However, refactoring the code to not require a "q" constraint doesn't seem to help either. The attached patch is what I have so far. Some help with people more familiar with gcc asm foo would be appreciated! Regards, Anthony Liguori > 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 > > ------------------------------------------------------------------------ > > _______________________________________________ > Qemu-devel mailing list > Qemu-devel@nongnu.org > http://lists.nongnu.org/mailman/listinfo/qemu-devel >