This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Unnesting of nested subreg expressions
Thank you for your answer!
Am Donnerstag, 21. April 2005 05:11 schrieb James E Wilson:
> Björn Haase wrote:
> > The mid-end seems not to be able to simplify nested subreg expressions.
> > I.e. it seems that there is no known transformation
> > (subreg:QI (subreg:HI (reg:SI xx) 0) 0)
>
> Nested subregs aren't valid. You should refrain from creating them.
OK, understood now. So it's up to the back-ends that they prevent that such
expression is ever emitted, both in define_expand and define_split.
> > (define_expand "xorhi3"
> > [(set (subreg:QI (match_operand:HI 0 "register_operand" "=r") 0)
> > (xor:QI (subreg:QI (match_operand:HI 1 "register_operand" "%0") 0)
> > (subreg:QI (match_operand:HI 2 "register_operand" "r")
> > 0))) (set (subreg:QI (match_dup 0) 1)
> > (xor:QI (subreg:QI (match_dup 1) 1)
> > (subreg:QI (match_dup 2) 1)))]
>
> If you have 16-bit registers, then I don't think there is any way to
> make this work as written. Intra-register high-part subregs aren't
> generally valid either. A high-part subreg is generally only valid when
> it is an entire-register of a multi-register value.
For AVR, we indeed have *only* 8 bit registers, so the template above works
quite well as long as operands[2] does not accidently happen to be a subreg
expression.
The best solution I am seeing now probably then is, to avoid using a
subreg-type template for generating the low- and high parts of operands[2]
but use special functions for generating the high- and low parts of
operands[2]. For this purpose, one probably would consider extending the
existing gen_highpart and gen_lowpart functions so that they are also able to
work on subreg input operands.
>
> You will have to use some other kind of rtl here, such as shift and
> masks, or zero_extract.
>
This might be true for >=16 bit targets. For AVR, the only difficulty I have
been experiencing with above expand-pattern is the case of subreg input
operands.
> > It seems that the cleanest solution would be to teach gcc how to unnest
> > subregs. Therefore my question: Is this possible and where would be the
> > place for doing this?
>
> Or you can fix your expander to stop creating nested subregs. That is
> proabably much simpler than trying to teach the rest of the compiler to
> accept them.
> You can't rely on the fact that any expanded rtl will get simplified, so
> if we allow nested subregs, then everyplace that handles them needs to
> accept them, and that means an awful lot of code will have to change.
>
OK understood.
> > BTW. I have stepped over a similar issue when using the gen_highpart and
> > gen_lowpart functions for splitters after reload.
>
> I can't comment without details.
>
> > are working on a label reference immediate operand. It seems that in
> > their present form gen_lowpart and gen_highpart should be used only in
> > DI-SI-mode splitters since then there is no danger that the DI mode
> > expression itself is a subreg of an even larger mode.
>
> Except that the DImode expression could be a paradoxical subreg of a
> smaller mode, in which case you might have similar problems.
So far, I now think that the solution of the issue would be to extend
gen_lowpart and gen_highpart so that they are able to handle also subreg
inputs and use them at all places that emmit RTL (i.e. expand and split).
Question is whether I should try to simultaneously implement support for the
case of paradoxial subregs as input operand, once I am working on the code?
(I had been hoping that, there is a possibility to implement the HI->QI and
SI->QI lowering by restricting the changes to the back-end's config
directory. But, ok, it seems that one would have to touch at least some of
the support functions ...)
Thank you again for your comment. Very important for a beginner to have such
support.
Yours,
Björn