AW: AW: AW: Issue with subregs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> On 01/30/2020 04:50 PM, Stefan Franke wrote:
> >
> >> -----Ursprüngliche Nachricht-----
> >> Von: gcc-help-owner@xxxxxxxxxxx <gcc-help-owner@xxxxxxxxxxx> Im
> >> Auftrag von Henri Cloetens
> >> Gesendet: Donnerstag, 30. Januar 2020 16:39
> >> An: gcc-help@xxxxxxxxxxx
> >> Betreff: Re: AW: Issue with subregs
> >>
> >> On 01/30/2020 11:57 AM, Stefan Franke wrote:
> >>>> -----Ursprüngliche Nachricht-----
> >>>> Von: gcc-help-owner@xxxxxxxxxxx <gcc-help-owner@xxxxxxxxxxx> Im
> >>>> Auftrag von Segher Boessenkool
> >>>> Gesendet: Donnerstag, 30. Januar 2020 11:48
> >>>> An: Henri Cloetens <henri.cloetens@xxxxxxxxxx>
> >>>> Cc: gcc-help@xxxxxxxxxxx
> >>>> Betreff: Re: Issue with subregs
> >>>>
> >>>> Hi!
> >>>>
> >>>> On Thu, Jan 30, 2020 at 11:19:18AM +0100, Henri Cloetens wrote:
> >>>>> - It is indeed true subreg only works on bytes.
> >>>>> - So, I changed the declaration:
> >>>>>     a. I declared all 12 condition code bits as BYTES (QI)
> >>>> That's not going to work.  The separate 3-bit fields are still at
> >>>> offsets
> >>> 0, 3, 6, 9
> >>>> bit.  You cannot use subregs to access them.
> >>>>
> >>>>>     b. I split it in 4 CC fields (cfr below), and declared each of
> >>>>> these as SI.
> >>>> Why not as CCmode?  That's what they are, after all.
> >>>>
> >>>>> - Then, the compare addresses the CC field in SI mode, the branch
> >>>>> in QI
> >>>>>     mode, and all goes well. I mean, it does not matter if I
> >>>>> declare SI or BI, because
> >>>>>     the compare instruction only writes 0 or 1, and the branch
> >>>>> instruction tests only
> >>>>>     for 0 or 1.
> >>>> Or do the compare insns only set single bits?  Not (e.g.) all of
> >>>> "less
> >>> than",
> >>>> "equal to", "greater than" at once?
> >>>>
> >>>>
> >>>> Segher
> >>> My approach was: group all bits which may change simultaneously into
> >>> one CC reg each
> >>>
> >>> This may result into one or more CC regs .
> >>> 	I got two of these
> >>>
> >>>
> >>> Create at least a mode for each CC reg for each used combination
> >>> 	I got two modes for the first CC reg: one to reflect eq/ne and one
> >>> mode for all other
> >>> 	And one mode for the second CC reg, which covers all conditions
> >>>
> >>> Then I coded the cbranch/cstore expands accordingly
> >>>
> >>> A CC reg is either used in a branch or sets  the boolean value 0/1
> >>> in a DI/SI/HI/QI register.
> >>>
> >>> You'll may do more work later, if you want to support insn resulting
> >>> by the combine pass, e.g. testing single bits...
> >>>
> >>> cheers
> >>>
> >>> Stefan
> >>>
> >>>
> >> Hello Stefan, Segher,
> >>
> >> - I still need to try Seghers suggestion. Let me first answer Stephan.
> >> Take following piece of C-code:
> >>
> >> int check_test(int a, int b, int c, int d) { _Bool check = (d == c) &
> >> (a > b) ;
> >> if(check)
> >>     {
> >>     b = a ;
> >>     }
> >> return(b) ;
> >> }
> >>
> >> - What I want, is that the compiler does following:
> >>     1. _Bool var1 = (d == c)
> >>     2. _Bool var2 = (a > b)
> >>     3. _Bool check = var1 & var2
> >>     if(check) then conditional branch ...
> >> - Now, the core has a condition code register,
> >>     does 1. and 2. with a compare instruction, 3 with a crand.
> >>     When I put the var1 and var2 in the condition register, this works !.
> >>     Well, there are still some bugs, but this is what it does :
> >>
> >> // The machine passes arguments in registers, a:R20, b: R21 and so on.
> >>           comparison internal signed %cf9 %r23 %r22  // (it writes 3
> >> flags. CF9 is less than, CF10 is greater, CF11 is equal
> >>           comparison internal signed %cf6 %r20 %r21  // writes CF6, CF7 and
> CF8
> >>           crand %cf9 %cf7 %cf11
> >>           novec_mybranch %cf9 1 .L2
> >>           addi %r20, %r21, 0
> >> .L2:
> >>           ret
> >> // return in register 20.
> >>
> >> Now, Stephan, how do you intend to do the boolean and, if you put the
> >> boolean variables in the SI (32-bit) register file of the machine ?.
> >> I mean, then you need to move the content of the CC reg to an R-reg,
> >> AND it, and move back from R-reg to CC-reg.  The other solution is 2
> branches ?.
> >>
> >> Best Regards,
> >>
> >> Henri.
> >>
> > Let's look at:
> >
> >   _Bool check = (d == c) & (a > b) ;
> >
> > This will do something like
> >
> >    cstoresi4(var1, ==, d, c)
> >    cstoresi4(var2, >, a, b)
> >    andsi3(check, var1, var2)
> >
> > So all variables are SImode then, the CCmode register is treated
> > inside of cstoresi4, which might emit two insns (or a combined one)
> >
> > (cstoresi4(var1, ==, d, c)
> > ->
> > (set (reg:CCmode CC_REG) (compare (reg:SImode d) (reg:SImode c))) (set
> > (reg:SImode var1) (match_eq [(reg:CCmode CC_REG) (const_int 0)]))
> >
> > So the compare sets the CCmode register and that is used to set the
> SImode register.
> >
> > Stefan
> >
> >
> -----Ursprüngliche Nachricht-----
> Von: Henri Cloetens <henri.cloetens@xxxxxxxxxx>
> Gesendet: Freitag, 31. Januar 2020 08:31
> An: Stefan Franke <stefan@xxxxxxxxx>; gcc-help@xxxxxxxxxxx
> Betreff: Re: AW: AW: Issue with subregs
> 
> Hello Frank,
> 
> > (set (reg:CCmode CC_REG) (compare (reg:SImode d) (reg:SImode c))) (set
> > (reg:SImode var1) (match_eq [(reg:CCmode CC_REG) (const_int 0)]))
> 
> Yes, and that is exactly what I DO NOT want. I want:
> 
> (set (reg:BImode var1) (compare (reg:SImode d) (reg:SImode c)))
> [var1 is BImode in the CCreg]
> 
> Then, the second operation is not necessary, the AND will be done on the
> CC-REG and not on the GP-REG, and there are 3 moves avoided:
> - The 2 moves from CC-REG to GP-REG [per your second statement]
> - The move from GP-REG to CC-REG to execute the branch.
> I got it working. It results, however, in non-standard usage of the SUBREG,
> and I got what looks like a compiler bug with that. I mean, a checking routine
> reports an error where I do not see one, I disabled it for the time being, will
> find out if it works like this or not.
> 
> Best Regards,
> 
> Henri.
> 
>

First: your version is missing how the compare is evaluated. How do you translate the different variants?

var1 = a == b;
var1 = a > b;
var1 = a <=b;
...

2nd: IMHO it's futile trying to obtain optimized code during the expand pass.

So good luck with your non-standard approach - I'm out.

Stefan






[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux