This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: gcc-3.3 problem with reloading byte into address register onColdFire


>Looking at a m68k manual, I see that no member of the m68k family
>supports QImode moves to/from address registers.  This isn't a Coldfire
>specific problem.  If you look at output_move_qimode, it always uses a
>word-sized (HImode) move if the source or destination is an address
>register.  So my initial analysis was wrong.

According to the 68000 Programmers Reference Manual, move.b could use
an address register as a source operand, bot not a destination
operand.  movea could only move words or longs, so there is no way
that a byte can be place into address register.  So an QImode can not
be placed into an address register, for either M68K, or ColdFire

>I also forgot that mov* patterns are special.  They always have to work,
>since they are want reload emits when it has an instruction that needs
>fixing.  So if we wanted to get around the problem of not having QImode
>moves, then we would need to use secondary reloads and a
>reload_{in,out}qi pattern to make this work.  However, we apparently do
>have QImode moves, so I need to look at this again.
>
>This appears to be a much more subtle problem than I originally
>thought.  I see that the Coldfire addsi3 pattern accepts "r" as a
>destination, whereas the non-Coldfire one accepts "d,a".  It looks like
>the a/T alternative was deleted for coldfire, and then the d and a
>destination alternatives were combined because they were identical. 
>However, this has the side effect of making a equally preferable to d,
>which it is not.  I suggest splitting r back into d,a and see if that
>helps.  That should cause us to prefer 'd' registers.  There may be
>other patterns that have similar problems that may also need to be
>fixed.

I'm a little leery of convering constraints when it is obvious the the
RTL in question is flat wrong.  Modifying the contstraints may suppress
the problem(for this testcase), but not fix it.  Besides, addsi is
perfecly valid to use 'r' as a constraint since the addsi pattern
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.

>There is also the choice of implementing secondary reloads and a
>reload_outqi pattern which should also work.

I've done his before to work around limitations of ColdFire floating
point instructions not being able to use Mode 7 (absolute addressing)
to access operands (source or destination) by using a scratch address
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.  If you could give me some insight(or an example of a
reload pattern that is used for this purpose), I'd be happy to code it
up and try it out.

In the meantime, I think I'll do some more debugging to see how if the
pattern doesn't allow a moveqi into an address register, and m68k.h
*really* doesn't allow QImode into an ADDR_REGS class that the code
decides to do it.  That information may indicate where the subtlety is
that is causing this bug.  For sure its has to be with dealing with
constructs such as converting: 

(insn 131 130 134 5 0x4001f2c0 (set (subreg:SI (reg/v:QI 41) 0)
        (plus:SI (subreg:SI (reg/v:QI 41) 0)
            (const_int 32 [0x20]))) 100 {*addsi3_5200} (nil)
    (nil))

into:

(insn 307 130 131 5 (nil) (set (reg:QI 8 %a0)
        (mem:QI (plus:SI (reg/f:SI 14 %a6)
                (const_int -255 [0xffffff01])) [0 mode S1 A8])) 37 {*m68k.md:1060} (nil)
    (nil))

(insn 131 307 308 5 0x4001f2c0 (set (reg:SI 8 %a0)
        (plus:SI (reg:SI 8 %a0)
            (const_int 32 [0x20]))) 100 {*addsi3_5200} (nil)
    (nil))


Where gcc is making the assumption that since the addsi pattern can use an
address register for SImode, then there's a load can load a QImode
into the address reigster that is the input/ouptut operand of the addsi.

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

-- 
Peter Barada
peter@baradas.org


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]