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サイクルです。事前のおおざっぱな見積もりがほぼ的中しています。