2009年09月04日

AndroidのユーザーランドをFPUを有効にしてリビルドする

これまで2回に渡ってDalvikVMのインタープリタの部分でFPU命令を使って高速化する変更方法を紹介しました。

残りのCの部分で書いてある部分もコンパイルオプションを変えればFPU命令を使うようになるはずです。ソースをながめてみるとsetjmpの部分でFPUレジスタが退避されていなかったので、そのソース修正も合わせて紹介します。



2009年11月のEclairのソースリリースでだいぶ状況が変わっています。こちらも参照してください。

setjmpの修正

setjmp関連でのFPUのレジスタの退避、復帰の部分がeabiのコーリングコンベンションとは違うかたちになっていたので以下のように修正します。

diff --git a/libc/arch-arm/bionic/_setjmp.S b/libc/arch-arm/bionic/_setjmp.S
index 6a27af2..4103e1a 100644
--- a/libc/arch-arm/bionic/_setjmp.S
+++ b/libc/arch-arm/bionic/_setjmp.S
@@ -53,13 +53,13 @@ ENTRY(_setjmp)
 	ldr	r1, .L_setjmp_magic
 	str	r1, [r0], #4
 #ifdef SOFTFLOAT
-	add	r0, r0, #52
+	add	r0, r0, #68
 #else
-	/* Store fp registers */
-	sfm	f4, 4, [r0], #48
 	/* Store fpsr */
-	rfs	r1
-	str	r1, [r0], #0x0004
+        fmrx    r1, fpscr
+        str     r1, [r0], #4
+	/* Store fp registers */
+        fstmiad r0!, {d8-d15}
 #endif	/* SOFTFLOAT */
 	/* Store integer registers */
         stmia	r0, {r4-r14}
@@ -77,13 +77,13 @@ ENTRY(_longjmp)
 	bne	botch
 
 #ifdef SOFTFLOAT
-	add	r0, r0, #52
+	add	r0, r0, #68
 #else
+	/* Restore FPSR */
+        ldr     r1, [r0], #4
+        fmxr    fpscr, r1
 	/* Restore fp registers */
-	lfm	f4, 4, [r0], #48
-	/* Restore fpsr */
-	ldr	r4, [r0], #0x0004
-	wfs	r4
+        fldmiad r0!, {d8-d15}
 #endif	/* SOFTFLOAT */
        	/* Restore integer registers */
         ldmia	r0, {r4-r14}
diff --git a/libc/arch-arm/bionic/setjmp.S b/libc/arch-arm/bionic/setjmp.S
index a9f6ea4..8903cdd 100644
--- a/libc/arch-arm/bionic/setjmp.S
+++ b/libc/arch-arm/bionic/setjmp.S
@@ -57,19 +57,19 @@ ENTRY(setjmp)
 	ldmfd	sp!, {r0, r14}
 
 	/* Store signal mask */
