RISC プロセッサの命令セットの特徴

作成日:2005.6.13

このページは HP の PA-RISC プロセッサの終焉を追悼 するために2005/6/4 の日記 を元にして作成。

MIPS、SPARC、PowerPC、PA-RISC、Alpha の五大 RISC アーキテクチャの特徴のチャートを完成させていく。 今後、空欄を埋め、ISA 仕様書とかプロセッサへのリンクを追加予定。


命令セットMIPSSPARCPowerPCPA-RISCAlpha
寸評 事実上の元祖 RISC。
32-bit の命令セットが MIPS1 として定義され、MIPS2、MIP3 と機能追加される。 MIPS4 で 64-bit 化された。
遅延スロットと乗除算を覗けば素直なアーキテクチャー。
Standford 大の RISC プロジェクトをベースに SUN Microsystems 社が作った RISC。
SPARC V8 までが 32-bit で、 SPARC V9 で 64-bit 化がなされた。

いろいろな癌を抱えている最悪な命令セット。 その中でも register window 方式の影響が最悪。 Register window は登場時には 構造化言語のスタックフレームの切り替えを ハードウェアレベルで実現し性能向上に役立った。 しかしスーパースカラープロセッサの登場で事態は逆転。 Out of order 実行は CPU 内部で依存性解決を行う register renaming を前提としているが、 register window とバッディングするため SUN Microsystems の UltraSPARC はいまだ out of order 実行を 実装できていない (富士通の SPARC64 は強引に out of order 実行をしている)。

SPARC は ABI まで広げてみると その場凌ぎのテクニックがいろいろ見つかる。
  HP 社が HP-UX 用に開発した RISC プロセッサ。
PA-RISC 2.0 で 64-bit 化。
最後の RISC。
最初から 64-bit。
アーキテクチャー屋とコンパイラ屋が手を組んで、 C 言語で書かれたプログラムを本当に速くする為にはどうすればいいのかを 真剣に考え抜いたアーキテクチャーになっている。

ただ過去のしがらみを無視しすぎな面がある (OSF の初期の C コンパイラの int 型が 64-bit だったとか)。
対象MIPS4SPARC V9 (一部 V8 を解説) PA-RISC 
汎用レジスタ 64-bit 汎用レジスタが 32本。
R0 はゼロレジスタ。
64-bit 汎用論理レジスタが 32本 (G0 〜 G7、I0 〜 I7、L0 〜 L7、O0 〜 O7)。 うち Gx の 8 本は固定で G0 はゼロレジスタ。それ以外の 24本は register window 方式。

24 本のレジスタは裏側にある大量の物理レジスタの覗き窓になっていて、 プログラム的にマッピング関係が変更できる。 save / restore 命令は論理レジスタのアクセス可能な物理レジスタを 16 本づつスライドさせることができる。 save 命令を使うと、 それまで Ox レジスタだったものが Ix レジスタの位置に移り Ox、Lx レジスタには隠れていた物理レジスタが割り当てられる。 restore 命令を使うと、 それまで Ix レジスタだったものが Ox レジスタの位置に移り Ix、Lx レジスタは直前の save 命令の実行前のレジスタに戻される。
64-bit 汎用レジスタが 32本。 64-bit 汎用レジスタが 32本。
R0 はゼロレジスタ。
64-bit 汎用レジスタが 32本。
R31 がゼロレジスタ。
浮動小数点レジスタ MIPS の命令セットの浮動小数点演算は、コプロセッサによって提供されることを前提に設計されている。

1つの浮動小数点コプロセッサは 64-bit 浮動小数点レジスタが 32 本使える。 1つの CPU はこのコプロセッサを 4 基まで使用可能。

ただし現在の MIPS プロセッサは、 CPU と FP ユニットが完全に統合されている。 そのため 2基以上の浮動小数点演算ユニットを持つ MIPS チップは商業的には存在しない。

MIPS の浮動小数点演算ユニットは、固定小数点も可能。
32-bit 浮動小数点レジスタ が64本(F0〜F63)ある (V8 では 32本)。 ただし single-precision (float 形式) で使用する限り前半の 32 本(F0〜F31) しか使えない。

