Andrew Stubbs schrieb:
Hi all,
I have an architecture that has two register files. Let's call them
class A and class B. There are some differences between their
capabilities, but for the purposes of this problem, they can be
considered to be identical, both holding SImode values, and both able to
receive values without a secondary reload.
In order to load data into A, the address register must also be in A.
Similarly, in order to load data into B, the address register must also
be in B.
So I set up my (simplified) pattern:
(set (match_operand:SI "register_operand" "=a,b")
(match_operand:SI "memory_operand" "Ra,Rb"))
where
"a" is a register in A
"b" is a register in B
"Ra" is a mem with base address in A
"Rb" is a mem with base address in B
(Obviously, there are stores and moves and whatnot too, but you get the
idea.)
1) You must not have more than 1 mov insn per mode.
2) You must handle any (reg, mem) x (reg, mem, constant) operand
combination (constants in pools are handled separately).
The problem is that the register allocator cannot see inside Ra and Rb
to know that it must allocate the base register correctly. It only knows
that, some of the time, the instruction "does not satisfy its constraints".
Dis you try secondary reload?
I believe the register allocator relies on base_reg_class to choose a
class for the base register, but that just says "AB" (the union of class
A and class B), because it has no context to say otherwise. Only the
constraints define what hard registers are acceptable, and all they see
is pseudoregs during reload.
Similarly for the other hooks I've investigated: they don't have enough
context to know what's going on, and the rtx given always has pseudo
registers anyway.
This might even be the case with secondary reloads. Sometimes you
just get "regclass is GENERAL_REGS" ... great.
The only solutions I can think of are to either preallocate the loads to
register classes via some means MODE_CODE_BASE_REG_CLASS can see
(address spaces, perhaps), or to have an alternative that catches the
mismatching cases and splits to a load and move, or set the base class
to A and always load via secondary reload for B.
I don't see how address spaces could work. Who would set the address
spaces of all types and decls? You don't even have enough information
to set the address space (no reg classes, just types and trees).
Dedicated machine mode is also no solution. You'd just waste time
duplication all SI pattern to also, say, PSI of same mode precision,
but you still have to handle the complete cross product in the mov
insns. Maybe could could deny specific modes to go into specific
reg classes, but even if that works the resulting code will be sub
optimal and you then need secondary reloads for reg-reg moves.
And the problem of who shall decide which mode to use is still there.
Johann
Any suggestions would be greatly appreciated.
Andrew