[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 

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 
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 

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.


More information about the Firm mailing list