--- /dev/null +++ /sys/src/9/port/logpow.c @@ -0,0 +1,41 @@ +/* + * log2 and pow2 routines. + */ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" + +/* + * these routines should be cheap enough that there will + * be no hesitation to use them. + * + * once 5c in-lines vlong ops, just use the vlong versions. + */ + +int +ispow2(uvlong uvl) +{ + return ISPOW2(uvl); +} + +static int +isulpow2(ulong ul) /* temporary speed hack */ +{ + return ISPOW2(ul); +} + +/* + * return exponent of smallest power of 2 ≥ n + */ +int +log2(ulong n) +{ + int i; + + i = BI2BY*BY2WD - 1 - clz(n); + if (n == 0 || !ISPOW2(n)) + i++; + return i; +} --- /sys/src/9/kw/archkw.c +++ /sys/src/9/kw/archkw.c @@ -227,27 +227,6 @@ praddrmap(void) praddrwin(&map->win[i], i); } -int -ispow2(uvlong ul) -{ - /* see Hacker's Delight if this isn't obvious */ - return (ul & (ul - 1)) == 0; -} - -/* - * return exponent of smallest power of 2 ≥ n - */ -int -log2(ulong n) -{ - int i; - - i = 31 - clz(n); - if (!ispow2(n) || n == 0) - i++; - return i; -} - void cacheinfo(int level, int kind, Memcache *cp) /* l1 only */ { --- /sys/src/9/kw/fns.h +++ /sys/src/9/kw/fns.h @@ -28,7 +28,6 @@ extern void cacheiinv(void); extern void cacheuwbinv(void); extern uintptr cankaddr(uintptr pa); extern void clockshutdown(void); -extern int clz(ulong); int cmpswap(long*, long, long); #define coherence barriers @@ -47,7 +46,6 @@ extern u32int dacget(void); extern void dacput(u32int); extern u32int farget(void); extern u32int fsrget(void); -extern int ispow2(uvlong); extern void l1cachesoff(void); extern void l1cacheson(void); extern void l2cachecfgoff(void); @@ -60,7 +58,6 @@ extern void l2cacheuwbinv(void); extern void l2cacheuwbinvse(void*, int); extern void l2cacheuwbse(void*, int); extern void lastresortprint(char *buf, long bp); -extern int log2(ulong); extern void mmuidmap(uintptr phys, int mbs); extern void mmuinvalidate(void); /* 'mmu' or 'tlb'? */ extern void mmuinvalidateaddr(u32int); /* 'mmu' or 'tlb'? */ --- /sys/src/9/kw/mkfile +++ /sys/src/9/kw/mkfile @@ -25,6 +25,7 @@ PORT=\ latin1.$O\ mul64fract.$O\ rebootcmd.$O\ + logpow.$O\ page.$O\ parse.$O\ pgrp.$O\ --- /sys/src/9/omap/archomap.c +++ /sys/src/9/omap/archomap.c @@ -347,27 +347,6 @@ archomaplink(void) { } -int -ispow2(uvlong ul) -{ - /* see Hacker's Delight if this isn't obvious */ - return (ul & (ul - 1)) == 0; -} - -/* - * return exponent of smallest power of 2 ≥ n - */ -int -log2(ulong n) -{ - int i; - - i = 31 - clz(n); - if (n == 0 || !ispow2(n)) - i++; - return i; -} - void archconfinit(void) { --- /sys/src/9/omap/fns.h +++ /sys/src/9/omap/fns.h @@ -25,7 +25,6 @@ extern void cacheuwbinv(void); extern uintptr cankaddr(uintptr pa); extern void chkmissing(void); extern void clockshutdown(void); -extern int clz(ulong); extern int cmpswap(long*, long, long); extern void coherence(void); extern void configscreengpio(void); @@ -54,13 +53,11 @@ extern u32int ifsrget(void); extern void intrsoff(void); extern int isaconfig(char*, int, ISAConf*); extern int isdmadone(int); -extern int ispow2(uvlong); extern void kbdenable(void); extern void l2cacheuinv(void); extern void l2cacheuwb(void); extern void l2cacheuwbinv(void); extern void lastresortprint(char *buf, long bp); -extern int log2(ulong); extern void machinit(void); extern void mmuidmap(uintptr phys, int mbs); extern void mmuinvalidate(void); /* 'mmu' or 'tlb'? */ --- /sys/src/9/omap/mkfile +++ /sys/src/9/omap/mkfile @@ -25,6 +25,7 @@ PORT=\ latin1.$O\ mul64fract.$O\ rebootcmd.$O\ + logpow.$O\ page.$O\ parse.$O\ pgrp.$O\ --- /sys/src/9/pc/devarch.c +++ /sys/src/9/pc/devarch.c @@ -51,6 +51,8 @@ enum { /* cpuid standard function codes */ typedef long Rdwrfn(Chan*, void*, long, vlong); +int bsr(ulong n); /* l.s */ + static Rdwrfn *readfn[Qmax]; static Rdwrfn *writefn[Qmax]; @@ -1260,3 +1262,11 @@ timerset(Tval x) if(doi8253set) (*arch->timerset)(x); } + +int +clz(ulong n) /* count leading zeroes */ +{ + if (n == 0) + return BI2BY*BY2WD; + return BI2BY*BY2WD - 1 - bsr(n); +} --- /sys/src/9/pc/l.s +++ /sys/src/9/pc/l.s @@ -878,6 +878,13 @@ TEXT islo(SB), $0 RET /* + * Miscellany + */ +TEXT bsr(SB), $0 + BSRL word+0(FP), AX /* return bit index of leftmost 1 bit */ + RET + +/* * Test-And-Set */ TEXT tas(SB), $0 --- /sys/src/9/pc/mkfile +++ /sys/src/9/pc/mkfile @@ -29,6 +29,7 @@ PORT=\ edf.$O\ fault.$O\ latin1.$O\ + logpow.$O\ page.$O\ parse.$O\ pgrp.$O\ --- /sys/src/9/pc/mtrr.c +++ /sys/src/9/pc/mtrr.c @@ -131,12 +131,6 @@ sanity(Mtrreg *mtrr) mtrr->mask &= Paerange - 1; } -static int -ispow2(uvlong ul) -{ - return (ul & (ul - 1)) == 0; -} - /* true if mtrr is valid */ static int mtrrdec(Mtrreg *mtrr, uvlong *ptr, uvlong *size, int *type) --- /sys/src/9/pcboot/bootmkfile +++ /sys/src/9/pcboot/bootmkfile @@ -19,6 +19,7 @@ PORT=\ dev.$O\ edf.$O\ latin1.$O\ + logpow.$O\ page.$O\ parse.$O\ pgrp.$O\ --- /sys/src/9/pcboot/l32v.s +++ /sys/src/9/pcboot/l32v.s @@ -540,6 +540,13 @@ TEXT islo(SB), $0 RET /* + * Miscellany + */ +TEXT bsr(SB), $0 + BSRL word+0(FP), AX /* count leading zeros */ + RET + +/* * basic timing loop to determine CPU frequency */ TEXT aamloop(SB),$0 --- /sys/src/9/port/portfns.h +++ /sys/src/9/port/portfns.h @@ -38,6 +38,7 @@ void closefgrp(Fgrp*); void closepgrp(Pgrp*); void closergrp(Rgrp*); long clrfpintr(void); +int clz(ulong); void cmderror(Cmdbuf*, char*); int cmount(Chan**, Chan*, int, char*); void confinit(void); @@ -146,6 +146,8 @@ int islo(void); Segment* isoverlap(Proc*, ulong, int); int ispages(void*); int isphysseg(char*); +#define ISPOW2(i) (((i) & ((i) - 1)) == 0) /* see Hacker's Delight */ +int ispow2(uvlong); void ixsummary(void); int kbdcr2nl(Queue*, int); int kbdgetmap(uint, int*, int*, Rune*); @@ -163,6 +165,7 @@ ulong l2be(long); long latin1(Rune*, int); int lock(Lock*); void logopen(Log*); +int log2(ulong); void logclose(Log*); char* logctl(Log*, int, char**, Logflag*); void logn(Log*, int, void*, int); --- a/sys/src/9/teg2/fns.h +++ b/sys/src/9/teg2/fns.h @@ -33,7 +33,6 @@ extern uintptr cankaddr(uintptr pa); extern void chkmissing(void); extern void clockprod(Ureg *); extern void clockshutdown(void); -extern int clz(ulong); extern int cmpswap(long*, long, long); extern void coherence(void); extern void configscreengpio(void); @@ -79,11 +78,9 @@ extern void intrshutdown(void); extern void intrsoff(void); extern int isaconfig(char*, int, ISAConf*); extern int isdmadone(int); -extern int ispow2(uvlong); extern void kbdenable(void); extern void l1diag(void); extern void l2pl310init(void); -extern int log2(ulong); extern void machoff(uint cpu); extern void machon(uint cpu); extern void memdiag(ulong *); --- /sys/src/9/teg2/mkfile +++ /sys/src/9/teg2/mkfile @@ -26,6 +26,7 @@ PORT=\ latin1.$O\ mul64fract.$O\ rebootcmd.$O\ + logpow.$O\ page.$O\ parse.$O\ pgrp.$O\ --- /sys/src/9/teg2/ts +++ /sys/src/9/teg2/ts @@ -57,7 +57,6 @@ misc pci rdb coproc - v7-arch caches caches-v7 cache-l2-pl310 --- /sys/src/9/teg2/v7-arch.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * arm arch v7 routines other than cache-related ones. - * - * calling this arch-v7.c would confuse the mk scripts, - * to which a filename arch*.c is magic. - */ -#include "u.h" -#include "../port/lib.h" -#include "mem.h" -#include "dat.h" -#include "fns.h" -#include "../port/error.h" -#include "io.h" -#include "arm.h" - -/* - * these routines should be cheap enough that there will - * be no hesitation to use them. - * - * once 5c in-lines vlong ops, just use the vlong versions. - */ - -/* see Hacker's Delight if this isn't obvious */ -#define ISPOW2(i) (((i) & ((i) - 1)) == 0) - -int -ispow2(uvlong uvl) -{ - /* see Hacker's Delight if this isn't obvious */ - return ISPOW2(uvl); -} - -static int -isulpow2(ulong ul) /* temporary speed hack */ -{ - return ISPOW2(ul); -} - -/* - * return exponent of smallest power of 2 ≥ n - */ -int -log2(ulong n) -{ - int i; - - i = BI2BY*BY2WD - 1 - clz(n); - if (n == 0 || !ISPOW2(n)) - i++; - return i; -}