top page > la vie en rose > here

long double と gcc 4.7


概要

i386 + gcc 4.7 にて,拡張倍精度 (long double) を利用する.

対象は次のようなものです.

  1. OS は FreeBSD の 7 系以降 (/i386 および /pc98)
  2. CPU は i386
  3. gcc は version 4.7

題材は次のようなものです.

  1. 拡張倍精度に関する gcc の bug (仕様) を修正する.
  2. gcc 4.7 のその他の bug を修正する.

目次

1. gcc 4.7 について
2. 修正の手順
3. 資料
4. その他

1. gcc 4.7 について

gcc 4.7 (ports/lang/gcc47) においても,long double の定数に関する bug は修正されておりません.

また,少なくとも gcc-4.7-20110521.tar.bz2 では compile すると次のようなエラー・メッセージが出力されます. (この問題は gcc 4.7 よりも前から生じているとのことです.)

error in /usr/lib/crtendS.o(.eh_frame); no .eh_frame_hdr table will be created.

これはプログラムの動作には影響はありませんが,非常に鬱陶しいです.

どちらの問題も,既に解決法は提示されております.[1][2] ここでは,それらを実践してみた結果を記します.
→ 後者の問題は,少なくとも gcc-4.7-20120128.tar.bz2 においては解決されています.

2. 修正の手順

先ず ports/lang/gcc47/distfiles を見て,ソースの日付を確認します. 以下の patch は gcc-4.7-20110521.tar.bz2 のためのものなので,それ以外は手作業でソースを修正することになります.

(1) 2011.3.27 付 (あるいはより最新) の ports を展開する.

(2) patch を /usr/ports/lang/gcc47/filescp する. patch はここにあります.→ gcc47.tgz

(3) make install する.

# cd /usr/ports/lang/gcc47
# make
# make install

3. 資料

この節では patch の中身を解説いたします.

(1) patch-gcc_freebsd.h
  参考資料 [1] に work/gcc-4.7-20110319/gcc/config/i386/freebsd.h への patch が提示されています.

--- gcc/config/i386/freebsd.h.orig      2010-12-09 22:27:07.000000000 +0900
+++ gcc/config/i386/freebsd.h   2011-04-15 21:12:04.000000000 +0900
@@ -132,7 +132,7 @@
 /* FreeBSD sets the rounding precision of the FPU to 53 bits.  Let the
    compiler get the contents of <float.h> and std::numeric_limits correct.  */
 #undef TARGET_96_ROUND_53_LONG_DOUBLE
-#define TARGET_96_ROUND_53_LONG_DOUBLE (!TARGET_64BIT)
+#define TARGET_96_ROUND_53_LONG_DOUBLE 0

 /* Put all *tf routines in libgcc.  */
 #undef LIBGCC2_HAS_TF_MODE

これは work/gcc-4.7-20110319/gcc/ChangeLog-2004 の 2004-11-12 の以下の部分に記された「修正」をやめ元に戻すものです.

PR 17778
* config/i386/i386.h (TARGET_96_ROUND_53_LONG_DOUBLE): New.

なお,ChangeLog-2004 は OS 標準の gcc 4.2.1 ならば /usr/src/contrib/gcc/ にあります.

(2) patch-gcc_config.gcc
  参考資料 [2] に work/gcc-4.7-20110319/gcc/config.gcc への patch が提示されています.

--- gcc/config.gcc.orig 2011-03-14 15:05:29.000000000 +0900
+++ gcc/config.gcc      2011-04-15 20:55:50.000000000 +0900
@@ -1212,6 +1212,7 @@
        ;;
 i[34567]86-*-freebsd*)
        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ${fbsd_tm_file} i386/freebsd.h"
+       tmake_file="${tmake_file} i386/t-crtstuff"
        ;;
 x86_64-*-freebsd*)
        tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h ${fbsd_tm_file} i386/x86-64.h i386/freebsd.h i386/freebsd64.h"

先にも書きましたが,最新のソースではこの問題は既に修正されているのでご注意下さい.

[1] FreeBSD-users-jp 91686 (2008.6)

[2] http://patchwork.ozlabs.org/patch/83779/

4. その他

先日,初めて Fortran 95 を使う機会がありました. Fortran 自体が久々で,ここ数年は OS の更新の際に f77, f2c すらも導入しておりませんでした.

gcc (GNU Compiler Collection) には Fortran も含まれているのですが,OS として標準で導入しているのは,この中の gcc (GNU C Compiler) と g++ のみです. gcc を ports から導入すれば,Fortran (gfortran) も一緒に導入されます. (ちなみに,その際に導入するしないを選択することができるのは java だけで,Fortran は不要であっても導入されます.)