coding, photo, plant and demo

*androidの残念かつ取り返しのつかない呼び出し規約について

tech arm android 20111008 185012
floatを引数とする場合、渡し方に通常のレジスタを使うsoftfpと浮動小数レジスタを使うhardfpというものがあるらしい。
31年生きてて初めて知りました。
当然、softfpだと汎用レジスタを食い潰すし、レジスタ間のコピーが必ず発生するので効率が悪い。

Getting hardware floating point with android NDK
http://stackoverflow.com/questions/3004915/getting-hardware-floating-point-with-android-ndk
それで、androidはGL等のライブラリも含めてsoftfpでコンパイルされているので、hardfpを使いたくても使えないという罠。emulatorがarmv5でfpuなしだから、softfpにしたのは致し方なしか。

ARM EABIでの浮動小数点演算
http://www.oidon.net/linux/arm-eabi-floating-point
コンパイラがどんなコードを吐くか。softを指定すると演算もFPUを使わずCPUで行う。

gccでNEONのSIMD命令を生成させる方法
http://blog.kmckk.com/archives/1565251.html
コメントでも指摘されているけど、mhard-floatの指定が無意味な気がするが...gccの特殊な事情でもあるのかな。

Re: [ARM/hard_vfp_4_4_branch] Update -mfloat-abi documentation
http://gcc.gnu.org/ml/gcc-patches/2009-05/msg00620.html
gcc4.5からarmでhardfpがサポートされたらしい。

試してみた。
$ sudo apt-get install gcc-4.5-arm-linux-gnueabi

$ echo "float add(float a, float b){return a+b;}" >add.c

$ arm-linux-gnueabi-gcc add.c -S -march=armv7-a -O2 -o - -mfloat-abi=soft
add:
        push    {r3, lr}
        bl      __aeabi_fadd
        pop     {r3, pc}

$ arm-linux-gnueabi-gcc add.c -S -march=armv7-a -O2 -o - -mfloat-abi=softfp
add:
        fmsr    s14, r0
        fmsr    s15, r1
        fadds   s14, s14, s15
        fmrs    r0, s14
        bx      lr

$ arm-linux-gnueabi-gcc add.c -S -march=armv7-a -O2 -o - -mfloat-abi=hard
add:
        fadds   s0, s0, s1
        bx      lr
身も蓋もない結果です。

ところで、問題はライブラリはsoftfpだとしても、自前の関数間はせめてhardfpでやりたいよね、と思うのだけど、float-abiに関しては関数単位で呼び出し規約を設定できないぽくて、どうにもならんということですね。無理矢理やるとすれば、hardfpでコンパイルするけど、外の関数は引数の載せ替えをするwrapper関数(asm)を自動生成すればいけるだろうけど辛すぎ。

11.2.2. Combining hardfp and softfp systems
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0041c/ch11s02s02.html
やはり、基本は混ぜるな危険ということらしい。
しかし、androidは今時有り得ないfpu無しの亡霊に引っ張られて、これからもsoftfpで書くしかないなんて、なんとも残念な感じである。