-	str	r1, [r0, #(25 * 4)]
+	str	r1, [r0, #(29 * 4)]
 
 	ldr	r1, .Lsetjmp_magic
 	str	r1, [r0], #4
 
 #ifdef SOFTFLOAT
-	add	r0, r0, #52
+	add	r0, r0, #68
 #else
-	/* Store fp registers */
-	sfm	f4, 4, [r0], #48
 	/* Store fpsr */
-	rfs	r1
-	str	r1, [r0], #0x0004
+        fmrx    r1, fpscr
+        str     r1, [r0], #4
+	/* Store fp registers */
+        fstmiad r0!, {d8-d15}
 #endif	/*SOFTFLOAT*/
 	/* Store integer registers */
         stmia	r0, {r4-r14}
@@ -87,7 +87,7 @@ ENTRY(longjmp)
 	bne	botch
 
 	/* Fetch signal mask */
-	ldr	r2, [r0, #(25 * 4)]
+	ldr	r2, [r0, #(29 * 4)]
 
 	/* Set signal mask */
 	stmfd	sp!, {r0, r1, r14}
@@ -101,13 +101,13 @@ ENTRY(longjmp)
 
 	add	r0, r0, #4
 #ifdef SOFTFLOAT
-	add	r0, r0, #52
+	add	r0, r0, #68
 #else
-	/* Restore fp registers */
-	lfm	f4, 4, [r0], #48
 	/* Restore FPSR */
-	ldr	r4, [r0], #0x0004
-	wfs	r4
+        ldr     r1, [r0], #4
+        fmxr    fpscr, r1
+	/* Restore fp registers */
+        fldmiad r0!, {d8-d15}
 #endif	/* SOFTFLOAT */
 	/* Restore integer registers */
         ldmia	r0, {r4-r14}
diff --git a/libc/arch-arm/include/machine/setjmp.h b/libc/arch-arm/include/machine/setjmp.h
index f20cab2..ce79d03 100644
--- a/libc/arch-arm/include/machine/setjmp.h
+++ b/libc/arch-arm/include/machine/setjmp.h
@@ -5,11 +5,8 @@
  * machine/setjmp.h: machine dependent setjmp-related information.
  */
 
-#ifdef __ELF__
 #define	_JBLEN	64		/* size, in longs, of a jmp_buf */
-#else
-#define	_JBLEN	29		/* size, in longs, of a jmp_buf */
-#endif
+
 
 /*
  * NOTE: The internal structure of a jmp_buf is *PRIVATE*
@@ -65,23 +62,28 @@
 /* Valid for all jmp_buf's */
 
 #define _JB_MAGIC		 0
-#define _JB_REG_F4		 1
-#define _JB_REG_F5		 4
-#define _JB_REG_F6		 7
-#define _JB_REG_F7		10
-#define _JB_REG_FPSR		13
-#define _JB_REG_R4		14
-#define _JB_REG_R5		15
-#define _JB_REG_R6		16
-#define _JB_REG_R7		17
-#define _JB_REG_R8		18
-#define _JB_REG_R9		19
-#define _JB_REG_R10		20
-#define _JB_REG_R11		21
-#define _JB_REG_R12		22
-#define _JB_REG_R13		23
-#define _JB_REG_R14		24
+#define _JB_REG_FPSR		 1
+#define _JB_REG_D8		 2
+#define _JB_REG_D9		 4
+#define _JB_REG_D10		 6
+#define _JB_REG_D11		 8
+#define _JB_REG_D12		10
+#define _JB_REG_D13		12
+#define _JB_REG_D14		14
+#define _JB_REG_D15		16
+
+#define _JB_REG_R4		18
+#define _JB_REG_R5		19
+#define _JB_REG_R6		20
+#define _JB_REG_R7		21
+#define _JB_REG_R8		22
+#define _JB_REG_R9		23
+#define _JB_REG_R10		24
+#define _JB_REG_R11		25
+#define _JB_REG_R12		26
+#define _JB_REG_R13		27
+#define _JB_REG_R14		28
 
 /* Only valid with the _JB_MAGIC_SETJMP magic */
 
-#define _JB_SIGMASK		25
+#define _JB_SIGMASK		29

それから、条件コンパイルで常にSOFTFLOATが有効になっていたので、FPUレジスタの退避、復帰の部分がはずれていました。

本来ならばコンパイルオプションに連動するように変更するべきですが、今回はとりあえず無条件にはずします。

diff --git a/libc/Android.mk b/libc/Android.mk
index 59a4c6b..ca6fa36 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -352,7 +352,6 @@ libc_common_cflags := \
 		-DUSE_LOCKS 			\
 		-DREALLOC_ZERO_BYTES_FREES 	\
 		-D_LIBC=1 			\
-		-DSOFTFLOAT                     \
 		-DFLOATING_POINT		\
 		-DNEED_PSELECT=1		\
 		-DINET6 \

コンパイルオプションの変更

コンパイルオプションでsoft-floatを指定しているところをvfpを使うように変更します。

diff --git a/core/combo/linux-arm.mk b/core/combo/linux-arm.mk
index 11a8ac7..46d0ccd 100644
--- a/core/combo/linux-arm.mk
+++ b/core/combo/linux-arm.mk
@@ -110,8 +110,18 @@ endif
 android_config_h := $(call select-android-config-h,linux-arm)
 arch_include_dir := $(dir $(android_config_h))
 
 $(combo_target)GLOBAL_CFLAGS += \
-                       -msoft-float -fpic \
+                       -mhard-float -mfloat-abi=softfp -mfpu=vfp -fpic \
                        -ffunction-sections \
                        -funwind-tables \
                        -fstack-protector \

これでトップディレクトリからクリーンビルドすればFPU命令を使用するユーザーランドがビルドできます。

qemuの変更

これをエミュレータで動かすには前回紹介したqemuへのパッチが必要になりますから、忘れずに変更してください。これをいれないとバスエラーが発生します。

diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 36de55b..41219f6 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -70,7 +70,7 @@ uint32_t HELPER(neon_tbl)(uint32_t ireg, uint32_t def,
 static void do_unaligned_access (target_ulong addr, int is_write, int is_user, void *retaddr);
 
 #define MMUSUFFIX _mmu
-#define ALIGNED_ONLY  1
+/*#define ALIGNED_ONLY  1*/
 
 #define SHIFT 0
 #include "softmmu_template.h"

まとめ

3回に渡ってAndroidでFPUを使って高速化する方法を紹介しました。

FPU付きの実機にAndroidを移植して動かしている方はぜひ試してみてください。速度性能評価などをトラックバックしてくれたら嬉しいです。

また、インタープリタにはまだ高速化の余地が残されています。どなたか続きに挑戦してみてください。



トラックバックURL

コメントする

名前
 
  絵文字
 
 
記事検索
最新コメント
アクセスカウンター
  • 今日:
  • 昨日:
  • 累計:

QRコード
QRコード