《おまけ》SuperH-2シミュレータ　中森章

　このファイルを見ているということは，筆者のシミュレータに興味があって，わざわざダウンロードしてくれた方ですよね？ありがとうございます．
　本誌では，RISC-VとCortex-M0のシミュレータを解説しましたが，暇なので，SuperH-2（SH-2）のシミュレータも作成してみました．使い方は他と同じです．
　さて，問題はコンパイラをどこからもってくるかですが，ネットを検索してもコンパイル済みでフリーなSH-2向けコンパイラをなかなか見つけることができません．果たして，CQ出版のInterface誌のダウンロード・サイト（以下）から，ARM，SH，RX，V850，M68K，FR30向けのGCC（Cygwin用）をダウンロードすることができることが判明しました．

http://www.cqpub.co.jp/interface/download/contents.htm
2013年12月号のところを参照してください．

…で，早速ダウンロードしてCygwin上で動かしてみようとしたのですが，「libiconv-2.dllという共有ライブラリがない」というエラー・メッセージが出力されてGCCが起動しません．これで，半ば諦めかけたのですが，以下のサイトなどからフリーのlibiconv-2.dllをダウンロードしてきて，Cygwinのbinディレクトリに格納したら，無事GCCが動作するようになりました．

https://jp.dll-files.com/libiconv-2.dll.html
何でこんな大事なファイルがデフォルトで用意されてないのか不思議です．恐らくは，昔のCygwinではサポートされていたのでしょうね．

　SH-2版のGCCではincludeディレクトリが空になっています．通常のCソースをコンパイルするためには，少なくとも，stdio.hやstdlib.hが必要になります．空のファイルでいいので，ダミーでこれらのヘッダ・ファイルを作成しておきましょう．また，GCCがデフォルトでは標準includeディレクトリを参照しません．「-I」オびっぐプションで標準のincludeディレクトリを指定してください．
　たとえば．

 d:/gcc-481/local/sh/bin/sh-elf-gcc -o dhry2.out -O2 -m2 -nostdlib -Ttext 8000 dhry_all.c -Id:/gcc-481/local/sh/include -lgcc

という感じです．「-m2」はSH-2用のコードを生成することを意味します．SH-1用のコードならば「-m1」を指定します．

　さて，今回SH-2のシミュレータを作るモチベーションは，ずばり「ビッグ・エンディアン」です．これまで作ってきた，RISC-V，ARM（Cortex-M0），MIPSのシミュレータは「リトル・エンディアン」専用でした．逆に，ビッグ・エンディアンのELFをロードすると暴走してしまいます．そこで「load.c」ファイルと「mem.c」ファイルの修正が必要です．どのように修正したかは実際の中身をみてください．良心的な作成者なら，リトル・エンディアンとビッグ・エンディアンを共存させるようにするのでしょうが，ものぐさな筆者はそこまで対応していません．

　今回，SH-2のシミュレータを作って実感したSH-2アーキテクチャの特徴は以下の通りです．
・16ビット固定長命令
・分岐命令も16ビット長なので，1回で分岐できる範囲に制限がある．このため，プログラムは，分岐の先に分岐というように，分岐命令が多用される．
・基本的に分岐遅延スロットがあるが，Tレジスタを参照する条件分岐には遅延スロットのないものも存在する．
・ロード/ストア命令（ニーモニックはMOV）のバリエーションが豊富．プレ・デクリメント，ポスト・インクリメント・アドレシングも存在する．
・定数値のロードは（即値の場合もあるが），PC相対ロードが多用される．コンパイルされたコードを見ると，命令の中にリテラル・プールが多く見られる（逆アセンブル結果が汚い）．
・除算命令は，1ステップを計算する命令を32回繰り返して実現する．
・アトミック命令が豊富（マルチコアを構成しやすい）．このシミュレータでは，コンパイラが出力しないので，実装していない．

これらの特徴をシミュレータで確認してみてください．

[EOF]

