On my target, the multiplication can involve all general purpose registers,
but there's are still some restrictions: the first and the second operand as
well as the result must be in different registers, and neither register can
be gr7. How can I enforce this restriction on the register allocator?
- Volodya
Vladimir Prus wrote:
On my target, the multiplication can involve all general purpose registers,
but there's are still some restrictions: the first and the second operand
as well as the result must be in different registers, and neither register
can be gr7. How can I enforce this restriction on the register allocator?
And the other side of the question is now to inform register allocator that
mul instruction clobbers gr7? I see some support for getting "implicit
operands" in MachineInstr.cpp, but the only method which can set them:
MachineInstr::SetRegForImplicitRef
is marked as SPARC-specific and is not documented.
- Volodya
In the entry for that instruction in your .td file, just set the 'Defs'
value to gr7. something like this:
let Defs = [GR7] in
def YOURMUL ...
There is also an implicit uses value "Uses" which you should also fill in
all of the implicit uses of instructions. The X86 backend uses a little
"Imp" helper class, defined like this:
class Imp<list<Register> uses, list<Register> defs> {
list<Register> Uses = uses;
list<Register> Defs = defs;
}
Which allows instructions to do this more tersely:
e.g.
def LEAVE : I<"leave", 0xC9, RawFrm>, Imp<[EBP,ESP],[EBP,ESP]>;
def REP_MOVSB : I<"rep movsb", 0xA4, RawFrm>, REP,
Imp<[ECX,EDI,ESI], [ECX,EDI,ESI]>;
def MUL32m : Im32<"mul", 0xF7, MRM4m>, Imp<[EAX],[EAX,EDX]>;
The X86 is big on implicit uses and definitions 
-Chris
This is a good question, one that I don't have a great answer for. In
order to just get things working for you in the short term, you can just
force the operands into specific physical registers, by outputting a
template like this:
gr5 = reg1024
gr6 = reg1025
gr4 = mul gr5, gr6
reg1026 = gr4
This is obviously not going to generate wonderful code over the long term,
but should work.
In the longer term, we need to increase the expressivity of the register
classes a bit. In particular we need to be able to support nested
register classes (important on the X86), be able to specify aliasing more
precisely, and be able to handle other strange constraints like you ran
into here.
I imagine that you are more interested in getting things working than
tuning the generated code at this point, but if you get interested in
working on this, please bring it back up 
-Chris