Double-precision (double 形式) で使用する場合、 32-bit 浮動小数点レジスタの隣あう2本をペアとして 32 本分として使える (V8 では 16 本)。

隣り合う 4本を使うことで quad-precision のレジスタが 16 本として使える (V8 では 8 本)。

浮動小数点レジスタと整数レジスタを CPU 内で転送しあう命令がない。
64-bit 浮動小数点レジスタが32本。 64-bit 浮動小数点レジスタが 32 本。

Single-precision (float) として使うと、 1本のレジスタが上下分割され 32-bit 浮動小数点レジスタ 64 本として使える。

隣り合う2本を束ねて quad-precision レジスタが 16 本としても使える。
64-bit 浮動小数点レジスタが 32 本。 Single-precision (float) としても使える。

FR31 がゼロレジスタ。

VAX 形式の浮動小数点モードがある。
命令による副作用(フラグ) 基本的に副作用はないが、演算の結果 トラップが発生する命令が数種類ある。 例えば ADD は加算の結果 オーバーフローが発生すると例外がトラップされる。
トラップのある演算命令は トラップのないバージョンも用意されている(例: ADD に対して ADDU) 。
C コンパイラはトラップのある命令は使わず、トラップのない命令を生成する。
演算の結果によってフラグセット (4-bit) が書き換えられる。 フラグを書き換えない副作用を伴わないバージョンも用意されている。

使用されるフラグセットは 6 組あり、 演算の種類によって書き換え先が異なる。 32-bit の整数演算は icc、 64-bit 整数演算の場合は xcc (V8 にはない) になる。

浮動小数点演算の場合 fcc0 〜 fcc3 の 4 つのフラグセットのいずれに副作用を残すかを 命令フィールド中で指定できる (ただし V8 は fcc0 のみを使う)。
演算の結果によって反映される各 4-bit の条件フラグ(セット)が CF0 〜 CF7 まで 8 組ある。
整数演算命令の結果は CF0 に、浮動小数点演算命令の結果は CF1 に反映されると決まっている。 残りの CF2 〜 CF7 は、CF0・CF1 の内容を退避したり、 比較演算命令の出力先として使うことができる。 条件分岐は指定した条件フラグの内容によって分岐を行う。

また、条件フラグとは別に XER レジスタが存在し、CA・SO・OV フラグ・String 系命令のカウンタを持つ。 条件フラグと同様に演算結果の副作用を受ける。 フラグは CF0 と重複するのだが、 XER レジスタの方はキャリー組み込み加算命令など通常演算命令の入力になりうる点が異なる。

CFx と XEF レジスタに対する副作用は、命令フォーマット中の設定ビットで無効にできる。
フラグはないが nullification がある。 ない。
条件分岐 整数条件分岐命令はレジスタをチェックして分岐方向を決定する。 1-汎用レジスタ指定と 2-汎用レジスタ指定タイプがある。
1-汎用レジスタ指定タイプの場合は、分岐条件を compare 命令で生成しておくことになる。

浮動小数点条件分岐は、 浮動小数点レジスタ比較命令を用いて 1-bit の条件フラグに真偽を書き込み、 フラグビットによって条件分岐を行う。 条件フラグビットは 4 個あり、 命令フォーマット内でどれを使用するか指定できる。
条件分岐命令は基本的にフラグセットから条件をもらい分岐する。

V9 には比較命令の結果を汎用レジスタに格納し、 その汎用レジスタの内容によって分岐するもある(1-汎用レジスタ分岐命令)。
条件分岐命令の条件は条件フラグ(CFx) によって与えられる。 命令フィールド中の指定で 8 つの条件フラグのどれか一つを指定する。 複雑すぎるので 昨日の日記 を参照してください。 条件分岐は 1-汎用レジスタ指定タイプオンリーなので、 比較命令 → 条件分岐のコンボが使われる。

