Re: AW: AW: Issue with subregs

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

 



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.


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






[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