R3000

IDT79R3051 R3000Aコア,命令キャッシュ4KB,TLB無し
R3000はMIPS I命令セットアーキテクチャ (ISA) のマイクロプロセッサで、ミップス社が開発し、1988年6月にリリースした。MIPSアーキテクチャとしては2つ目の実装であり、R2000の後継である。
オリジナルのR3000 はCPUと、メモリ管理および例外処理を担当するCP0と呼ばれる部分から構成される。またFPUはR3010という別チップであり、R3000と密に結合して使用される。キャッシュメモリは内蔵していないが、命令キャッシュとデータキャッシュのコントローラを内蔵し、それぞれ256KBまでの1次キャッシュを接続することができた。動作周波数は20MHzから最大で40MHzだが、主に30MHz、33MHzで使用されることが多い。1.2μmのCMOSプロセスで製造され、56 mm2 のチップサイズに11万5千個のトランジスタを集積している。
ミップス社は設計のみを行い、製造はメーカーに任せていた。R3000 を製造したメーカーとしては、IDT、LSIロジック、NEC、シーメンス、東芝などがある。SGIなどのワークステーションやサーバに使用された。また、派生品がPlayStationのプロセッサとしても使用され、組み込みシステムにも多く使われた。

**アーキテクチャ**
R3000のパイプライン構造
R3000 は、4つのコプロセッサをサポート可能なアーキテクチャとなっているが、実際に使っているのはふたつであり、CP0 としてメモリ管理ユニットと例外処理ユニットを内蔵し、CP1 として接続された FPU を制御する。後継アーキテクチャでは FPU の拡張命令を CP1X として従来 CP3用とされていたオペコード表に割り当てている。命令長は32ビット固定となっていて命令フェッチとデコードを単純化している。CPUのパイプラインは5段になっていて、実行ユニットとしてALU以外に、乗除算ユニットなどを持っている。CPUの汎用レジスタは32ビット×32本で、他に乗除算の結果を格納する専用レジスタ（32ビット×2本）とプログラムカウンタがある。
PlayStationはジオメトリエンジン（GTE）となるベクトル演算ユニットを未使用のCP2に割り当てて使用している。
R3000での基本的な仮想空間と物理空間の対応
CP0 は、以下のような機能を持つ。- ユーザモード、カーネルモードの設定- 例外発生時の原因情報を保持- メモリ管理機能。MIPSアーキテクチャでは仮想物理アドレス変換のためのTLBを直接ソフトウェアで制御するようになっており、そのための機能を実装している。TLBは64エントリのCAM（連想メモリ）であり、各エントリが4Kバイトのページをマップする。そのうち 8エントリは固定エントリと呼ばれ、OSが固定的に使用し、それ以外はランダムエントリとして無作為に入れ替えて使用する。OSのカーネルはTLBを操作する際に、TLBを使用しない空間（下記）で動作するか、固定TLBエントリでマップされた空間内で動作しなければならない。
** TLB を使用しないメモリアクセスも可能になっていて、右図のようになっている。kseg1 をメモリマップドI/Oに使用するため、I/Oをその位置に配置すると、TLBを使わずにアクセスできるメモリは512Mバイト以下となる。
** TLBミスが発生した場合、カーネルが処理を行う。これは他のアーキテクチャではハードウェアで実現している機能であり、ここを如何に最適化するかが性能に重要な影響を与える。OSが用意したページテーブルを仮想空間上で連続に配置しておくと高速にTLBのリフィル（置き換え）ができるよう設計されているが、そのためにはページテーブルがTLB上でマップされている必要があり、固定TLBエントリがこの用途のために使われることが多い。- キャッシュメモリはTLBの外側にあり、物理アドレスタグになっている。ダイレクトマップ方式であるため、物理アドレスがちょうど64Kバイトの倍数分だけ離れたところにある配列のコピーなどを行うとスラッシングが発生して劇的に性能が低下する。これは、ロード命令によってキャッシュ上に置かれたメモリ内容を直後のストア命令で置き換えてしまうため、次のロード命令でも再度メモリから読み込む必要が生じるために起こる。
FPU（R3010）は、以下のような特徴を持つ。- IEEE 754に準拠。- 32ビット×32本のレジスタ。倍精度演算では 64ビット×16本のレジスタとして使用。- 6段のパイプライン。実行ユニットは、加減算ユニット、乗算ユニット、除算ユニットの3つ。- CPUとは異なり、ステータス・レジスタを持っている。

