gcc-3.3 problem with reloading byte into address register on ColdFire

Jim Wilson wilson@tuliptree.org
Mon Jul 7 06:18:00 GMT 2003


On Sun, 2003-07-06 at 22:09, Peter Barada wrote:
> According to the 68000 Programmers Reference Manual, move.b could use
> an address register as a source operand, bot not a destination
> operand.

I am looking at a Programmer's Reference Manual from 1992, which is 68k
plus cpu32.  It says that an address register is never a valid source
for a move.q.  This seems to match the gcc code, but it is possible that
my manual is in error.

> can use an address register as a target via the lea instruction.  I
> don't see how changing 'r' into 'd,a' will fix this issue since it
> still allows an address register to be selected.

Reload will see the d before the a, and hence will prefer a data
register over an address register.

You are right that this doesn't completely fix the problem, since we
could still end up with an ADDR_REG output reload.  It should be less
likely but could still appear.

My assumption here was that the compiler was working for m68k, but not
for Coldfire, in which case playing with the constraints to make
Coldfire work as well as the m68k might be a reasonable solution. 
Defining a secondary reload is a better solution.

> register to hold the address of the operand.  I don't see how
> reload_inqui or reload_outqi can suppress QImode moves to an address
> register.

Since the 68k movqi patterns allow moves from data regs to address regs,
but not loads, what you can do is allocate a data reg as a secondary
reload, emit the load into a data reg, and then move the data reg to the
address reg (which is implemented via a word sized move).  It isn't safe
to substitute a word-sized load from memory, because the address may not
be aligned, or could extend past the end of mapped memory if unaligned
loads are allowed (though I don't remember if any 68k allows this as an
option).

If you really want to get the QImode move done correctly, then what you
do is move the address reg to the data reg first, do the QImode load
into the register, and then move the value back to the address
register.  The same thing can be done for the reg to reg moves.  I think
this trick works on m68k, but if it doesn't, then you just allocate two
data register scratches, and do a bitfield insert to combine the two
values.  The old alpha port did this before the alpha architecture added
byte-loads, so you could look at that for an example, though I don't
think we need that generality for the m68k target.

> Perhaps the real fix is to put a predicate on moveqi that refuses to
> use an address register as the destination.  That might prevent
> reload from choosing an address register for its target.  Of course
> that can open up a whole 'nother can of worms :-)

This what secondary reloads are for.  The only thing reload can do is
emit a load to try to fix something, and if loads don't work then reload
can't do anything but abort.  If secondary reloads are defined, then if
a load doesn't work reload uses the secondary reload to make it work.

Jim




More information about the Gcc mailing list