Hi! This little patch turns bitwise.c's mask[] lookup table into a bit-twiddling macro (which avoids the <<32 case without branching). This spares the size of the 132-byte lookup table (and then a bit more, curiously). While I expected this to generally be faster (because it uses a few more instructions in place of a table lookup), it's actually slightly slower than the LUT, in a tight benchmark (perhaps because of the large chance of the LUT being in the dcache?), on an i32-athlon-classic at least. But other architectures may see some small benefit -- or this could be of academic interest to someone. :) It's been _V_BIT_TEST'd on i32, and I expect it to work on 64-bit archs but haven't been able to test. --Adam -------------- next part -------------- Index: .libs/libvorbisidec.a ==================================================================Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Index: bitwise.c ==================================================================--- bitwise.c (revision 3086) +++ bitwise.c (working copy) @@ -23,14 +23,8 @@ #include "misc.h" #include "ogg.h" -static unsigned long mask[]-{0x00000000,0x00000001,0x00000003,0x00000007,0x0000000f, - 0x0000001f,0x0000003f,0x0000007f,0x000000ff,0x000001ff, - 0x000003ff,0x000007ff,0x00000fff,0x00001fff,0x00003fff, - 0x00007fff,0x0000ffff,0x0001ffff,0x0003ffff,0x0007ffff, - 0x000fffff,0x001fffff,0x003fffff,0x007fffff,0x00ffffff, - 0x01ffffff,0x03ffffff,0x07ffffff,0x0fffffff,0x1fffffff, - 0x3fffffff,0x7fffffff,0xffffffff }; +#define MASK(b) ( (unsigned long)( (( (1<<((b)&31)) ^ (((b)&32)>>5) ) ) -1 ) \ + & 0xffffffff ) /* spans forward, skipping as many bytes as headend is negative; if headend is zero, simply finds next byte. If we're up to the end @@ -80,7 +74,7 @@ /* Read in bits without advancing the bitptr; bits <= 32 */ long oggpack_look(oggpack_buffer *b,int bits){ - unsigned long m=mask[bits]; + unsigned long m=MASK(bits); unsigned long ret; bits+=b->headbit; @@ -229,15 +223,15 @@ int tbit=bits?bits:ilog(b[i]); if((test=oggpack_look(&r,tbit))==0xffffffff) report("out of data!\n"); - if(test!=(b[i]&mask[tbit])){ - fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test); + if(test!=(b[i]&MASK(tbit))){ + fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&MASK(tbit)),test); report("looked at incorrect value!\n"); } if((test=oggpack_read(&r,tbit))==0xffffffff){ report("premature end of data when reading!\n"); } - if(test!=(b[i]&mask[tbit])){ - fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&mask[tbit]),test); + if(test!=(b[i]&MASK(tbit))){ + fprintf(stderr,"%ld) %lx %lx\n",i,(b[i]&MASK(tbit)),test); report("read incorrect value!\n"); } bitcount+=tbit; @@ -607,10 +601,10 @@ j-begin,ilen); exit(1); } - if(temp!=(values[j]&mask[len[j]])){ + if(temp!=(values[j]&MASK(len[j]))){ fprintf(stderr,"\nERROR: Incorrect read %lx != %lx, word %ld, len %d\n" , - values[j]&mask[len[j]],temp,j-begin,len[j]); + values[j]&MASK(len[j]),temp,j-begin,len[j]); exit(1); } bitcount+=len[j]; @@ -642,10 +636,10 @@ j-begin); exit(1); } - if(temp!=(values[j]&mask[len[j]])){ + if(temp!=(values[j]&MASK(len[j]))){ fprintf(stderr,"\nERROR: Incorrect look %lx != %lx, word %ld, len %d\n" , - values[j]&mask[len[j]],temp,j-begin,len[j]); + values[j]&MASK(len[j]),temp,j-begin,len[j]); exit(1); } oggpack_adv(&o,len[j]);