Fast fixed-point log2 approximation

This commit is contained in:
Ken Cooke 2017-05-18 14:15:10 -07:00
parent cad9eeb8ba
commit 106dd6ce6a

View file

@ -252,6 +252,69 @@ static inline int32_t peaklog2(float* input0, float* input1, float* input2, floa
return (e << LOG2_FRACBITS) - (c2 >> 3);
}
//
// Count Leading Zeros
// Emulates the CLZ (ARM) and LZCNT (x86) instruction
//
static inline int CLZ(uint32_t x) {
if (x == 0) {
return 32;
}
int e = 0;
if (x < 0x00010000) {
x <<= 16;
e += 16;
}
if (x < 0x01000000) {
x <<= 8;
e += 8;
}
if (x < 0x10000000) {
x <<= 4;
e += 4;
}
if (x < 0x40000000) {
x <<= 2;
e += 2;
}
if (x < 0x80000000) {
e += 1;
}
return e;
}
//
// Compute -log2(x) for x=[0,1] in Q31, result in Q26
// x = 0 returns 0x7fffffff
// x < 0 undefined
//
static inline int32_t fixlog2(int32_t x) {
if (x == 0) {
return 0x7fffffff;
}
// split into e and x - 1.0
int e = CLZ((uint32_t)x);
x <<= e; // normalize to [0x80000000, 0xffffffff]
x &= 0x7fffffff; // x - 1.0
int k = x >> (31 - LOG2_TABBITS);
// polynomial for log2(1+x) over x=[0,1]
int32_t c0 = log2Table[k][0];
int32_t c1 = log2Table[k][1];
int32_t c2 = log2Table[k][2];
c1 += MULHI(c0, x);
c2 += MULHI(c1, x);
// reconstruct result in Q26
return (e << LOG2_FRACBITS) - (c2 >> 3);
}
//
// Compute exp2(-x) for x=[0,32] in Q26, result in Q31
// x < 0 undefined