[Firm] Queries about writing a backend
Christoph Mallon
mallon at cs.uni-saarland.de
Sat Jul 11 15:01:53 CEST 2015
Hi David,
Am 11.07.15 14:16, schrieb David Given:
> I hadn't though of rewriting the instructions later. That makes a lot of
> sense.
Maybe you can even handle this in the emitter.
E.g. something like emit => 'add %DS0, %S1',
And implement '%DSx' to emit destination and source operand x if the
registers differ ("add r0, r1, r2") and only one of them, if they are
equal ("add r0, r2").
See ia32_emitf() in ia32_emitter.c.
> As an alternative, is there any way to tell the compiler what registers
> cost? That the compiler looks pretty keen on reusing registers anyway,
> so it may be possible to simply tell it that r0-15 are cheaper than
> r16-r31 and then just let the 2op instructions appear by chance. That
> would be a whole lot easier and probably just as good.
Currently there is no mechanism to make registers preferable over other
registers.
Maybe there is some implicit bias towards earlier mentioned registers in
the list of registers.
That's the reason why eax is not the first register in the list in
ia32_spec.pl.
Many years ago it caused worse code if eax was used first.
Maybe we should reinvestigate this issue.
> Incidentally, doing some experimentation, I tried this:
>
> Add => {
> template => $binop,
> emit => '%D0 = add %S0, %S1',
> out_reqs => ['in_r0']
> },
>
> ...but it will quite happily put D0 in a different register to S0. What
> does 'in_r0' mean here?
First, for some hysterical raisins, in_rX is 1-based rather than zero based.
So you probably want in_r1 there.
Though it is a bug, that 'in_r0' silently does nothing.
It should cause an error.
It's a should_be_same requirement.
I.e. the register allocator will try to give this output the same
register as the given input (again: 1-based!).
But if that fails, then some later phase has to clean up the mess.
In your case, no cleanup is needed, because you also have 3-address
variants of your instructions.
For ia32 this correction is done in ia32_finish_irg_walker() in
ia32_finish.c.
For 'add' you probably even want 'in_r1 in_r2' and then swap the
operands, if the destination got the same register as the right operand.
See assure_should_be_same_requirements() in ia32_finish.c.
Christoph
More information about the Firm
mailing list