Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Tricky implementation of Go ARM soft float

5,657 views

Published on

Tricky implementation of Go ARM soft float.
Written in Japanese

Published in: Technology
  • Be the first to comment

Tricky implementation of Go ARM soft float

  1. 1. 1 Tricky implementation Of Go ARM soft float Tetsuyuki Kobayashi 2015.2.14 Kernel/VM 探検隊 2015.2.22 YAPF
  2. 2. 2  The latest version of this slide will be available from here  http://www.slideshare.net/tetsu.koba/presentati ons
  3. 3. 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. 4. 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. 5. 5 GOARM  GOARM=5  For armv5, no FPU, soft float  GOARM=6  (Default)  For armv6, VFPv1  GOARM=7  For armv7, VFPv3
  6. 6. 6 以上。
  7. 7. 7 間違えなければ どうということはない。
  8. 8. 8 しかし、
  9. 9. 9 間違いから理解が 深まることもある。
  10. 10. 10 ツールチェインのビルドミス $ GOOS=linux GOARCH=arm GOARM=5 ./make.bash  GOARM を指定しないときは GOARM=6 これを忘れた!
  11. 11. 11 ARM$ ./hello Illegal Instruction  できた実行ファイルを実機 (armv5, no FPU) に持って行って実行すると $ GOOS=linux GOARCH=arm GOARM=5 go build hello.go
  12. 12. 12 FPU 命令が混じってた vldr d2, [r3]  gdb で illegal instruction を起こした命令を 調べると ランタイムライブラリが GOARM=6 で ビルドされているからか!
  13. 13. 13 やり直し $ GOOS=linux GOARCH=arm GOARM=5 ./make.bash $ GOOS=linux GOARCH=arm GOARM=5 go build hello.go
  14. 14. 14 念のために逆アセンブル $ arm-linux-gnueabi-objdump -d hello ... bl <_sfloat> vldr d2, [r3] fcpyd d4, d2 ...   FPU 命令がまだある?!
  15. 15. 15 Go1.4 は armv5 サポート 無くなった?  git で go1.3, go1.2, go1.1 のそれぞれ のタグをチェックアウトして調べた  全て同じだった
  16. 16. 16 Soft float emulation  ARM の Linux kernel には soft float emulation があった  kernel を再ビルド CONFIG_OABI_COMAT=y CONFIG_FPE_NWFPE=y  これで動いた! ARM$ ./hello Hello, Go
  17. 17. 17 しかし  Go ARM がカーネルコンフィグに依 存するとはどこにも書いてない?  しかも  ARM の soft float emulation は Deprecated  最近のカーネルではすでに削除されて いる
  18. 18. 18 実は  soft float emulation を有効にしていな いカーネルでも hello は動いた  カーネルのコンフィグは無関係   ( 本当はツールチェインのビルドを間 違っただけ )
  19. 19. 19 謎の関数 _sfloat ... bl <_sfloat> vldr d2, [r3] fcpyd d4, d2 ... フロート演算のコードに共通するパターンを発見。 ... bl <_sfloat> vldr d2, [r0] fcmped d3, d2 fmstat bvs 117fc ...   FPU 命令の前に必ず _sfloat を呼び出す
  20. 20. 20 _sfloat のソースコードを追跡  _sfloat in go/src/runtime/vlop_arm.s  → runtime ・ _sfloat2  _sfloat2 in go/src/runtime/softfloat_arm.c  → sfloat2
  21. 21. 21 static void sfloat2(void) { … while (skip = stepflt(pc, (uint32*)&regs->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. 22. 22 // returns number of words that the fp instruction // is occupying, 0 if next instruction isn't float. static uint32 stepflt(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] %xn", regd, regm, m->freglo[regd]); break; case 0xeeb00b40: // D[regd] = D[regm] (MOVD) stepflt は FPU 命令のインタープリタ
  23. 23. 23 FPU 命令は CPU で実行されていない FPU 命令が混じっていても illegal instruction にならない ... bl <_sfloat> vldr d2, [r0] fcmped d3, d2 fmstat bvs 117fc ... _sfloat から戻ってきた後に この命令から実行再開
  24. 24. 24 GOARM=5 と 6 の生成コードの違い  どちらも FPU 命令を生成する  GOARM=5 の場合は FPU 命令の塊の前に _sfloat への呼び出しが挿入される。 ( リンカーがこれを行っている )  生成された FPU 命令は同じ。  コンパイラは soft float のための命令を生成し ないので実装がラク。
  25. 25. 25 結論  Golang は自前で soft float emulation する 仕組みを持っている。  カーネルの soft float emulation は不要。  正しくビルドすれば普通に動く。  ついでにわかったこと  ARM Linux の soft float emulation は deprecated
  26. 26. 26 Q & A @tetsu_koba Thank you for listening!

×