> ccpm and carrybit are probably ints or unsigned ints,
> because of the L and N instructions, which read them.
> The final STC moves the rightmost 8 bits to the bool variable;
> bool (no C standard type) is probably a typedef which means char.

> I hope, I understood the coding correctly.
Indeed.  The full code, which I omitted to keep the focus, is:

    __uint32_t ccpm;
    const __uint32_t carrybit = 0x20000000;
    __uint32_t sum = u32a;
    asm("alr %[r1],%[r2] \n\t"
        "ipm %[r3]"
        : [r1] "+r" (sum),    // output
          [r3] "=r" (ccpm)
        : [r2] "r"  (u32b)    // input
        :                    // clobbers
       );
    bool overflow = (ccpm & carrybit) != 0;    // check if carry bit set

bool is defined in stdbool.h as an alias for _Bool (a standard type, I believe, 
since since C99).  


I had to check up how LCR behaved with x80...0, and the answer (viz, leave it 
alone and set the overflow bit) somewhat surprised me.
It's certainly a mighty clever piece of code, one that I've not seen before.  
It brings up in my mind the question what exactly is the cost of a branch?  How 
many instructions can I use before they before more expensive than the branch 
they replace?

Best wishes / Mejores deseos /  Meilleurs vœux

Ian ... 

    On Wednesday, April 20, 2022, 01:00:03 AM GMT+2, Bernd Oppolzer 
<[email protected]> wrote:  
 
 ccpm and carrybit are probably ints or unsigned ints,
because of the L and N instructions, which read them.

so, the & (bitwise AND) operation yields a nonzero result, if there is a 
one bit
in the same bit position in both operands. This nonzero result must be 
transferred
to a one byte value X'01', using some clever register operations.

And: yes, IMO the coding here tries to avoid branches and compares.

The solution LPR ... LCR ... SRL looks OK for me.
LPR keeps a nonzero result, but with a positive sign,
LCR does the same, but enforces a negative sign,
and SRL moves the sign to the rightmost bit position.

In contrast, a zero result of the N operation would stay zero
throughout the LPR / LCR sequence, and the SRL would move
a zero bit in the rightmost bit position.

The final STC moves the rightmost 8 bits to the bool variable;
bool (no C standard type) is probably a typedef which means char.

I hope, I understood the coding correctly.

Kind regards

Bernd



Am 19.04.2022 um 15:06 schrieb Ian Worthington:
> Noticed today that the GCC C compiler generated an unexpected sequence of 
> instructions for an AND and TEST:
>
> ****     bool overflow = (ccpm & carrybit) != 0;    // check if carry bit set
>   109                      .loc 1 189 0
>   110 0078 5810B25C         l    %r1,604(%r11)    # D.7949, ccpm
>   111 007c 5410B26C         n    %r1,620(%r11)    # D.7949, carrybit
>   112 0080 1011             lpr    %r1,%r1    # tmp54, D.7949
>   113 0082 1311             lcr    %r1,%r1    # tmp55, tmp54
>   114 0084 8810001F         srl    %r1,31    # tmp56,
>   115 0088 4210B25B         stc    %r1,603(%r11)    # tmp56, overflow
>
> I can only guess this is to avoid the cost of a branch?  Or is there some 
> other advantage in this?
>
>
> Best wishes / Mejores deseos /  Meilleurs vœux
>
> Ian ...
  

Reply via email to