《おまけ》MIPS R3000シミュレータ 中森章

　このファイルを見ているということは，筆者のシミュレータに興味があって，わざわざダウンロードしてくれた方ですよね？ありがとうございます．
　本誌では，RISC-VとCortex-M0のシミュレータを解説しましたが，暇なので，R3000のシミュレータも作成してみました．使い方は他と同じです．
　MIPSって，身売りされて，コンパイラの入手が困難なのではと思っている人がいるかもしれませんね．実は，MIPSのサイトは生き残っていて，以下のサイトからコンパイラ（GCC）のダウンロードが可能です．
https://codescape.mips.com/components/toolchain/2017.10-07/downloads.html

C:\mips-mti-elf\2017.10-07\bin\mips-mti-elf-gcc -o dhry2.out -EL -O2 -march=r3000 -nostdlib -Ttext 8000 start.s dhry_all.c

のような感じでコンパイルをしてください．逆アセンブルは

C:\mips-mti-elf\2017.10-07\bin\mips-mti-elf-objdump -D dhry2.out > dhry2.txt

という感じです．ここで，「start.s」というファイルを追加したのは，毎回，main関数のアドレスを探しに行くのが煩わしいので，

----------------------------------------------
	.text
__start:	
	.extern	main
	ori	$sp,$0,0x7000
	jal	main
1:
	b	1b
----------------------------------------------
図1．start.sの内容

という、ファイルでmain関数を呼び出すようにしました．これで，start.sの内容が「.text」セクションの先頭に来ることを期待したのですが，そうは甘くありませんでした．
start.sの内容を先頭に持ってくるためには，リンカのスクリプトを使用しなければなりません．そのためには，以下のようなリンカ・スクリプトを作ってGCCに食わせます．

----------------------------------------------
SECTIONS
 {
   . = 0x8000;
   .text : { start.o(.text)
             dhry_all.o(.text) }
   .data : { *(.data) }
   .bss : { *(.bss) }
 }
----------------------------------------------
図2．リンカ・スクリプトldscript.txt（名前は任意）の内容

　この場合，「.s」や「.c」のままでいきなりコンパイルすることはできなくなり，まず「.o」ファイルを作ることが必要になります．つまり，

C:\mips-mti-elf\2017.10-07\bin\mips-mti-elf-gcc -c -EL -O2 -march=r3000 start.s
C:\mips-mti-elf\2017.10-07\bin\mips-mti-elf-gcc -c -EL -O2 -G0 -march=r3000 dhry_all.c
C:\mips-mti-elf\2017.10-07\bin\mips-mti-elf-gcc -o dhry2.out -EL -T ldscript.txt -nostdlib start.o dhry_all.o

というような感じです．これで，start.sの内容を「.text」セクションの先頭にもってくることができます．「-G0」オプション（「ゴー」ではなくて「ジー・ゼロ」です）は，MIPS特有の「大域変数をr28（$gp)相対でアクセスする特徴」を無効化するオプションです．これをつけないと大域変数の領域が64KBに制限されて，「.text」セクションの開始アドレスを自由に設定できなくなります（リンク時にエラーが出る）．

　さて，いきなりコンパイルの話から始めましたが，RISC-Vのシミュレータを作ったうえで，R3000のシミュレータを作る意義はあるのでしょうか？RISC-VもR3000（MIPS）も似たようなISAです．RISC-VとR3000の決定的な違いは，R3000には分岐遅延スロットがあるということです．それを，シミュレータでどのように実現したのかは，「execute.c」の中身を参照してください．

[EOF]