浮動小数点レジスタの比較命令も汎用レジスタの出力先にとるので、 浮動小数点レジスタをチェックして条件分岐を行う命令はない。
遅延スロット 無条件分岐も含む全ての分岐命令が1命令分の遅延スロットを持つ。
条件分岐に関しては遅延スロットを常に有効にするものと、 not-taken 時に実行しないもの2種類がある。
無条件分岐も含む全ての分岐命令が1命令分の遅延スロットを持つ。
条件分岐に命令フォーマット内の annul bit により遅延スロットを常に有効にするものと、 not-taken 時に実行しないもの2種類がある。
ない。 無条件分岐も含む全ての分岐命令が1命令分の遅延スロットを持つ。
条件分岐命令で nullification を適用した場合、 後方分岐の場合は not-taken 時に遅延スロットをスキップし、 前方分岐の場合は taken 時に遅延スロットをスキップする。
当然ナッシング
整数乗除算 乗・除・剰余演算は、結果を格納するための専用レジスタ LO レジスタと HI レジスタが使う。
乗算は 64bit x 64bit の積が 128bit になり、上位 64bit が HI に 下位 64bit が LOに格納される。
除算は 64bit / 64bit の商が LO に、余りが HI に格納される。

MIPS の乗・除・剰余演算は、out of order 実行ができないため遅い。 そのため SGI の MIPS Pro コンパイラは、 浮動小数点ユニットを使って整数乗算を行う最適化を行うことがある。
V8 では、32bit の整数乗・除算命令に専用の 32-bit レジスタ(Yレジスタ) を使用する。 乗・除算命令は Rd = R1 op R2 の 3-op 指定のフォーマットだが、 暗黙に Y レジスタ が使用されることになる。 乗算は 32bit x 32bit = 64 bit (上位を Y レジスタに格納) で、 除算は 64bit (上位を Y レジスタで指定) / 32bit = 32 bit に結果を返す。

ただこの命令は CPU には実装されておらず、 不正命令例外をキャッチして OS 側で処理を行うことになっている。 V9 では deprecated である。

V9 から普通の 3-汎用レジスタ指定タイプの乗・除演算が導入された。
基本的には 3-汎用レジスタタイプなのだが、 32-bit x 32-bit 乗算の結果を 64-bit で得てその上位 32-bit を取得とか、 64-bit x 64-bit 乗算の結果を 128-bit で得てその上位 64-bit を取得というような、 特殊な乗・除算がある。 3-汎用レジスタ指定タイプのみ。

これは 32-bit x 32-bit であれば 32-bit で結果を、 64-bit x 64-bit であれば 64-bit で結果を受けるタイプである。 結果、乗算の場合は桁が溢れた部分は破棄される。

この 3-汎用レジス指定タイプの乗除余算は、 C 言語のセマンティクスとよく合致する。
3-汎用レジスタ指定タイプのみ。

左に同じ。
メモリアクセス 初期の Alpha は1バイト・2バイトのロード・ストア命令がなかった。
これは読み書きを 4バイト・8バイトに制限し、 バイト操作命令(汎用レジスタを char[8] とみなして操作する命令群)を使わせようとしたためである。

不評だったため EV5 (21164) で 1バイト・2バイトのロード・ストア命令が追加された。
即値フィールド 算術演算は s16
論理演算は u16
条件分岐命令は s16
ジャンプ命令は s26
ロード・ストア命令は1レジスタ+s16
算術・論理演算は s13
条件分岐命令は s22、s19、s16 の3パターン
ロード・ストア命令は1レジスタ+s13
32ビットの上位22ビットを埋める即値代入命令がある。
他に s10 と s11 の即値を取る命令フォーマットがある。

フォーマット多すぎ
特殊な整数演算命令
特殊な浮動小数点演算命令
SIMD命令
キャッシュコントロール

コメント

トラックバック   [Trackback URL: http://www.nminoru.jp/cgi-bin/tb.cgi/programming__arch__arch_features]
コメントを書き込む

TOP    掲示板    戻る
Written by NAKAMURA Minoru, Email: nminoru atmark nminoru dot jp, Twitter:@nminoru_jp