/* SuperCollider real time audio synthesis system Copyright (c) 2002 James McCartney. All rights reserved. http://www.audiosynth.com This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* count leading zeroes function and those that can be derived from it */ #ifndef _CLZ_ #define _CLZ_ #include "SC_Types.h" #ifdef __MWERKS__ #define __PPC__ 1 #define __X86__ 0 // powerpc native count leading zeroes instruction: #define CLZ(x) ((int)__cntlzw((unsigned int)x)) #elif defined(SC_WIN32) && !defined(__GCC__) static int32 CLZ( int32 arg ) { __asm{ bsr eax, arg jnz non_zero mov arg, 32 jmp end non_zero: xor eax, 31 mov arg, eax end: } return arg; } #elif defined(__ppc__) || defined(__powerpc__) || defined(__PPC__) static __inline__ int32 CLZ(int32 arg) { __asm__ volatile("cntlzw %0, %1" : "=r" (arg) : "r" (arg)); return arg; } #elif defined(__i386__) || defined(__x86_64__) static __inline__ int32 CLZ(int32 arg) { if (arg) { __asm__ volatile("bsrl %0, %0\nxorl $31, %0\n" : "=r" (arg) : "0" (arg)); } else { arg = 32; } return arg; } #else # error "clz.h: Unsupported architecture" #endif // count trailing zeroes inline int32 CTZ(int32 x) { return 32 - CLZ(~x & (x-1)); } // count leading ones inline int32 CLO(int32 x) { return CLZ(~x); } // count trailing ones inline int32 CTO(int32 x) { return 32 - CLZ(x & (~x-1)); } // number of bits required to represent x. inline int32 NUMBITS(int32 x) { return 32 - CLZ(x); } // log2 of the next power of two greater than or equal to x. inline int32 LOG2CEIL(int32 x) { return 32 - CLZ(x - 1); } // next power of two greater than or equal to x inline int32 NEXTPOWEROFTWO(int32 x) { return 1L << LOG2CEIL(x); } // is x a power of two inline bool ISPOWEROFTWO(int32 x) { return (x & (x-1)) == 0; } // input a series of counting integers, outputs a series of gray codes . inline int32 GRAYCODE(int32 x) { return x & (x>>1); } // find least significant bit inline int32 LSBit(int32 x) { return x & -x; } // find least significant bit position inline int32 LSBitPos(int32 x) { return CTZ(x & -x); } // find most significant bit position inline int32 MSBitPos(int32 x) { return 31 - CLZ(x); } // find most significant bit inline int32 MSBit(int32 x) { return 1L << MSBitPos(x); } // count number of one bits inline uint32 ONES(uint32 x) { uint32 t; x = x - ((x >> 1) & 0x55555555); t = ((x >> 2) & 0x33333333); x = (x & 0x33333333) + t; x = (x + (x >> 4)) & 0x0F0F0F0F; x = x + (x << 8); x = x + (x << 16); return x >> 24; } // count number of zero bits inline uint32 ZEROES(uint32 x) { return ONES(~x); } // reverse bits in a word inline uint32 BitReverse(uint32 x) { x = ((x & 0xAAAAAAAA) >> 1) | ((x & 0x55555555) << 1); x = ((x & 0xCCCCCCCC) >> 2) | ((x & 0x33333333) << 2); x = ((x & 0xF0F0F0F0) >> 4) | ((x & 0x0F0F0F0F) << 4); x = ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8); return (x >> 16) | (x << 16); } // barrel shifts inline uint32 RotateRight (uint32 x, uint32 s) { s = s & 31; return (x << (32-s)) | (x >> s); } inline uint32 RotateLeft (uint32 x, uint32 s) { s = s & 31; return (x >> (32-s)) | (x << s); } #endif