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("");
}