2020年04月15日
RISC-Vベクトル拡張対応のGCCツールチェーンをビルドする(Linuxホスト)
RISC-V のベクトル拡張は現在策定中の仕様です。最新安定板はバージョン 0.8 で、一つ前は 0.7.1 でした。そのためインターネット上には古い情報と新しい情報が混在しています。
この記事もすぐに古くなると思いますが、開発版の 0.9.x ベースの GCC ツールチェーンの動作確認ができたので、シェルスクリプト化して公開します。
この記事もすぐに古くなると思いますが、開発版の 0.9.x ベースの GCC ツールチェーンの動作確認ができたので、シェルスクリプト化して公開します。
確認環境は Ubuntu 18.04 で、以下のツールを apt-get しておいてください。
$ sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev libreadline-dev libppl-dev libcloog-ppl-dev以下がシェルスクリプト本体(build_riscv_gcc.sh)です。何をやっているかわかりやすいように、あえてコマンドラインをべた書きしただけのものになっています。32 bit ターゲットと 64 bit ターゲットのツールを両方ビルドします。このスクリプトを実行すると、サブディレクトリ obj.XXX(XXX はプロセス ID)内でソースコードをダウンロード、ビルド、インストールします。
set -x -e [ -z $TOP ] && export TOP=$PWD/obj.$$ [ -z $PARA ] && export PARA=-j8 mkdir -p $TOP export RISCV=$TOP/install mkdir $RISCV export PATH=$RISCV/bin/:$PATH SRC=$TOP/src mkdir $SRC cd $SRC git clone -b rvv-0.9.x --depth 1 https://github.com/riscv/riscv-binutils-gdb.git cd riscv-binutils-gdb/ git branch git log -n 1 cd $SRC git clone --depth 1 https://github.com/riscv/riscv-gcc.git cd riscv-gcc/ git branch git log -n 1 cd $SRC git clone --depth 1 https://github.com/riscv/riscv-newlib.git cd riscv-newlib/ git branch git log -n 1 cd $SRC git clone --depth 1 https://github.com/riscv/riscv-isa-sim.git cd riscv-isa-sim git branch git log -n 1 cd $SRC git clone --depth 1 https://github.com/riscv/riscv-pk cd riscv-pk/ git branch git log -n 1 cd $SRC [ -z $ARCH32 ] && export ARCH32=rv32gcv [ -z $ABI32 ] && export ABI32=ilp32d [ -z $TARGET32 ] && export TARGET32=riscv32-unknown-elf BUILD32=$TOP/build32 mkdir $BUILD32 cd $BUILD32 mkdir binutils cd binutils/ $SRC/riscv-binutils-gdb/configure --prefix=$RISCV --target=$TARGET32 --enable-multilib --disable-gdb make $PARA && make install cd $BUILD32 mkdir stage1_gcc cd stage1_gcc/ $SRC/riscv-gcc/configure --prefix=$RISCV --target=$TARGET32 --enable-multilib --enable-languages=c --without-headers make $PARA all-gcc && make install-gcc cd $BUILD32 mkdir newlib cd newlib/ $SRC/riscv-newlib/configure --prefix=$RISCV --target=$TARGET32 --enable-multilib make $PARA all && make install cd $BUILD32 mkdir gcc cd gcc/ $SRC/riscv-gcc/configure --prefix=$RISCV --target=$TARGET32 --enable-multilib --enable-languages=c,c++ --with-newlib make $PARA all && make install cd $BUILD32 mkdir spike cd spike/ $SRC/riscv-isa-sim/configure --prefix=$RISCV --with-isa=$ARCH32 make $PARA && make install cd $BUILD32 mkdir pk cd pk/ $SRC/riscv-pk/configure --prefix=$RISCV --host=$TARGET32 --with-arch=$ARCH32 --with-abi=$ABI32 make $PARA && make install cd $BUILD32 mkdir ../test32 cd ../test32/ echo -e '#includecore i7 6700k の少し古い PC で 32 分ぐらいかかりました。\nint main(){puts("Hello, rv32!");}' > main.c $RISCV/bin/$TARGET32-gcc -mabi=$ABI32 -march=$ARCH32 main.c $RISCV/bin/spike --isa=$ARCH32 $RISCV/$TARGET32/bin/pk a.out [ -z $ARCH64 ] && export ARCH64=rv64gcv [ -z $ABI64 ] && export ABI64=lp64d [ -z $TARGET64 ] && export TARGET64=riscv64-unknown-elf BUILD64=$TOP/build64 mkdir $BUILD64 cd $BUILD64 mkdir binutils cd binutils/ $SRC/riscv-binutils-gdb/configure --prefix=$RISCV --target=$TARGET64 --enable-multilib --disable-gdb make $PARA && make install cd $BUILD64 mkdir stage1_gcc cd stage1_gcc/ $SRC/riscv-gcc/configure --prefix=$RISCV --target=$TARGET64 --enable-multilib --enable-languages=c --without-headers make $PARA all-gcc && make install-gcc cd $BUILD64 mkdir newlib cd newlib/ $SRC/riscv-newlib/configure --prefix=$RISCV --target=$TARGET64 --enable-multilib make $PARA all && make install cd $BUILD64 mkdir gcc cd gcc/ $SRC/riscv-gcc/configure --prefix=$RISCV --target=$TARGET64 --enable-multilib --enable-languages=c,c++ --with-newlib make $PARA all && make install cd $BUILD64 mkdir spike cd spike/ $SRC/riscv-isa-sim/configure --prefix=$RISCV --with-isa=$ARCH64 make $PARA && make install cd $BUILD64 mkdir pk cd pk/ $SRC/riscv-pk/configure --prefix=$RISCV --host=$TARGET64 --with-arch=$ARCH64 --with-abi=$ABI64 make $PARA && make install cd $BUILD64 mkdir ../test64 cd ../test64/ echo -e '#include \nint main(){puts("Hello, rv64!");}' > main.c $RISCV/bin/$TARGET64-gcc -mabi=$ABI64 -march=$ARCH64 main.c $RISCV/bin/spike --isa=$ARCH64 $RISCV/$TARGET64/bin/pk a.out
$ time ./build_riscv_gcc.sh > build.log 2>&1 real 32m50.194s user 117m41.893s sys 11m48.754sベクトル命令の動作確認例です。テストには msyksphinz 氏のブログのコードを使わせていただきました。
~/test/RISCV$ ./obj.23850/install/bin/riscv64-unknown-elf-gcc -mabi=lp64d -march=rv64gcv rvv.c -o rvv ~/test/RISCV$ ./obj.23850/install/bin/spike ./obj.23850/install/riscv64-unknown-elf/bin/pk rvv bbl loader calling v_test 0.000000, 127.000000, 252.000000, 375.000000, 496.000000, 615.000000, 732.000000, 847.000000, 960.000000, 1071.000000, 1180.000000, 1287.000000, 1392.000000, 1495.000000, 1596.000000, 1695.000000, 1792.000000, 1887.000000, 1980.000000, 2071.000000, 2160.000000, 2247.000000, 2332.000000, 2415.000000, 2496.000000, 2575.000000, 2652.000000, 2727.000000, 2800.000000, 2871.000000, 2940.000000, 3007.000000, 3072.000000, 3135.000000, 3196.000000, 3255.000000, 3312.000000, 3367.000000, 3420.000000, 3471.000000, 3520.000000, 3567.000000, 3612.000000, 3655.000000, 3696.000000, 3735.000000, 3772.000000, 3807.000000, 3840.000000, 3871.000000, 3900.000000, 3927.000000, 3952.000000, 3975.000000, 3996.000000, 4015.000000, 4032.000000, 4047.000000, 4060.000000, 4071.000000, 4080.000000, 4087.000000, 4092.000000, 4095.000000, 4096.000000, 4095.000000, 4092.000000, 4087.000000, 4080.000000, 4071.000000, 4060.000000, 4047.000000, 4032.000000, 4015.000000, 3996.000000, 3975.000000, 3952.000000, 3927.000000, 3900.000000, 3871.000000, 3840.000000, 3807.000000, 3772.000000, 3735.000000, 3696.000000, 3655.000000, 3612.000000, 3567.000000, 3520.000000, 3471.000000, 3420.000000, 3367.000000, 3312.000000, 3255.000000, 3196.000000, 3135.000000, 3072.000000, 3007.000000, 2940.000000, 2871.000000, 2800.000000, 2727.000000, 2652.000000, 2575.000000, 2496.000000, 2415.000000, 2332.000000, 2247.000000, 2160.000000, 2071.000000, 1980.000000, 1887.000000, 1792.000000, 1695.000000, 1596.000000, 1495.000000, 1392.000000, 1287.000000, 1180.000000, 1071.000000,pk は Proxy Kernel という極小の OS のようなもの(RISC-V プログラムの ELF ファイル)で、これがテストコード中の printf などの IO を処理しているようです。 varch オプションが参考ブログ記事のようには動作しなかったのですが、バージョンの違いでしょうか?
~/test/RISCV$ ./obj.23850/install/bin/spike --varch=v512:e32:s32 ./obj.23850/install/riscv64-unknown-elf/bin/pk rvv error: bad --varch option v512:e32:s32: Unsupported token