**命令セットの概要**
命令は三種類のフォーマットに分類される（R, I, J）。Rフォーマットは三つのレジスタとオペコードから構成される。Iフォーマットは二つのレジスタと16ビットのイミディエート値（とオペコード）から構成される。Jフォーマットは6ビットのオペコードと26ビットのイミディエート値から構成される。
算術演算（加減算）は以下のような形式である。
add   $1,  $2,  $3 ; $1 = $2 + $3 (符号付)
addu  $1,  $2,  $3 ; $1 = $2 + $3 (符号無)
sub   $1,  $2,  $3 ; $1 = $2 - $3 (符号付)
subu  $1,  $2,  $3 ; $1 = $2 - $3 (符号無)
addi  $1,  $2, 100 ; $1 = $2 + 100 (符号無・符号拡張されたイミディエート値)
addiu $1,  $2, 100 ; $1 = $2 + 100 (符号付・符号拡張されたイミディエート値)
符号付き演算であるadd, sub, addiでは、オーバーフロー時に例外処理が発生する。一方、符号無し演算であるaddu, subu, addiuでは、オーバーフロー時に例外処理が発生しない。C言語ではオーバーフロー時に例外処理を行わないことや、負の数は2の補数で表現可能であることから、ほとんどの場合、符号無し演算が用いられる。
MIPSは、ロード・ストア型のアーキテクチャなので、メモリへのアクセスは基本的に以下のふたつの命令で実現される。
lw  $1, 100($2) ; $2 + 100 で示されるアドレスのメモリワード（32ビット）を $1 レジスタにロードする。
sw  $1, 100($2) ; $1 レジスタの内容（32ビット）を $2 + 100 で示されるアドレスのメモリにストアする。
分岐とジャンプ命令には、以下のようなものがある。これらは必ず次の命令を実行してからジャンプするため（ディレイスロット）、注意が必要である。
beq $1,  $2, 100 ; もし ($1 == $2) ならば、PC+4+100 へ飛ぶ。
slt $1,  $2,  $3 ; もし ($2 < $3) ならば $1 = 1、そうでなければ $1 = 0 。（これは正確には比較命令）
j       10000    ; 10000番地へ飛ぶ。
jal     10000    ; $31 = PC + 4 とした上で、10000番地へ飛ぶ。サブルーチンコールで使用する。
他に重要な命令として、以下のものがある。
lui $1, 100      ; イミディエート値 100 を $1 レジスタの上位16ビットに格納する。
MIPSでは、命令サイズが32ビットであるため、32ビットの定数やアドレスを一命令ではレジスタに格納できない。そこで、lui 命令と addiu 命令などを組み合わせて使用する。アセンブリ言語には32ビット定数をレジスタに格納するマクロ命令があり、マクロ命令のために汎用レジスタのうちのひとつをアセンブリ言語に固定的に割り当てている。

