__builtin_ffsはどこへ行くのか?(続編)

GCのマークビット判定などに使用される__builtin_ffsというGCCコンパイラ拡張が気になったので 「__builtin_ffsはどこへ行くのか? - dec9ue's diary」って記事をちょっと前に書きました。

続編です。

さて、何の話だったかというと、__builtin_ffsとは



Other Builtins - Using the GNU Compiler Collection (GCC) http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Other-Builtins.html によると

Returns one plus the index of the least significant 1-bit of x, or if x is zero, returns zero.

ということで、ビットマップ何かを操作するときに使えるGCC拡張のようだ。



ということでした。

そして、今回は

でも、対象をもうちょっとモダンなアーキテクチャに変えちゃうかも。。。

の予告通り、armv7-aのアーキテクチャに変えてみました。

arm-linux-gnueabihf-gcc -O0 -S -std=gnu99 builtin_ffs_test.c 

の結果:

test:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        @ link register save eliminated.
        push    {r7}
        sub     sp, sp, #12
        add     r7, sp, #0
        str     r0, [r7, #4]
        ldr     r3, [r7, #4]
        rbit    r3, r3
        clz     r3, r3
        ldr     r2, [r7, #4]
        cmp     r2, #0
        bne     .L2
        mov     r3, #-1
.L2:
        add     r3, r3, #1
        mov     r0, r3
        add     r7, r7, #12
        mov     sp, r7
        pop     {r7}
        bx      lr

ARMv7AのARMインストラクションセットにはclzという先行0ビット判定を行うインストラクションがあります。これ使っちゃえば楽勝じゃん?

本当にありがとうございました。



あ、でもちょっと気になるのは、このインストラクションの発行フローはclzrbitの組み合わせがあれば使う価値があるのですが、これはARMv6T2以降のARM/32bitThumbで使えるはずです。じゃぁ、なんでCortex-M3向けのコードはあんなややこしいコードになってたのか。16bitThumbを使うことを優先したのかな?