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

Reply via email to