uncomment the prints, and the function will return the
correct value.

it looks like the compiler is aliasing n and m, from 6c -S:

TEXT    log2ceil+0(SB),0,$16
        MOVQ    BP,SI
        MOVQ    BP,AX
        DECQ    ,AX
        MOVQ    BP,CX
        ANDQ    AX,CX
        CMPQ    CX,$0
        JEQ     ,3(PC)
        MOVL    $1,AX
        JMP     ,2(PC)
        MOVL    $0,AX
        MOVL    AX,BX
        MOVL    SI,DX
        JMP     ,2(PC)
        JMP     ,3(PC)
>>      CMPQ    SI,SI
        JNE     ,2(PC)
        JMP     ,5(PC)
        MOVQ    SI,AX
        SHRQ    $32,AX
        MOVL    AX,DX
        ADDL    $32,BX
[etc].

- erik

#include <u.h>
#include <libc.h>
typedef u64int  uintmem;

static  uchar   log2v[256];

void
log2init(void)
{
        int i;

        for(i=2; i<nelem(log2v); i++)
                log2v[i] = log2v[i/2] + 1;
}

/* ceil(logâ‚‚ m) */
int
log2ceil(uintmem m)
{
        uint n;
        int r;

        r = (m & (m-1)) != 0;   /* not a power of two => round up */
        n = (uint)m;
//print("%llux %ux\n", m, n);
        if(sizeof(uintmem)>sizeof(uint) && n != m){
                n = (u64int)m>>32;
                r += 32;
        }
//print("r = %d\n", r);
        if((n>>8) == 0)
                return log2v[n] + r;
        if((n>>16) == 0)
                return 8 + log2v[n>>8] + r;
        if((n>>24) == 0)
                return 16 + log2v[n>>16] + r;
        return 24 + log2v[n>>24] + r;
}

void
main(void)
{
        log2init();
        print("%d\n", log2ceil(0x430000000ull));
        exits("");
}


Reply via email to