読者です 読者をやめる 読者になる 読者になる

H8300用クロスコンパイラの作成

gcc h8

コンパイラテストツールが 16bitコンパイラでも使用できるか
ということを確かめたかったので作って見ました。


基本的にその他のクロスコンパイラと同様です。
以下とほとんど同じです。


v850用クロス開発環境の構築 - Life is very short

ビルド環境

ツールチェインのバージョン

Binutilsの作成

   % tar xf binutils-2.21.1.tar.bz2
   % cd buinutils-2.21.1
   % mkdir build && cd build
   % ../configure --target=h8300-linux-elf --prefix=/home/syohei/local/h8300 \
      --disable-nls
   % make
   % make install
   % export PATH=/home/syohei/local/h8300/bin:$PATH

GCCの作成

   % tar xf gcc-4.6.1.tar.bz2
   % tar xf newlib-1.19.0.tar.gz
   % ln -s ../newlib-1.19.0/newlib .
   % ln -s ../newlib-1.19.0/libgross .
   % cd gcc-4.6.1
   % mkdir build && cd build
   % ../configure --target=h8300-linux-elf --prefix=/home/syohei/local/h8300 \
      --enable-languages=c --with-gmp=/usr/local --with-mpfr=/usr/local \
      --with-mpc=/usr/local --with-cloog=/usr/local --disable-nls \
      --disable-multilib --disable-libssp --with-newlib \
      --with-headers=/home/syohei/src/newlib-1.19.0/newlib/libc/include
   % make
   % make -j2

newlibの作成

   % cd newlib-1.19.0
   % mkdir build && cd build
   % ../configure --target=h8300-linux-elf --prefix=/home/syohei/local/h8300 \
      --disable-nls
   % make
   % make install

gdbの作成

   % tar xf gdb-7.3.tar.bz2
   % cd gdb-7.3
   % mkdir build && cd build
   % ../configure --target=h8300-linux-elf --prefix=/home/syohei/local/h8300 \
      --disable-nls
   % make
   % make install

チェック

以下のコードで各データ型のサイズを見てみます。

#include <stdio.h>

int main (void)
{
  printf("size of char      = %d\n", sizeof(char));
  printf("size of short     = %d\n", sizeof(short));
  printf("size of int       = %d\n", sizeof(int));
  printf("size of long      = %d\n", sizeof(long));
  printf("size of long long = %d\n", sizeof(long long));
  printf("size of pointer   = %d\n", sizeof(void*));
  return 0;
}

以下で確認

   % h8300-linux-elf-gcc size.c
   % h8300-linux-elf-run a.out
   size of char        = 1
   size of short      = 2
   size of int          = 2
   size of long       = 4
   size of long long = 8
   size of pointer   = 2

intが 2バイト、ポインタが2バイトということがわかります。
今時の携帯電話のような高性能な機器であれば、32ビットが
普通ですが、組み込みではまだこういうのが使われています。
機器によっては 8ビット CPUというのも未だ現役で使われて
います。


PCばっかりでやってると気づきませんが、このように各型の
サイズはアーキテクチャによりよりまちまちであるので、
データ長が保証されたサイズ(C99のstdint.hに定義される型)を
使うことが望ましいわけです。

テスト

Testgenを使ってテストして見ました。
最新の Testgenは以下にあります。


syohex/p5-Testgen · GitHub

コンフィギュレーションファイル

以下のようにしました。

+{
    compiler      => 'h8300-linux-elf-gcc',
    simulator     => 'h8300-linux-elf-run',
    c_flags       => [ '-g', '-Dunix' ],
    ld_flags      => [ '' ],
    options       => [ '-O0', '-O2' ],
    testdir       => 'testsuite_h8300',
    compile_only  => 0,

    size => {
         char  => 8,
         short => 16,
         int   => 16,
         long  => 32,
         pointer => 16,
    },

    timeout       => 10,
    parallels     => 2,
}
テストの実行
   % perl bin/tgen.pl --config=h8300_cross.cnf template/*.tt 
   % cd testsuite_8300
   % ./runtest.pl
テスト結果

c89.4-2-05/lt2906.cを '-O2'オプションでコンパイルしたときのみ
失敗しています。該当のプログラムは以下のとおり。

long dummy1(unsigned (*) (unsigned), unsigned);
unsigned divide4(long);
long dummy2(long (*) (long), unsigned);
long divide2(long);

short           statusFlag = NoMistake;

int main(void)
/*
 * test class: simple arithmatic expression ( case 2 ) instance  : linear tree structure, return value, legal pointer to
 * function returning a long
 */
{
	unsigned        i = 3;

	i = dummy1(divide4, i *= 4);
	if (i != 3L)
		statusFlag++;
	if (statusFlag == NoMistake)
		printok();
	else
		printno();
	return 0;
}

long dummy1(unsigned (*func) (unsigned), unsigned Long)
{
	long            i = (long) Long;

	i = (*func) (i % 100);
	if (i != 3L)
		statusFlag++;
	return i;
}

unsigned divide4(long Long)
{
	return dummy2(divide2, (unsigned) Long) / 2;
}

long dummy2(long (*func) (long), unsigned Long)
{
	long            i;

	i = (*func) ((long) Long);
	if (i != 6L)
		statusFlag++;
	return i;
}

long divide2(long Long)
{
	return Long / 2;
}

アセンブルで確認したところ、dummy1が呼ばれていないことが
原因のようです。インライン展開されているわけでもないのに、
divide4の方にいきなり飛んで、引数に値が正しく設定されていない
という現象が発生しています。


特殊なオプションをつけたわけでもないただの O2でこんなことが
起こるとなると、信頼度は低いと言わざるをえないですね。
商用でこのバージョンを使うというのは難しいのではないかと
思います。

最後に

h8300クロスコンパイラの作成方法について示しました。