diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES
index 09a4476..4d4418e 100644
--- a/apps/plugins/CATEGORIES
+++ b/apps/plugins/CATEGORIES
@@ -93,6 +93,7 @@ test_scanrate,apps
 test_touchscreen,apps
 test_viewports,apps
 test_greylib_bitmap_scale,viewers
+test_clz_speed,apps
 text_editor,apps
 vbrfix,viewers
 video,viewers
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 6257a22..e8f1f8d 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -28,6 +28,7 @@ firmware_flash.c
 #if (CONFIG_CPU == SH7034)
 rockbox_flash.c
 #endif /* CONFIG_CPU */
+test_clz_speed.c

 #ifndef OLYMPUS_MROBE_500

diff --git a/apps/plugins/test_clz_speed.c b/apps/plugins/test_clz_speed.c
new file mode 100644
index 0000000..3d9a530
--- /dev/null
+++ b/apps/plugins/test_clz_speed.c
@@ -0,0 +1,173 @@
+/*****************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _// __ \_/ ___\|  |/ /| __ \ / __ \  \/  /
+ *   Jukebox    |    |   ( (__) )  \___|    ( | \_\ ( (__) )    (
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * Copyright (C) 2008 Andrew Mahone
+ *
+ * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "plugin.h"
+#include "lib/pluginlib_actions.h"
+
+PLUGIN_HEADER
+
+static const char clz_lut1[16] = { 4, 3, 2, 2, 1, 1, 1, 1,
+                                  0, 0, 0, 0, 0, 0, 0, 0 };
+/* This clz is based on the log2(n) implementation at
+ * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup
+ */
+int clz1(uint32_t v)
+{
+    int r = 28;
+    if (v >= 0x10000)
+    {
+        v >>= 16;
+        r -= 16;
+    }
+    if (v & 0xff00)
+    {
+        v >>= 8;
+        r -= 8;
+    }
+    if (v & 0xf0)
+    {
+        v >>= 4;
+        r -= 4;
+    }
+    return r + clz_lut1[v];
+}
+
+static const char clz_lut2[256] = {
+    8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+int clz2(uint32_t v)
+{
+    int r = 24;
+    if (v >= 0x10000)
+    {
+        v >>= 16;
+        r -= 16;
+    }
+    if (v & 0xff00)
+    {
+        v >>= 8;
+        r -= 8;
+    }
+    return r + clz_lut2[v];
+}
+
+static const char clz_lut3[53] = {
+    32, 31, 30, 25, 29,  6, 24,  0, 28,  0, 19,  5, 23, 12,  0,  0, 27,  8,  0,
+    14, 16, 18,  4,  0,  2, 22, 11,  0,  0,  0,  0,  0,  0, 26,  7,  0,  0, 20,
+    13,  0,  9, 15, 17,  0,  3,  0,  0,  0,1,  0, 21,  0, 10
+};
+int clz3(uint32_t v)
+{
+    v |= v >> 16;
+    v |= v >> 8;
+    v |= v >> 4;
+    v |= v >> 2;
+    v |= v >> 1;
+    v ^= v >> 1;
+    return clz_lut3[(v * 70428299UL)>>26];
+}
+
+int clz4(uint32_t v)
+{
+    int r = 32;
+    if (v >= 0x10000)
+    {
+        v >>= 16;
+        r -= 16;
+    }
+    if (v & 0xff00)
+    {
+        v >>= 8;
+        r -= 8;
+    }
+    if (v & 0xf0)
+    {
+        v >>= 4;
+        r -= 4;
+    }
+    if (v & 0xc)
+    {
+        v >>= 2;
+        r -= 2;
+    }
+    if (v & 2)
+    {
+        v >>= 1;
+        r -= 1;
+    }
+    r -= v;
+    return r;
+}
+
+int (*func_table[])(uint32_t) =
+{
+    clz1,
+    clz2,
+    clz3,
+    clz4,
+    NULL,
+};
+
+const struct button_mapping *plugin_contexts[] = {generic_actions};
+
+/* this is the plugin entry point */
+enum plugin_status plugin_start(const void* parameter)
+{
+    (void) parameter;
+    int y = 0, w=0, h=0, n;
+    char buf[16];
+    h = rb->lcd_getstringsize("0", &w, &h);
+    rb->lcd_set_drawmode(DRMODE_FG);
+    for (n = 0 ; func_table[n]; n++)
+    {
+        long t1 = *(rb->current_tick);
+        uint32_t i, lz;
+        for(i = 0; i < 1UL<<31; i+= 1023)
+            lz = (*(func_table[n]))(i);
+        long t2 = *(rb->current_tick);
+        rb->snprintf(buf, sizeof(buf), "%d:%d", n, (int)(t2-t1));
+        rb->lcd_putsxy(0, y, buf);
+        rb->lcd_update();
+        y += h * 2;
+    }
+    while(1)
+    {
+        int button = pluginlib_getaction(1, plugin_contexts, 1);
+        if (button == PLA_QUIT)
+            return PLUGIN_OK;
+        rb->yield();
+    }
+}