FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V for LLVMのビルド試行 (2. RISC-Vターゲットでのコンパイルとテスト)

f:id:msyksphinz:20181111134229p:plain

RISC-V on LLVMについて少し調べている。 LLVMソースコードを眺めていると、TargetとしてRISC-Vが追加されているのを発見した。 なんだ、追加されてるじゃないか。じゃあ動くんじゃないか。

という訳で最新版のLLVM(ver 8.0?)とClangを落としてきて、パッチを当てずにターゲットをRISC-Vにしてビルドを試行した。

mkdir build-llvm
cd build-llvm
cmake -G Ninja -DCMAKE_BUILD_TYPE="Release" -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="RISCV" ../llvm
cmake --build .

一応ビルドは成功したようだ。 テストプログラムを流してみる。まずは、オブジェクトを生成するだけ。

$ cat hello.c
int test_int(int a, int b) {
  return a + b;
}

float test_float(float a, float b) {
  return a + b;
}
$ ./bin/clang --target=riscv64-unknown-elf -O3 hello.c -c -o hello.o
fatal error: error in backend: Cannot select: 0x7fffd2df4fb8: i64 = sign_extend_inreg 0x7fffd2df4f50, ValueType:ch:i32
  0x7fffd2df4f50: i64 = add 0x7fffd2df4c78, 0x7fffd2df4ba8
    0x7fffd2df4c78: i64 = AssertSext 0x7fffd2df4ad8, ValueType:ch:i32
      0x7fffd2df4ad8: i64,ch = CopyFromReg 0x7fffd2d9fc78, Register:i64 %1
        0x7fffd2df4a70: i64 = Register %1
    0x7fffd2df4ba8: i64 = AssertSext 0x7fffd2df4a08, ValueType:ch:i32
      0x7fffd2df4a08: i64,ch = CopyFromReg 0x7fffd2d9fc78, Register:i64 %0
        0x7fffd2df49a0: i64 = Register %0
In function: test_int
clang-8: error: clang frontend command failed with exit code 70 (use -v to see invocation)
clang version 8.0.0 (https://git.llvm.org/git/clang.git/ 3919b8d9833d23d98e8be71fe608627866d5c40c) (https://git.llvm.org/git/llvm.git 20a1e3c6acad46a947e7633f39c83eb00de22ea2)
Target: riscv64-unknown-unknown-elf
Thread model: posix
InstalledDir: /home/msyksphinz/work/riscv/llvm-build/./bin
clang-8: note: diagnostic msg: PLEASE submit a bug report to https://bugs.llvm.org/ and include the crash backtrace, preprocessed source, and associated run script.
clang-8: note: diagnostic msg:
********************

PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT:
Preprocessed source(s) and associated run script(s) are located at:
clang-8: note: diagnostic msg: /tmp/hello-3a45a2.c
clang-8: note: diagnostic msg: /tmp/hello-3a45a2.sh
clang-8: note: diagnostic msg:

********************

うお、いきなり落ちた!まだきちんと対応していないのか?

と思ったら、よく考えたらまだriscv32の対応に限定されているのか。riscv32-unknown-elfでリコンパイルしてみる。

$ ./bin/clang --target=riscv32-unknown-elf -O3 hello.c -c -o hello.o
$ riscv64-unknown-elf-objdump -d hello.o

hello.o:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <test_int>:
   0:   00a58533                add     a0,a1,a0
   4:   00008067                ret

00000008 <test_float>:
   8:   ff010113                addi    sp,sp,-16
   c:   00112623                sw      ra,12(sp)
  10:   00000097                auipc   ra,0x0
  14:   000080e7                jalr    ra
  18:   00c12083                lw      ra,12(sp)
  1c:   01010113                addi    sp,sp,16
  20:   00008067                ret

ちゃんと生成できている。と思ったらtest_floatの方は様子が変だぞ。こんなコードで浮動小数点の加算ができるはずがない。

ちゃんと-marchを指定しなきゃだめだ。

$ ./bin/clang --target=riscv32-unknown-elf -march=rv32gc -O3 hello.c -c -o hello.o
$ riscv64-unknown-elf-objdump -d hello.o

hello.o:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <test_int>:
   0:   952e                    add     a0,a0,a1
   2:   8082                    ret

00000004 <test_float>:
   4:   f0058053                fmv.w.x ft0,a1
   8:   f00500d3                fmv.w.x ft1,a0
   c:   0000f053                fadd.s  ft0,ft1,ft0
  10:   e0000553                fmv.x.w a0,ft0
  14:   8082                    ret

よく考えたらこれもおかしい。なんで整数レジスタ経由で渡しているんだ?ABIを変えてみよう。

$ ./bin/clang --target=riscv32-unknown-elf -march=rv32gc -mabi=ilp32 -O3 hello.c -c -o hello.o
$ riscv64-unknown-elf-objdump -d hello.o

hello.o:     file format elf32-littleriscv


Disassembly of section .text:

00000000 <test_int>:
   0:   952e                    add     a0,a0,a1
   2:   8082                    ret

00000004 <test_float>:
   4:   f0058053                fmv.w.x ft0,a1
   8:   f00500d3                fmv.w.x ft1,a0
   c:   0000f053                fadd.s  ft0,ft1,ft0
  10:   e0000553                fmv.x.w a0,ft0
  14:   8082                    ret

それでも直らない。float経由で引数を渡すABIはあるはずだけど...