summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Mahone <andrew.mahone@gmail.com>2009-01-30 10:52:30 +0000
committerAndrew Mahone <andrew.mahone@gmail.com>2009-01-30 10:52:30 +0000
commitba4be5157191af6fbb83756119ffd29147b7fb99 (patch)
tree11e1cafefa29f74c763b3a54e9823814886feb59
parentb081a38131bf50aa4ca10b7805b1dd6b5c7a1c75 (diff)
downloadrockbox-ba4be5157191af6fbb83756119ffd29147b7fb99.tar.gz
rockbox-ba4be5157191af6fbb83756119ffd29147b7fb99.zip
per Jens Arnold's suggestion:
use platform clz instruction only on ARMv5+, where we know it returns 32 for a 0 input, and remove the special case for 0 use binary search only to find most significant four bits, then use lookup table to add number of leading zeroes within those bits git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19888 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/pictureflow.c26
1 files changed, 8 insertions, 18 deletions
diff --git a/apps/plugins/pictureflow.c b/apps/plugins/pictureflow.c
index 31e4c97468..cd7e54ce35 100644
--- a/apps/plugins/pictureflow.c
+++ b/apps/plugins/pictureflow.c
@@ -337,11 +337,9 @@ static inline PFreal fmul(PFreal a, PFreal b)
337 return (a*b) >> PFREAL_SHIFT; 337 return (a*b) >> PFREAL_SHIFT;
338} 338}
339 339
340/* ARMv5+ have a clz instruction. So do most modern desktop processors, and the 340/* ARMv5+ has a clz instruction equivalent to our function.
341 * simulator doesn't need to be as concerned about savings for inlining a calls
342 * to a clz function.
343 */ 341 */
344#if defined(SIMULATOR) || (defined(CPU_ARM) && (ARM_ARCH > 4)) 342#if (defined(CPU_ARM) && (ARM_ARCH > 4))
345static inline int clz(uint32_t v) 343static inline int clz(uint32_t v)
346{ 344{
347 return __builtin_clz(v); 345 return __builtin_clz(v);
@@ -349,12 +347,14 @@ static inline int clz(uint32_t v)
349 347
350/* Otherwise, use our clz, which can be inlined */ 348/* Otherwise, use our clz, which can be inlined */
351#else 349#else
350static const char clz_lut[16] = { 4, 3, 2, 2, 1, 1, 1, 1,
351 0, 0, 0, 0, 0, 0, 0, 0 };
352/* This clz is based on the log2(n) implementation at 352/* This clz is based on the log2(n) implementation at
353 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog 353 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup
354 */ 354 */
355static inline int clz(uint32_t v) 355static inline int clz(uint32_t v)
356{ 356{
357 uint32_t r = 31; 357 int r = 28;
358 if (v >= 0x10000) 358 if (v >= 0x10000)
359 { 359 {
360 v >>= 16; 360 v >>= 16;
@@ -370,14 +370,7 @@ static inline int clz(uint32_t v)
370 v >>= 4; 370 v >>= 4;
371 r -= 4; 371 r -= 4;
372 } 372 }
373 if (v & 0xc) 373 return r + clz_lut[v];
374 {
375 v >>= 2;
376 r -= 2;
377 }
378 if (v & 2)
379 r -= 1;
380 return r;
381} 374}
382#endif 375#endif
383 376
@@ -387,10 +380,7 @@ static inline int clz(uint32_t v)
387static inline int allowed_shift(int32_t val) 380static inline int allowed_shift(int32_t val)
388{ 381{
389 uint32_t uval = val ^ (val >> 31); 382 uint32_t uval = val ^ (val >> 31);
390 if (!uval) 383 return clz(uval) - 1;
391 return 31;
392 else
393 return clz(uval) - 1;
394} 384}
395 385
396/* Calculate num/den, with the result shifted left by PFREAL_SHIFT, by shifting 386/* Calculate num/den, with the result shifted left by PFREAL_SHIFT, by shifting