📄 math64.h
字号:
#ifdef TIMINGstatic unsigned int tick,tock ;inline void fTICK(){ register int t ; asm { mftb t } ; tick = t ; }inline void fTOCK(){ register int t ; asm { mftb t } ; tock = t ; if (tock < tick) { tock += 65536 ; tick -= 65536 ; }}#define TICK() fTICK()#define TOCK(nsamples) ( fTOCK() , printf("cycles = %4.1f\n",4.0f*(tock-tick)/(float)(nsamples)), \ tock-tick )#endif // TIMING#endif // defined(__MWERKS__) && defined(__POWERPC__)///////////////////////////////////////////////////////////////////////////////////////// GCC / PowerPC///////////////////////////////////////////////////////////////////////////////////////#if defined(__GNUC__) && (defined(__POWERPC__) || defined(__powerpc__))/*if your compiler can compile 64-bit instructions, and your CPU has them, define this. */// #define USE_64BIT_INSNS#define HAVE_PLATFORM_MACROS/* Compute a * b / c, using 64-bit intermediate result */static __inline__ int MulDiv64(int a, int b, int c){ int res ;#ifdef USE_64BIT_INSNS __asm__ volatile ("mulhd %0,%2,%3\n\t" "divd %0,%0,%1" : "=&r" (res) : "r" (c), "%r" (a), "r" (b) ) ;#else res = (int)(((double)a*(double)b - (double)(c>>1)) / (double)c) ;#endif return res ;}/* Compute (a * b) >> 32, using 64-bit intermediate result */static __inline__ int MulShift32(int a, int b){ int res ; __asm__ ("mulhw %0,%1,%2" : "=r" (res) : "%r" (a) , "r" (b) ) ; return res ;}/* Compute (a * b) >> 30, using 64-bit intermediate result */static __inline__ int MulShift30(int a, int b){ int res ;#ifdef USE_64BIT_INSNS __asm__ ("mulhd %0,%1,%2\n\t" "srd %0,30" : "=r" (res) : "%r" (a), "r" (b) ) ;#else res = MulShift32(a,b) << 2 ;#endif return res ;}/* Compute (a * b) >> 31, using 64-bit intermediate result */static __inline__ int MulShift31(int a, int b){ int res ;#ifdef USE_64BIT_INSNS __asm__ ("mulhd %0,%1,%2\n\t" "srd %0,31" : "=r" (res) : "%r" (a), "r" (b) ) ;#else res = MulShift32(a,b) << 1 ;#endif return res ;}/* Compute (a * b) >> n, using 64-bit intermediate result */static __inline__ int MulShiftN(int a, int b, int n){ int res ;#ifdef USE_64BIT_INSNS __asm__ ("mulhd %0,%1,%2\n\t" "srd %0,%3" : "=&r" (res) : "%r" (a), "r" (b), "r" (n) ) ;#else unsigned int temp ; __asm__ ("mullw %0,%1,%2" : "=r" (temp) : "%r" (a) , "r" (b) ) ; res = temp >> n ; __asm__ ("mulhw %0,%1,%2" : "=r" (temp) : "%r" (a) , "r" (b) ) ; res |= (temp << (32-n)) ;#endif return res ;}#ifdef TIMINGstatic unsigned int tick,tock ;inline void fTICK(){ register int t ; __asm__ ( "mftb %0" : "=r" (t) ) ; tick = t ; }inline void fTOCK(){ register int t ; __asm__ ( "mftb %0" : "=r" (t) ) ; tock = t ; if (tock < tick) { tock += 65536 ; tick -= 65536 ; }}#define TICK() fTICK()#define TOCK(nsamples) ( fTOCK() , printf("cycles = %4.1f\n",4.0f*(tock-tick)/(float)(nsamples)), \ tock-tick )#endif // TIMING#endif // defined(__GNUC__) && defined(__POWERPC__)///////////////////////////////////////////////////////////////////////////////////////// EVC3.0 / ARM///////////////////////////////////////////////////////////////////////////////////////#if (defined(_ARM) && defined(_MSC_VER))/* EVC does not allow us to use inline assembly. Thus, you'll only see prototypes here. */#define HAVE_PLATFORM_MACROS/* Compute a * b / c, using 64-bit intermediate result. Since the ARM does not have a division instruction, we code a totally lame C version here. TODO wschildbach */static __inline int MulDiv64(int a, int b, int c){ __int64 t = (__int64)a * (__int64)b ; return (int)(t / c) ;}/* Compute (a * b) >> 31, using 64-bit intermediate result */#ifdef __cplusplusextern "C" {#endif // __cplusplusint MulShift32(int a, int b);/* Compute (a * b) >> 31, using 64-bit intermediate result */int MulShift31(int a, int b);/* Compute (a * b) >> 31, using 64-bit intermediate result */int MulShift30(int a, int b);/* Compute (a * b) >> n, using 64-bit intermediate result */int MulShiftN(int a, int b, int n);#ifdef __cplusplus}#endif // __cplusplus#endif // (defined(_ARM) && defined(_MSC_VER))///////////////////////////////////////////////////////////////////////////////////////// GNUC / ARM///////////////////////////////////////////////////////////////////////////////////////#if (defined(_ARM) && defined(__GNUC__))#define HAVE_PLATFORM_MACROS#if defined(__MARM_THUMB__)/* Compute a * b / c, using 64-bit intermediate result. Since the ARM does not have a division instruction, we code a totally lame C version here. TODO wschildbach */static __inline int MulDiv64(int a, int b, int c){ long long t = (long long)a * (long long)b ; return (int)(t / c) ;}/* Compute (a * b) >> 31, using 64-bit intermediate result */static __inline__ int MulShift32(int x, int y){ SymInt64 a = x; SymInt64 b = y; a *= b; a >>= 32; return a.Low();}/* Compute (a * b) >> 31, using 64-bit intermediate result */static __inline__ int MulShift31(int x, int y){ SymInt64 a = x; SymInt64 b = y; a *= b; a >>= 31; return a.Low();}/* Compute (a * b) >> 31, using 64-bit intermediate result */static __inline__ int MulShift30(int x, int y){ SymInt64 a = x; SymInt64 b = y; a *= b; a >>= 30; return a.Low();}/* Compute (a * b) >> n, using 64-bit intermediate result */static __inline__ int MulShiftN(int x, int y, int n){ SymInt64 a = x; SymInt64 b = y; a *= b; a >>= n; return a.Low();}#define HAVE_FASTABSstatic __inline int FASTABS(int x){ if (x >= 0) return x; return -x;}#else/* Compute a * b / c, using 64-bit intermediate result. Since the ARM does not have a division instruction, we code a totally lame C version here. TODO wschildbach */static __inline int MulDiv64(int a, int b, int c){ long long t = (long long)a * (long long)b ; return (int)(t / c) ;}/* Compute (a * b) >> 31, using 64-bit intermediate result */static __inline__ int MulShift32(int x, int y){ int zlow ; __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ; return x ;}/* Compute (a * b) >> 31, using 64-bit intermediate result */static __inline__ int MulShift31(int x, int y){ int zlow ; __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ; __asm__ volatile ("mov %0,%1, lsr #31" : "=r" (zlow) : "r" (zlow)) ; __asm__ volatile ("orr %0,%1,%2, lsl #1" : "=r" (x) : "r" (zlow), "r" (x)) ; return x ;}/* Compute (a * b) >> 31, using 64-bit intermediate result */static __inline__ int MulShift30(int x, int y){ int zlow ; __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ; __asm__ volatile ("mov %0,%1, lsr #30" : "=r" (zlow) : "r" (zlow)) ; __asm__ volatile ("orr %0,%1,%2, lsl #2" : "=r" (x) : "r" (zlow), "r" (x)) ; return x ;}/* Compute (a * b) >> n, using 64-bit intermediate result */static __inline__ int MulShiftN(int x, int y, int n){ int zlow ; __asm__ volatile ("smull %0,%1,%2,%3" : "=&r" (zlow), "=r" (x) : "%r" (y), "1" (x)) ; __asm__ volatile ("mov %0,%1, lsr %2" : "=r" (zlow) : "r" (zlow), "r" (n)) ; __asm__ volatile ("orr %0,%1,%2, lsl %3" : "=r" (x) : "r" (zlow), "r" (x), "r" (32-n)) ; return x ;}#define HAVE_FASTABSstatic __inline int FASTABS(int x){ int s; // s = x ^ (x >> 31) __asm__ volatile ("eor %0, %1, %1, asr #31" : "=r" (s) : "r" (x)) ; // x = s - (x >> 31) __asm__ volatile ("sub %0, %1, %2, asr #31" : "=r" (x) : "r" (s), "r" (x)) ; return x;}#endif // defined(__MARM_THUMB__)#endif // (defined(_ARM) && defined(__GNUC__))///////////////////////////////////////////////////////////////////////////////////////// ARM_ADS / ARM///////////////////////////////////////////////////////////////////////////////////////#if defined(ARM_ADS)static __inline int MulShift32(int x, int y){ /* JR - important rules for smull RdLo, RdHi, Rm, Rs: * RdHi and Rm can't be the same register * RdLo and Rm can't be the same register * RdHi and RdLo can't be the same register * for MULSHIFT0(x,y), x = R0 and y = R1 * therefore we do y*x instead of x*y so that top 32 can go in R0 (the return register) */ int zlow; __asm { smull zlow,x,y,x } return x;}static __inline int MulShift31(int x, int y){ /* JR - store result in z (instead of reusing zlow) so that gcc optimizes properly */ int zlow, z; __asm { smull zlow, x, y, x mov zlow, zlow, lsr #31 orr z, zlow, x, lsl #1 } return z;}static __inline int MulShift30(int x, int y){ /* JR - store result in z (instead of reusing zlow) so that gcc optimizes properly */ int zlow, z; __asm { smull zlow, x, y, x mov zlow, zlow, lsr #30 orr z, zlow, x, lsl #2 } return z;}#define HAVE_FASTABSstatic __inline int FASTABS(int x) { int s; __asm { eor s, x, x, asr #31 sub x, s, x, asr #31 } return x;}#endif // defined(ARM_ADS)///////////////////////////////////////////////////////////////////////////////////////// platform independent implementations///////////////////////////////////////////////////////////////////////////////////////#ifndef ASSERT#define ASSERT(x)#endif#ifndef TICK#define TICK()#endif#ifndef TOCK#define TOCK(nsamples) 1#endif#ifndef HAVE_FASTABSstatic __inline int FASTABS(int x) { int sign; sign = x >> 31; x ^= sign; x -= sign; return x;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -