On Thu, 14 Mar 2024, Andrew Cooper via Gcc wrote:
> I suppose that what I'm looking for is something a little like
> __builtin_constant_p() which can either be used in a straight if(), or
> in a __builtin_choose_expr().
>
> Anyway - is there a way of doing this that I've managed to overlook?
I am missing what is lacking for you with __builtin_constant_p, I would
do it like this:
unsigned ffs(unsigned x)
{
unsigned res;
unsigned nonzero = x != 0;
if (__builtin_constant_p(nonzero) && nonzero)
asm("bsf %1, %0" : "=r"(res) : "rm"(x));
else {
res = -1;
asm("bsf %1, %0" : "+r"(res) : "rm"(x));
}
return res;
}
or with handling known-zero-input case like this:
unsigned ffs(unsigned x)
{
unsigned res;
unsigned nonzero = x != 0;
if (!__builtin_constant_p(nonzero)) {
res = -1;
asm("bsf %1, %0" : "+r"(res) : "rm"(x));
} else if (nonzero) {
asm("bsf %1, %0" : "=r"(res) : "rm"(x));
} else {
res = -1;
}
return res;
}
Does it work for you?
HTH
Alexander