> 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