[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] qemu vs gcc4
From: |
Paul Brook |
Subject: |
Re: [Qemu-devel] qemu vs gcc4 |
Date: |
Tue, 31 Oct 2006 19:02:21 +0000 |
User-agent: |
KMail/1.9.5 |
On Tuesday 31 October 2006 16:53, Rob Landley wrote:
> On Monday 23 October 2006 2:37 pm, Paul Brook wrote:
> > > > Better to just teach qemu how to generate code.
> > > > In fact I've already done most of the infrastructure (and a fair
> > > > amount of the legwork) for this. The only major missing function is
> > > > code to do softmmu load/store ops.
> > > > https://nowt.dyndns.org/
>
> I looked at the big diff between that and mainline, and couldn't make heads
> nor tails of it in the half-hour I spent on it. I also looked at the svn
> history, but there's apparently a year and change of it.
>
> I don't suppose there's a design document somewhere? Or could you quickly
> explain "old one did this, new one does this, the code path diverges here,
> start reading at this point and expect this and this to happen, and if you
> go read this unrelated documentation to get up to speed it might help..."
Not really.
The basic principle is very similar. Host code is decomposed into an
intermediate form consisting of simple operations, then native code is
generated from those operations.
In the existing dyngen implementation most operands to ops are implicit, with
only a few ops taking explicit arguments. The principle with the new system
is that all operands are explicit.
The intermediate representation used by the code generator resembles an
imaginary machine. This machine has various different instructions (qops),
and a nominally infinite register file (qregs). Each qop takes zero or more
arguments, each of which may be an input or output.
In addition to dynamically allocated qregs there are a fixed set of qregs that
map onto the guest CPU state. This is to simplify code generation.
Each qreg has a particular type (32/64 bit, integer or float). It's up to you
ro make sure the argument types match those expected by th qop. It's
generally fairly obvious from the name. eg. add32 adds I32 values, addf64
adds F64 values, etc. The exception is that I64 values can be used in place
of I32. The upper 64-bit of outputs are undefined in this case, and teh value
must be explicitly extended before the full 64 bits are used.
The old dyngen ops are actually implemented as a special case qops.
As an example take the arm instruction
add, r0, r1, r2, lsl #2
This is equivalent to the C expression
r0 = r1 + (r2 << 2)
The old dyngen translate.c would do:
gen_op_movl_T1_r2()
gen_op_shll_T1_im(2)
gen_op_movl_T0_r1();
gen_op_addl(); /* does T0 = T0 + T1 */
gen_op_movl_r0_T0
When fully converted to the new system this would become:
int tmp = gen_new_qreg(); /* Allocate a temporary reg. */
/* gen_im32 is a helper that allocates a new qreg and
initializes it to an immediate value. */
gen_op_add32(tmp, QREG_R2, gen_im32(2));
gen_op_add32(QREG_R0, QREG_R1, tmp);
One of the changes I've made to target-arm/translate.c is to replace all uses
of T2 with new pseudo-regs. IN many cases I've left the code structure as it
was (using the global T0/T1 temporaries), but replaced the dyngen ops with
the equivalent qops. eg. movl and andl now generate mov32 and and32 qops.
The standard qops are defined in qops.def. A target can also define additional
qops in qop-target.def. The target specific qops are to simplify
implementation the i386 static flag propagation pass. the expand_op_*
routines.
For operations that are too complicated to be expressed as qops there is a
mechanism for calling helper functions. The m68k target uses this for
division and a couple of other things.
The implementation make fairly heavy use of the C preprocessor to generate
code from .def files. There's also a small shell script that pulls the
definiteions of the helper routines out of qop-helper.c
The debug dumps can be quite useful. In particular -d in_asm,op will dump the
input asm and the resulting OPs.
For converting targets you can probably ignore most of the translate-all and
host-*/ changes. These implement generating code from the qops. This works by
the host defining a set of "hard" qregs that correspond to host CPU
registers, and constraints for the operands of each qop. Then we do register
allocation and spilling to satisfy those constraints. The qops can then be
assembled directly into binary code.
There is also mechanisms for implementing floating point and 64-bit arithmetic
even if the target doesn't support this natively. The target code doesn't
need to worry about this, it just generates 64-bit/fp qops and they will be
decomposed as neccessary.
Paul
- Re: [Qemu-devel] qemu vs gcc4, (continued)
- Re: [Qemu-devel] qemu vs gcc4, K. Richard Pixley, 2006/10/23
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/23
- Re: [Qemu-devel] qemu vs gcc4, K. Richard Pixley, 2006/10/23
- Re: [Qemu-devel] qemu vs gcc4, Laurent Desnogues, 2006/10/23
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/23
- Re: [Qemu-devel] qemu vs gcc4, Rob Landley, 2006/10/24
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/24
- Re: [Qemu-devel] qemu vs gcc4, Rob Landley, 2006/10/25
- Re: [Qemu-devel] qemu vs gcc4, Daniel Jacobowitz, 2006/10/26
- Re: [Qemu-devel] qemu vs gcc4, Rob Landley, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4,
Paul Brook <=
- Re: [Qemu-devel] qemu vs gcc4, Rob Landley, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Laurent Desnogues, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Rob Landley, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Rob Landley, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Rob Landley, 2006/10/31
- Re: [Qemu-devel] qemu vs gcc4, Paul Brook, 2006/10/31