Upload
tetsuyuki-kobayashi
View
2.483
Download
2
Embed Size (px)
Citation preview
1
Tricky implementationOf Go ARM soft float
Tetsuyuki Kobayashi
2015.2.14 Kernel/VM 探検隊2015.2.22 YAPF
2
The latest version of this slide will be available from here
http://www.slideshare.net/tetsu.koba/presentations
3
Who am I?
20+ years involved in embedded systems 10 years in real time OS, such as iTRON 10 years in embedded Java Virtual Machine Now GCC, Linux, QEMU, Android, …
Blogs http://d.hatena.ne.jp/embedded/ http://kobablog.wordpress.com/(English)
Twitter @tetsu_koba
4
Golang for ARM Linux
ツールチェインのビルド ソースコードを入手して
$ cd go/src$ GOOS=linux GOARCH=arm GOARM=5 ./make.bash
実行型のビルド Go コマンドに PATHを通して
$ GOOS=linux GOARCH=arm GOARM=5 go build hello.go
5
GOARM
GOARM=5 For armv5, no FPU, soft float
GOARM=6 (Default) For armv6, VFPv1
GOARM=7 For armv7, VFPv3
11
ARM$ ./helloIllegal Instruction
できた実行ファイルを実機 (armv5, no FPU)に持って行って実行すると
$ GOOS=linux GOARCH=arm GOARM=5 go build hello.go
13
やり直し
$ GOOS=linux GOARCH=arm GOARM=5 ./make.bash
$ GOOS=linux GOARCH=arm GOARM=5 go build hello.go
14
念のために逆アセンブル
$ arm-linux-gnueabi-objdump -d hello
... bl <_sfloat> vldr d2, [r3] fcpyd d4, d2 ...
FPU命令がまだある?!
16
Soft float emulation
ARMの Linux kernelには soft float emulationがあった
kernelを再ビルドCONFIG_OABI_COMAT=yCONFIG_FPE_NWFPE=y
これで動いた!ARM$ ./helloHello, Go
17
しかし
Go ARM がカーネルコンフィグに依存するとはどこにも書いてない?
しかも ARMの soft float emulationは
Deprecated 最近のカーネルではすでに削除されている
19
謎の関数 _sfloat
... bl <_sfloat> vldr d2, [r3] fcpyd d4, d2 ...
フロート演算のコードに共通するパターンを発見。
... bl <_sfloat> vldr d2, [r0] fcmped d3, d2 fmstat bvs 117fc ...
FPU命令の前に必ず_sfloatを呼び出す
20
_sfloatのソースコードを追跡
_sfloat in go/src/runtime/vlop_arm.s → runtime・ _sfloat2
_sfloat2 in go/src/runtime/softfloat_arm.c → sfloat2
21
static void sfloat2(void){ … while (skip = stepflt(pc, (uint32*)®s->r0)){ : : pc += skip } g->m->ptarg[0] = pc;}
Soft float emulation inside golang
Comment is source code:stepflt returns number of words that the fp instruction is occupying, 0 if next instruction isn't float
FPU命令のインタープリタ
22
// returns number of words that the fp instruction// is occupying, 0 if next instruction isn't float.static uint32stepflt(uint32 *pc, uint32 *regs){ ...
switch(i & 0xffff0ff0) {default:
goto done;
case 0xeeb00a40: // F[regd] = F[regm] (MOVF)m->freglo[regd] = m->freglo[regm];
if(trace)runtime·printf("*** F[%d] = F[%d] %x\n",
regd, regm, m->freglo[regd]);break;
case 0xeeb00b40: // D[regd] = D[regm] (MOVD)
stepflt は FPU命令のインタープリタ
23
FPU命令は CPUで実行されていない
FPU命令が混じっていてもillegal instruction にならない
... bl <_sfloat> vldr d2, [r0] fcmped d3, d2 fmstat bvs 117fc ...
_sfloatから戻ってきた後にこの命令から実行再開
24
GOARM=5と 6の生成コードの違い
どちらも FPU 命令を生成する GOARM=5の場合は FPU命令の塊の前に
_sfloatへの呼び出しが挿入される。(リンカーがこれを行っている )
生成された FPU命令は同じ。 コンパイラは soft floatのための命令を生成しないので実装がラク。
25
結論
Golang は自前で soft float emulation する仕組みを持っている。 カーネルの soft float emulationは不要。
正しくビルドすれば普通に動く。 ついでにわかったこと
ARM Linuxの soft float emulationはdeprecated