> -----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