Discussion:
bitshift intrinsics
(too old to reply)
Marco van de Voort
2016-10-14 09:44:06 UTC
Permalink
Raw Message
I revisited some old code and noticed there was a BSR using piece of
assembler there that used bsr as a cheap 2log for some buffer dimensioning.

When I tried to replace it with the intrinsic bsrdword, hoping making it
both inlinable and more portablw I noted that the intrinsic was exactly the
same as my code but returned 255 instead of -1 for "0".

Since this is a higher number than other values, it required another test to
avoid outrageous large buffers, resulting in asm code (-O4):

bsrl %eax,%eax
jne .Lj7
movl $255,%eax
.Lj7:
# Var $result located in register eax
# [6] if result=255 then result:=-1;
cmpl $255,%eax
jne .Lj9
movl $-1,%eax
.Lj9:


and then leal 2(%eax),%ebx to add two. Pretty hideous.

If the dword version returned $FFFFFFFF it could be at least typecasted to
-1.

So the questions are:
1. why do the primitives deliver a signed result ?
2. why do they not all deliver -1 for their with ($FFFF for 2-byte etc).
3. (for Michael: :-) why doesn't the documentation doesn't mention the
behaviour for no bits set?).

Since (3) the behaviour is not documented, we can still fix this ? :-)

The current choices (0..31 and 255) seem pointless.

_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Jonas Maebe
2016-10-14 09:56:23 UTC
Permalink
Raw Message
Post by Marco van de Voort
If the dword version returned $FFFFFFFF it could be at least typecasted to
-1.
You can typecast the result to shortint to get -1 in that case.
Post by Marco van de Voort
1. why do the primitives deliver a signed result ?
*unsigned
Post by Marco van de Voort
2. why do they not all deliver -1 for their with ($FFFF for 2-byte etc).
Probably because that is how the originally submitted generic
implementation behaved: http://bugs.freepascal.org/view.php?id=17592
Post by Marco van de Voort
3. (for Michael: :-) why doesn't the documentation doesn't mention the
behaviour for no bits set?).
Since (3) the behaviour is not documented, we can still fix this ? :-)
They've behaved like this since FPC 2.6.0, so no.


Jonas
_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Marco van de Voort
2016-10-14 12:25:44 UTC
Permalink
Raw Message
Post by Jonas Maebe
Post by Marco van de Voort
If the dword version returned $FFFFFFFF it could be at least typecasted to
-1.
You can typecast the result to shortint to get -1 in that case.
That removes the additional branch, reducing it to a movsbl, so I assume the
resulting code is better, thanks.
Post by Jonas Maebe
Post by Marco van de Voort
1. why do the primitives deliver a signed result ?
*unsigned
True, but question still stands. Anyway, I'll wait if FLorian recollects
anything.
Post by Jonas Maebe
Post by Marco van de Voort
3. (for Michael: :-) why doesn't the documentation doesn't mention the
behaviour for no bits set?).
Since (3) the behaviour is not documented, we can still fix this ? :-)
They've behaved like this since FPC 2.6.0, so no.
Looking at the generic (non cpu) version with the lookup table, the reason
for $ff becomes somewhat logical. It is bytewise, and $FF is the value of 0
in the per byte table.

Anyway, I just wanted to avoid floating point in the original case, and it
was not really extremely speeddependent. I just wondered.

I've filed a doc bug 30740 so that at least something good comes out of it.

_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
Florian Klämpfl
2016-10-14 20:29:41 UTC
Permalink
Raw Message
Post by Marco van de Voort
Post by Jonas Maebe
Post by Marco van de Voort
If the dword version returned $FFFFFFFF it could be at least typecasted to
-1.
You can typecast the result to shortint to get -1 in that case.
That removes the additional branch, reducing it to a movsbl, so I assume the
resulting code is better, thanks.
Post by Jonas Maebe
Post by Marco van de Voort
1. why do the primitives deliver a signed result ?
*unsigned
True, but question still stands. Anyway, I'll wait if FLorian recollects
anything.
I guess the reason was that no more than one byte is needed for the result of bs*. But I agree, the
decision was not very well thought.

_______________________________________________
fpc-devel maillist - fpc-***@lists.freepascal.org
http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Loading...