**コンパイラによるレジスタ使用法**
ハードウェアアーキテクチャ上、汎用レジスタの使用に次のような制約がある。- 汎用レジスタ $0 は常に内容が 0 であり、何を書き込んでも 0 のままである。- 汎用レジスタ $31 はサブルーチンコール時の jump and link 命令でリンクレジスタ（戻りアドレスを格納するレジスタ）として使われる。- HI レジスタと LO レジスタは整数の乗除算の結果を格納する。
これら以外に制約はない。
MIPSの用意したコンパイラなどのツール群は呼出規約の一環としてレジスタの使用法を規定している。これらの規定はハードウェアの制約ではないが、ツール群がこれに従っている関係で、MIPSアーキテクチャを採用したシステムではほぼ間違いなくこの規定に従ってレジスタを使用している。
なお、"Callee must preserve?" とは、あるルーチンの中でそのルーチンに入ってきたときの値を保持した状態で呼び出した側に戻る必要があることを意味する。例えば、$s-レジスタをルーチン内で使うときは、その内容をスタックに一時的に退避させなければならない。$sp と $fp はルーチンに入ってきたときにセーブされ、それぞれルーチン固有の固定値でインクリメントされる。そして、そのルーチンから戻るときに元の値に戻す。一方 $ra は jal 命令でルーチンに飛び込むときに自動的に変更される。$t-レジスタはサブルーチンを呼び出すと内容が破壊されるので、必要なら呼び出す側がセーブしておかなければならない。$at はアセンブラの仮想命令（マクロ命令）で一時変数として使われる。$t-レジスタだけを使って、サブルーチンを呼び出すことがないルーチンは、スタックにレジスタをセーブする必要がないため、$sp や $fp もセーブする必要がない。

**採用例**
R3000は大いに成功したマイクロプロセッサで、ワークステーションやサーバに各社が採用した。次のような例がある。- アーデントコンピュータ- シリコングラフィックス - Professional IRIS、Personal IRIS、Indigo 他- セイコーエプソン- ソニー - NEWS- ソニー・コンピュータエンタテインメント - PlayStation、PlayStation 2（PlayStationとの互換性のため）、- タンデムコンピューターズ - Cyclone/R、CLX/R- DEC - DECstation、DECsystem（マルチプロセッサ）- 日本電気 - EWS4800、UP4800- ピラミッド・テクノロジー- Prime Computer- Whitechapel Workstations - Hitech-20
組み込みシステム用にも採用され、当初はハイエンドとして、後には低コストの組み込みシステム用として長く使われた。LSI Logic などは組み込み用途に特化したR3000派生品を開発している。

**派生品**
組み込み用途に特化していない派生品として次がある。- R3000A - 1989年に登場した改良版。20MHz、25MHz、33.33MHz、40MHz で動作。- PR3400 - Performance Semiconductor が1991年5月に開発。25MHz、33MHz、40MHzで動作。同社のPR3000AとPR3010Aを単一のダイに集積したもの。- 他にR3000 と R3010 をワンチップ化したマイクロプロセッサとしては、R3500（IDT）、VR3600p=34（NEC）がある。VR3600(μPD30360)は、189ピンPGAパッケージで、25MHz品と33MHz品が用意されたp=34。
組み込み向けの派生品として次がある。- TX3900 - 東芝が開発した R3000 コアを使用したマイクロコントローラで、Windows CE を搭載した初期のハンドヘルドPC向けに開発された。- PR31700 - フィリップス・セミコンダクターズの75MHzのマイクロコントローラ。0.35μmプロセスで製造され、パッケージは208ピンLQFPである。電源電圧は3.3Vで、消費電力は0.35W。- RISController - IDTのローエンドマイクロコントローラシリーズ。R3041、R3051、R3052、R3081 がある。
宇宙空間での使用を想定した派生品として次がある。- Mongoose-V - 放射線対策が施された人工衛星の制御向け。12MHzで動作。ニュー・ホライズンズに使われている

**脚注**

**参考文献**
  "MIPS, Partners Flex Their Muscles In Battle With SPARC". (30 March 1988). Computer Business Review.- Chris Rowen, Mark Johnson, Paul Ries, "The MIPS R3010 Floating-Point Coprocessor," IEEE Micro, vol. 8, no. 3, pp. 53–62, May/June 1988.

**関連項目**
 MIPSアーキテクチャ- R2000 - 1985年リリースされた最初の32ビットMIPSアーキテクチャのRISCマイクロプロセッサ- R4000

**外部リンク**
 SPIM MIPSシミュレータ（英語） WindowsやLinux上で動作するシミュレータ。シミュレータだけでなく各種マニュアルへのリンクも豊富。- The vmips Project（英語） もうひとつのMIPS R3000シミュレータ