ぼくのかんがえたさいきょうCPU:命令エミュレーションについて

 昔の汎用機(System/360以降)は上位機種から下位機種まで命令互換で価格に応じて拡張性や性能が違っていた。上位機種は最先端の半導体テクノロジーを採用し積極的に布線論理(ハードワイヤド)で実装、下位機種はこなれた半導体テクノロジーで集積度や動作速度も遅く、マイクロ命令で実装していた。ということを参考にするとよく使う命令はハードで実装し、使用頻度の低い命令は未実装命令でトラップを発生させ、トラップハンドラで処理して戻すようにすればよい。以下のように分けてみる。

L0: 必須命令 基本的な整数ADD/SUB、論理演算、分岐、ロード/ストア、WR(レジスタ書き込み)命令
L1: 未実装命令 MUL/DIVなどハード実装しなくてもよい命令
L2: 型(浮動小数点など)、レーン(SIMD)、データ幅が直接扱えないもの
L3: 未定義命令

 未実装命令そのものと扱えないオペランドについて分けてみた。


 さて、ほとんどの命令は以下のようにRa,Rb,Rc入力とRd,Re,Rf出力を扱う。

ALU.png

 未実装命令でL1命令トラップが発生したら、トラップハンドラで命令エミュレーションの処理を行う。トラップハンドラではRa〜Rfの値をトラップハンドラ内のメモリ空間に割り当ててロード/ストアで参照できる。汎用レジスタのセットは新規に割り当てられる。トラップハンドラの先頭で命令の種別を判定し、Ra,Rb,Rcを参照して対応する演算を行い、Rd,Re,Rfに書き込む。Rd,Re,Rfに対応する値はトラップハンドラ終了時に書き戻され、汎用レジスタの値は破棄され呼び出し元のセットに戻される。

 高速化のためには命令種別によるエントリポイントの複数化、Ra〜Rfへのポインタをトラップの先頭で汎用レジスタにセットするなど。

 オペランドがハードで用意したレジスタのサイズを越える、サポートしていない型であるL2命令トラップは、Ra,Rb,Rcのサイズと型をチェックして発生する。その原因となる扱えない型やサイズは、その命令以前に実行した型やサイズを設定する命令、ロード命令でRa,Rb,Rcのいずれかに定義されている。扱えないサイズのデータはあらかじめ確保してあるRa〜Rfに対応するメモリ空間上に置かれる。あとは型を見て浮動小数点変換を行う、SIMDなら繰り返し演算を行うなどして戻る。

 ハードウェアで直接サポートできるデータ幅、型がわかる固定値のレジスタがあればよい。命令エミュレーションのリソース確保とエントリポイントの設定を行ったら、その命令エミュレーションを利用するユーザモードや特権モードから見えるレジスタにサポートできるデータ幅や型の情報を書き込めれば良い。

 命令トラップの優先度はL3>L2>L1となる。L2命令トラップでオペランドを確認したあと、命令そのものが未実装ならL1命令トラップが呼び出されて処理される。命令エミュレーショントラップ中にさらに同種の命令エミュレーショントラップを発生させることはしない。

 未定義命令であるL3とオペランドだけを処理するL2の優先度は考える必要がある。いまのところ未定義命令であればオペランドも未定義であるとすればこの優先度でよい。

世界名作劇場・完結版 トラップ一家物語 [DVD]
世界名作劇場・完結版 トラップ一家物語 [DVD]

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント