__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ビット判定を行うインストラクションがあります。これ使っちゃえば楽勝じゃん?
本当にありがとうございました。
あ、でもちょっと気になるのは、このインストラクションの発行フローは
clz
とrbit
の組み合わせがあれば使う価値があるのですが、これはARMv6T2以降のARM/32bitThumbで使えるはずです。じゃぁ、なんでCortex-M3向けのコードはあんなややこしいコードになってたのか。16bitThumbを使うことを優先したのかな?