AW: AW: Issue with subregs
Henri Cloetens
henri.cloetens@blueice.be
Fri Jan 31 07:31:00 GMT 2020
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@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