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