This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Help with constraint for single register
On Mon, 27 Dec 2004 16:41:15 -0500, Robert Baruch <autophile@gmail.com> wrote:
> In this architecture, putting an address in the FSR register will
> cause the INDF register to be aliased to that address. That's the only
> way you can do indirect addressing on this processor. During the CSE
> phase, I had these insns. This sequence takes a value from the TMP
> register, and stores it into the location pointed to by pseudo-59,
> i.e. (P59) <- TMP:
>
> 2618: W <- pseudo-59
> 2619: clobber INDF
> 2620: FSR <- W
> 2621: use FSR
> 2622: W <- TMP
> 2623: INDF <- W
>
> However, during the GCSE phase, I get this:
>
> 2618: W <- pseudo-59
> 2619: clobber INDF
> 2620: FSR <- pseudo-59 ;; Not allowed -- not moved through W !!!
> 2621: use FSR
> 2622: W <- TMP
> 2623: INDF <- W
I've traced where this change occurs to the GCSE phase.
try_replace_reg (gcse.c:3876) is called when a potential replacement
is found, in this case replacing W in insn 2620 with pseudo-59.
Basically what happens in try_replace_reg is that the instruction is
changed, and the old instruction is saved. Then the change is
validated in apply_change_group (recog.c:318). That will determine if
the changed instruction is invalid, by calling insn_invalid_p
(recog.c:259). That, in turn, calls the generated recog function in
insn-recog.c... which only goes with the define_expand of movqi, and
does not call the expander's body code.
Since I defined the movqi expander to accept anything in general
(because the RTL generation phase needs a movqi pattern that accepts
anything), and to generate code in its body which uses W to do the
actual move, insn_invalid_p determines that the instruction is OK
(because it satisfies the generalized expander).
That's where the problem lies: the movqi expander must accept a move
from anywhere to anywhere (actually, from a general operand to a
nonimmediate operand) because of the RTL generation phase. However,
the instruction gets changed by try_replace_reg, and is accepted
because it is checked against the expander, which has to accept
everything. Since the change is accepted, the old form of the
instruction is deleted, and all hell breaks loose.
What am I doing wrong? It seems like there is a contradiction between
the purpose of an expander during RTL generation, and the purpose of
an expander during CSE...
Any advice?
Thanks!
--Rob