On 05/25/14 18:19, Matt Thomas wrote:
But even if movhi is a define_expand, as far as I can tell there's
isn't enough info to know whether that is possible. At that time,
how can I tell that operands[0] will be a hard reg or operands[1]
will be subreg of a mode dependent memory access?
At that time, you can't know those things. Not even close ;-) You
certainly don't want to try and rewrite the insn to just use SImode.
This is all an indication something has gone wrong elsewhere and this
would just paper over the problem.
I've tried using secondary_reload and it called called with
(subreg:HI (reg:SI 113 [ MEM[base: _154, offset: 0B] ]) 0)
but it dies in change_address_1 before invoking the code returned in
sri.
I suspect if you dig deep enough, you can make a secondary reload do
what you want. It's just amazingly painful.
You want to allocate an SImode temporary, do the load of the SI memory
location into that SImode temporary, then (subreg:SI (tempreg:SI)).
Your best bet is going to be to look at how some other ports handle
their secondary reloads. But I warn you, it's going to be painful.
I've tracked this down to reload replacing (reg:SI 113) with
reg_equiv_mem (133) in the rtx. However, it doesn't verify the rtx
is actually valid. I added a gcc_assert to trap this and got:
Right. reload will make that replacement and it's not going to do any
verification at that point. Verification would have happened earlier.
You have to look at the beginning of the main reload loop and poke at
that for a while:
/* For each pseudo register that has an equivalent location defined,
try to eliminate any eliminable registers (such as the frame
pointer)
assuming initial offsets for the replacement register, which
is the normal case.
If the resulting location is directly addressable, substitute
the MEM we just got directly for the old REG.
If it is not addressable but is a constant or the sum of a
hard reg
and constant, it is probably not addressable because the
constant is
out of range, in that case record the address; we will generate
hairy code to compute the address in a register each time it is
needed. Similarly if it is a hard register, but one that is not
valid as an address register.
If the location is not addressable, but does not have one of the
above forms, assign a stack slot. We have to do this to avoid the
potential of producing lots of reloads if, e.g., a location
involves
a pseudo that didn't get a hard register and has an equivalent
memory
location that also involves a pseudo that didn't get a hard
register.
Perhaps at some point we will improve reload_when_needed handling
so this problem goes away. But that's very hairy. */
Jeff