重ねたテーブル使ってみた。遅かったのでインラインアセンブラで書き直したら早くなった。コンパイラは当てにできないなぁ。
invariant ubyte[152] table=[ 0, 0, 1, 0, 2, 0, 8, 9, 3,10, 0,16,17,11,18, 0, 4, 0,19, 0, 0,12, 0, 0,24,25,20,26, 0, 0, 0,27, 5, 0, 0, 0, 0,13, 0,28, 0, 0,21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,29, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0,14, 0, 0, 0, 0,22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,30, 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, 7, 0, 0, 0, 0,15, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,31 ]; uint ntz(bool zero=true)(uint x){ asm{ naked; }; static if(!zero) assert(x); else asm{ test EAX, EAX; jne n; mov EAX, 32; ret; }; n: asm{ mov ECX, EAX; neg ECX; and ECX, EAX; movzx EAX, CL; mov AL, byte ptr table[EAX]; movzx EDX, CH; or AL, byte ptr table[EDX+0x5]; shr ECX, 16; mov DL, CL; or AL, byte ptr table[EDX+0xa]; mov DL, CH; or AL, byte ptr table[EDX+0x17]; ret; }; }