MMIX
MMIX(エムミックス)は、ドナルド・クヌースがジョン・ヘネシー(MIPSプロセッサ設計者)や Dick Sites(Alphaプロセッサ設計者)の協力を得て設計した命令セット(命令セットアーキテクチャ、ISA)である。コンピュータプログラミングの「Art」を記している大著The Art of Computer Programming (TAoCP) において使用していた「MIX」の代替となるべく設計され、現代的な特徴を持つ。当命令セットを設計した後に執筆・改訂の TAoCP にて既に使用されている。
"MMIX" という綴りはローマ数字として解釈すると2009であり、前任のMIXの頭にMを付けたものであると同時に、2000年代のコンピュータ(プロセッサ)という意味を掛けているものと思われる(とはいえ、MIXの時の「実在のコンピュータ 16 種の型番から取って平均した」値の1009である、という主張にはかなりこじつけの気配があったのと同様、特に意味があるものではない)。
MMIX は二進法コンピュータであり(MIXでは十進を併用していた)、64ビット仮想アドレス空間と32ビット幅の命令セットを持つ(ビッグエンディアン方式)。
命令は32ビット幅で、一般に "OP X, Y, Z" という形式である。OPは命令コード、Xに結果が返され、それぞれのフィールドは8ビット幅である。例えば、加算命令 (ADD) の命令コードは32となっている。Xオペランドは通常演算結果を格納するレジスタを指定する。他のオペランドは演算対象のレジスタを指定する。例えば、"ADD $0, $1, 3" はレジスタ 1 と即値 3 を加算してレジスタ 0 に結果を格納する(Zオペランドを即値として扱う ADDI 命令の命令コードは 33 だが、同じ ADD というニーモニックを使用)。MMIXプログラムは MMIXALアセンブリ言語で書かれる。
MMIXチップには256本のアークテクチャ上の汎用レジスタがあり、$0 から $255 で表される。他に32本の専用レジスタを持つ。MMIX は後述するレジスタスタック機能を持つ。レジスタスタックに使用するレジスタをローカルレジスタ、任意のルーチンからアクセス可能なレジスタをグローバルレジスタと呼ぶ。ローカルレジスタは $0 から始まり rL レジスタで指定される番号のレジスタまで、グローバルレジスタは rG レジスタで指定される番号のレジスタから $255 までとなっている。ローカルレジスタはサブルーチン呼び出しの際に自動的に切り替えられる(切り替えない呼び出し方法もある)。物理的なレジスタの構成はMMIXでは規定されていないが、例えばグローバルレジスタを 256-32本、ローカルレジスタを512本物理的に用意するなどの構成が考えられる。
ローカルレジスタスタックはレジスタ・ウィンドウに似ているが、具体的な実装方式は定義されておらず、あくまでもユーザーから見た見え方のみが定義されている。ローカルレジスタスタックを使用すると、各サブルーチンは $0 から $(rL-1) までをローカルレジスタとして持つ(rLレジスタは専用レジスタ)。どちらでもない汎用レジスタはマージナルレジスタと呼ばれる。マージナルレジスタをオペランドに使用すると自動的にそのレジスタまでがローカルレジスタとなる(入力オペランドとして使用すると、値は 0)。例えば、ルーチン A が $0 から $4 までをローカルレジスタに使用していて、引数を2つ持つルーチン B を呼び出す場合、$5 をルーチン B の結果格納域とし、$6 と $7 に引数を設定してルーチンBを呼び出す。そうするとルーチンBでは$6だった物理レジスタが $0、$7だった物理レジスタが $1 として見えるようになる。ルーチン B のリターン値を $0 に格納してルーチン A に戻ると、ルーチンA からは $5 にそのリターン値が見えることになる($0 から $4 は B を呼び出す前と同じものが復帰している)。物理レジスタには限りがあるため、全コールスタックをレジスタに保持することはできない。スタック内容のレジスタからメモリへの移動(またはその逆)は自動的に行われ、rO レジスタと rS レジスタがメモリ上のスタックとレジスタスタックの関連付けを行う。
MMIXには以下のような32本の専用レジスタがある。
rB(g[0]):ブートストラップレジスタ(トリップ)
トリップ時、rB ← $255 および $255 ← rJ が行われる。 従って rJ が汎用レジスタにセーブされる。
rD (g[1]):被序数レジスタ
符号無し整数除算で 128ビット被序数の上位64ビットとして使用される。
rE (g[2]):イプシロンレジスタ
浮動小数点数のイプシロンに関する比較に使用。
rH (g[3]):乗算上位レジスタ
符号無し整数乗算で 128ビットの積の上位64ビットを格納。
rJ (g[4]):リターンジャンプレジスタ
PUSH命令で次の命令アドレスを格納し、後に POP 命令で戻る際に使用する。
rM (g[5]):多重化マスクレジスタ
MUX命令で使用($X ← ($Y & rM)|($Z & ~rM))
rR (g[6]):剰余レジスタ
整数除算で剰余を格納。
rBB (g[7]):ブートストラップレジスタ(トラップ)
トラップ時、rBB ← $255 および $255 ← rJ が行われる。従って rJ が汎用レジスタにセーブされる。
rC (g[8]):サイクルカウンタ
サイクル毎にインクリメントされる。
rN (g[9]): シリアル番号
rO (g[10]):レジスタスタックオフセット
rS (g[11]):レジスタスタックポインタ
rI (g[12]):インターバルカウンタ
サイクル毎にデクリメントされる。ゼロになると割り込みを発生。
rT (g[13]):トラップアドレスレジスタ
rTT (g[14]):動的トラップアドレスレジスタ
rK (g[15]):割り込みマスクレジスタ
rQ (g[16]):割り込み要求レジスタ
rU (g[17]):使用量カウンタ
rV (g[18]):仮想変換レジスタ
仮想物理アドレス変換のためのレジスタ。セグメントのサイズと大きさ、ページテーブルの位置と仮想空間番号などを保持。
rG (g[19]):グローバル閾値レジスタ
$(rG)から R255までをグローバルレジスタとして使用。
rL (g[20]):ローカル閾値レジスタ
$0から$(rL-1)までをローカルレジスタとして使用。
rA (g[21]):数値演算状態レジスタ
オーバフローやゼロ除算などの算術例外の記録およびイネーブル/ディセーブル設定。
rF (g[22]):フェイルアドレスレジスタ
障害を発生した命令のアドレスを格納。
rP (g[23]):予測レジスタ
コンペア・アンド・スワップ命令で使用。
rW (g[24]):割り込み箇所レジスタ(トリップ)
トリップ時、次の命令のアドレスを保持。
rX (g[25]):実行レジスタ(トリップ)
トリップ時、現在の命令そのものを保持。
rY (g[26]): Yオペランド(トリップ)
トリップ時、現在の命令のYオペランドを保持。
rZ (g[27]): Zオペランド(トリップ)
トリップ時、現在の命令のZオペランドを保持。
rWW (g[28]):割り込み箇所レジスタ(トラップ)
トラップ時、次の命令のアドレスを保持。
rXX (g[29]):実行レジスタ(トラップ)
トラップ時、現在の命令そのものを保持。
rYY (g[30]): Yオペランド(トラップ)
トラップ時、現在の命令のYオペランドを保持。
rZZ (g[31]): Zオペランド(トラップ)
トラップ時、現在の命令のZオペランドを保持。
トリップとはユーザーレベルの例外処理機構であり、トリップが発生するとユーザー空間の固定アドレス(0番地)にジャンプする。トラップはオペレーティングシステムに飛び込む機構である。上記専用レジスタの説明に「トリップ」とあるのはトリップ発生時に使用されるコンテキスト保持のレジスタ、「トラップ」とあるのはトラップ発生時に使用されるコンテキスト保持のレジスタである。