Codesourcery G++ LiteでCortex-M4Fプログラムをコンパイルする
2010年秋版のCodesourcery G++ LiteはCORTEX-M4Fに対応しています。試行錯誤した結果、以下のようにそれらしいコンパイル結果を得ることができました。
takemasa@takemasa-desktop:~/foo$ cat main.c volatile float a[20], b[20]; int main(void) { float sum=0.0; int i; for( i=0; i<20; i++ ) sum += a[i]*b[i]; return (int) sum; } takemasa@takemasa-desktop:~/foo$ takemasa@takemasa-desktop:~/foo$ arm-none-eabi-gcc -O2 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -mcpu=cortex-m4 -S main.c takemasa@takemasa-desktop:~/foo$ cat main.s .syntax unified .cpu cortex-m4 .eabi_attribute 27, 3 .eabi_attribute 28, 1 .fpu fpv4-sp-d16 .eabi_attribute 20, 1 .eabi_attribute 21, 1 .eabi_attribute 23, 3 .eabi_attribute 24, 1 .eabi_attribute 25, 1 .eabi_attribute 26, 1 .eabi_attribute 30, 2 .eabi_attribute 18, 4 .thumb .file "main.c" .text .align 2 .global main .thumb .thumb_func .type main, %function main: @ args = 0, pretend = 0, frame = 0 @ frame_needed = 0, uses_anonymous_args = 0 @ link register save eliminated. push {r4} movw r1, #:lower16:a movw r2, #:lower16:b flds s15, .L6 movs r3, #0 movt r1, #:upper16:a movt r2, #:upper16:b .L2: ldr r4, [r1, r3, lsl #2] ldr r0, [r2, r3, lsl #2] adds r3, r3, #1 fmsr s0, r4 fmsr s1, r0 ldr r4, [r1, r3, lsl #2] ldr r0, [r2, r3, lsl #2] fmacs s15, s0, s1 fmsr s13, r4 fmsr s14, r0 adds r3, r3, #1 cmp r3, #20 fmacs s15, s13, s14 bne .L2 ftosizs s15, s15 fmrs r0, s15 @ int pop {r4} bx lr .L7: .align 2 .L6: .word 0 .size main, .-main .comm a,80,4 .comm b,80,4 .ident "GCC: (Sourcery G++ Lite 2010.09-51) 4.5.1"
実機で確認していませんのでこれで決まりとは言えませんが、それらしい結果が出ています。苦労したのは-mfpu=fpv4-sp-d16 -mfloat-abi=hardを指定する点です。それでも後者はドキュメントを検索すればわかりましたが、前者の-fpu=fpv4-sp-d16には難儀しました。ほとんど隠しパラメータ扱いです。
ARMの浮動小数点コプロセッサはNEONとVFP(Vectored Floating Point)と呼ばれるコプロセッサが主流ですが、VFPは倍精度命令を持っています。CORTEX-M4はこのVFPの単精度派生品のFPv4-spで、GCCはそれをfpv4-sp-d16と呼んでいます。ああめんどくさい。
性能のほうは、ベクトルのスカラ積を実行したときに、1MACに9サイクルです。事前のおおざっぱな見積もりがほぼ的中しています。