RISC-Vのコンパイラでmin-rt-cをコンパイルしてみる
code:min-rt.c をコンパイルしてオブジェクトファイル(min-rt.o)を生成してみる
$ git clone git@github.com:keiichiw/min-rt-c.git
$ git clone git@github.com:keiichiw/ucc.git
$ cd min-rt-c
$ riscv32-unknown-elf-gcc -c min-rt.c -I ../ucc/include/
生成された min-rt.o を sizeコマンドでバイナリのサイズを確認してみる。
code:size min-rt.o の結果
$ size min-rt.o
text data bss dec hex filename
25312 16 104796 130124 1fc4c min-rt.o
本体は130KBくらい。ライブラリを入れたら多めに見積もって300KBくらい?ヒープとスタックの領域も必要になるのでNexys A7のブロックRAMでは少し心許ない感じ。SDRAM無しでレイトレーサを動かすには Nexys VideoぐらいのブロックRAMが必要かもなあ...(SDRAMを使うとCPU作成の難易度が急激に高まるのでできれば避けたい)
Nexys VideoのBRAM
1.6MB
Nexys A7のBRAM
0.5MB
Basys3のBRAM
0.2MB
次に、どのRISC-V命令を用意すればいいかを確認するため、min-rtで使われている命令の一覧を確認してみる。
code:min-rtで使われている命令一覧を取得
$ riscv32-unknown-elf-gcc -S min-rt.c -I ../ucc/include/
$ awk '{ print $1 }' min-rt.s | grep -v '\.' | grep -v ':' | sort | uniq
add
addi
andi
beq
bge
bgt
ble
blt
bne
call
fld
flw
fsd
j
jr
lbu
li
lui
lw
mul
mv
nop
rem
sb
seqz
slli
snez
srai
srli
sub
sw
自作のRISC-Vサブセットでは未実装な命令がいくつかあるものの、そこは出力されたアセンブラを書き換えてあげれば行けそうな気がする。
自前で実装が必要そうな関数たち
シンボルテーブルを見てたら以下の関数たちは自前で実装する必要がありそうな。mallocとかfreeとかが悩ましいですね。
code:sh
$ riscv-none-embed-readelf -s min-rt.o | grep UND
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
363: 00000000 0 NOTYPE GLOBAL DEFAULT UND getchar
364: 00000000 0 NOTYPE GLOBAL DEFAULT UND __extendsfdf2
367: 00000000 0 NOTYPE GLOBAL DEFAULT UND putchar
369: 00000000 0 NOTYPE GLOBAL DEFAULT UND printf
370: 00000000 0 NOTYPE GLOBAL DEFAULT UND __eqdf2
371: 00000000 0 NOTYPE GLOBAL DEFAULT UND __gtdf2
373: 00000000 0 NOTYPE GLOBAL DEFAULT UND __muldf3
374: 00000000 0 NOTYPE GLOBAL DEFAULT UND __adddf3
375: 00000000 0 NOTYPE GLOBAL DEFAULT UND __divdf3
377: 00000000 0 NOTYPE GLOBAL DEFAULT UND sqrt
379: 00000000 0 NOTYPE GLOBAL DEFAULT UND __subdf3
381: 00000000 0 NOTYPE GLOBAL DEFAULT UND cos
382: 00000000 0 NOTYPE GLOBAL DEFAULT UND sin
385: 00000000 0 NOTYPE GLOBAL DEFAULT UND __ltdf2
386: 00000000 0 NOTYPE GLOBAL DEFAULT UND __nedf2
389: 00000000 0 NOTYPE GLOBAL DEFAULT UND __assert_fail
391: 00000000 0 NOTYPE GLOBAL DEFAULT UND malloc
392: 00000000 0 NOTYPE GLOBAL DEFAULT UND memset
395: 00000000 0 NOTYPE GLOBAL DEFAULT UND free
428: 00000000 0 NOTYPE GLOBAL DEFAULT UND __floatsidf
436: 00000000 0 NOTYPE GLOBAL DEFAULT UND abort
441: 00000000 0 NOTYPE GLOBAL DEFAULT UND floor
442: 00000000 0 NOTYPE GLOBAL DEFAULT UND atan
458: 00000000 0 NOTYPE GLOBAL DEFAULT UND __fixdfsi
466: 00000000 0 NOTYPE GLOBAL DEFAULT UND calloc
469: 00000000 0 NOTYPE GLOBAL DEFAULT UND tan
uccを参考にできるかもな関数
malloc
free
sqrt
cos
sin
floor
atan
memset
abort
getchar
putchar
printf
覚書
$ riscv-none-embed-gcc --specs=nosys.specs min-rt.c -I /Users/thata/src/learn-fpga/FemtoRV/FIRMWARE/TOOLCHAIN/xpack-riscv-none-embed-gcc-10.1.0-1.1-darwin-x64/riscv-none-embed/include/ -L /Users/thata/src/learn-fpga/FemtoRV/FIRMWARE/TOOLCHAIN/xpack-riscv-none-embed-gcc-10.1.0-1.1-darwin-x64/riscv-none-embed/lib/ -lm
ビルドが通った
参考
自作CPU向けCコンパイラをつくってOS動かした話 (CPU実験まとめ)