AW: AW: Issue with subregs

Stefan Franke stefan@franke.ms
Thu Jan 30 15:50:00 GMT 2020



> -----Ursprüngliche Nachricht-----
> Von: gcc-help-owner@gcc.gnu.org <gcc-help-owner@gcc.gnu.org> Im
> Auftrag von Henri Cloetens
> Gesendet: Donnerstag, 30. Januar 2020 16:39
> An: gcc-help@gcc.gnu.org
> Betreff: Re: AW: Issue with subregs
> 
> On 01/30/2020 11:57 AM, Stefan Franke wrote:
> >
> >> -----Ursprüngliche Nachricht-----
> >> Von: gcc-help-owner@gcc.gnu.org <gcc-help-owner@gcc.gnu.org> Im
> >> Auftrag von Segher Boessenkool
> >> Gesendet: Donnerstag, 30. Januar 2020 11:48
> >> An: Henri Cloetens <henri.cloetens@blueice.be>
> >> Cc: gcc-help@gcc.gnu.org
> >> 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



More information about the Gcc-help mailing list