2021:分岐命令

 プログラムは命令列が順に取り込まれては実行されるイメージで、現在実行中のコードの位置を指し示すのがプログラムカウンタ(PC)である。プロセッサによっては次に実行する命令を指したり名称が違っていたりする。PCは4バイトの固定長命令ならば+4ずつ、可変長命令なら現在実行した命令のサイズ分増えていく。この流れを変えるのは分岐命令で、制御転送命令とも呼ばれる。
 分岐命令の飛び先指定は絶対番地指定、レジスタの値による指定、PCとの相対値による指定がある。可変長命令の場合、分岐先が命令の先頭でないとそこからビット列を命令と解釈して実行してしまうので、予期せぬ動作をしたりトラップが発生したりする。
 サブルーチンコール命令は分岐命令の一種で、この命令の次の番地を保存し、分岐する。サブルーチン実行を終了して戻る場合はリターン命令で先程保存した戻り番地を取り出し、そこへ分岐する。この戻り番地の保存にはメモリ上のスタックが使われたり、特定の汎用レジスタが使われたりする。サブルーチンを呼び出す前後では引数や作業用のレジスタを確保する作業が必要となる。

 割り込みは特殊な分岐命令として扱える。割り込みは現在実行中のプログラムを一時停止し、再開するのに必要な情報を保存して割り込み要因ごとに指定された番地へ分岐する。割り込み要因ごとの分岐先は割り込みベクタとして特定の番地が使用される。これは割り込みベクタの要素ごとの番地に分岐するものもあれば、割り込みベクタに列挙されている番地を取り込んでそこに分岐するアーキテクチャもある。割り込みはサブルーチンコールに似ているが、割り込みは外部要因など命令実行とは非同期に発生することもあり、戻り番地に加えて条件フラグなどの状態を持っていればそれを保存しなければならない。また、割り込み発生後の応答時間を改善するために一部の汎用レジスタを割り込み処理用の汎用レジスタに切り替えるものもある。割り込みからの復帰は次の命令からの実行、実行中の命令が要因の場合はその命令からの再実行となる。例えばロードストア命令でTLBミスが発生した場合はその命令のメモリアクセスに失敗したということなので、割り込み先でTLBを再設定した後当該命令を再実行すればロードストアが何事もなかったかのように実行される。エミュレーションのための未定義命令は割り込み先で命令をエミュレーションした後、未定義命令割り込みが発生した命令の次の番地から実行を再開する。

 高級言語のIF文を構成するのが条件分岐命令で、演算結果を使って分岐の可否を判断し、条件が成立したら指定した分岐先へ、成立しなかったら次の命令を継続実行する。これで2方向の分岐ができることになる。条件としては2つの汎用レジスタの差を求め、0ならば等しい、正の値か負の値で大小を比較することができる。比較する汎用レジスタの順序を入れ替えることで大小関係の反対が得られることを利用して分岐命令のパターンを減らしたプロセッサもある。多くのプロセッサでは数値の比較では2の補数と符号なし整数を同時に判定できるC,V,N,Zの条件フラグを使う。Cは符号なしの算術演算でキャリー/ボロー発生、Vは2の補数の演算でオーバーフロー発生、Zは結果がゼロ、Nは結果が負の値をあらわす。このうちZ,Nは結果の数値だけから判断可能で、C,Vは演算することでフラグが立つ。C,Vについては他の種類の演算結果をあらわすのに流用しても問題ない。例えばCフラグはシフト演算の結果、MSBまたはLSBからはみ出た1bitをあらわすことができる。条件フラグを使わないアーキテクチャは汎用レジスタに比較結果を残すので割り込み発生時も通常の汎用レジスタの退避/復帰として扱えば良いが条件フラグが存在すると特別扱いが必要になる。浮動小数点の比較でも条件フラグは存在する。これは整数演算とは異なる条件フラグになる。

 条件付きで実行する命令としてはARMにはほぼすべての命令に条件と比較して実行するかどうかを決める4bitのフィールドがある。PA-RISCには条件によって続く1つの命令実行を無効化するNullificationがある。これはシングルパイプライン実行だと直前のデコードまで済んだ命令を破棄するだけで実現できる。その他古めのプロセッサも続く命令をスキップする命令を持っている。
 ConditionalMove命令は条件判断の結果、指定した汎用レジスタへの値の設定を行う。条件分岐でよくある動作は条件判断の後の値の設定であり、パイプライン実行するプロセッサでは条件分岐命令はパイプラインに空きが発生してしまうので、これを抑止できる。これはNullificationでも実現可能。
 先程言及したが、パイプライン実行で条件判断後分岐が成立/不成立することでパイプラインには空きが発生する。これはパイプラインが深いほどペナルティが大きい。これを少しでも改善するためにはその分岐が成立するかどうかを予測して、分岐する/しないを前提とした動作を準備しておく。予測がミスしてもペナルティが発生するだけで命令の実行には問題はない。分岐命令中の特定のビットを指定してヒントを与える(SPARC V9)アーキテクチャや、戻る方向の分岐はループの戻りでほとんどの場合分岐成立、進む方向の分岐はループからの脱出でほとんどの場合が分岐不成立(Alpha)があったが現在の分岐予測機構は飛び先の番地を記録してその履歴で判断するので命令列中のヒントは不要になった。投機実行というメカニズムは複数の分岐先をある程度並列に実行して、分岐した方の結果を反映しもう片方の結果は消去する。分岐予測も投機実行も実行時間以外はユーザーからは見えない。

以上から考えた必要なもの:
・分岐先を間違えたときのガード
・割り込みベクタの定義
・条件フラグを明にするかどうか
・条件転送命令

"2021:分岐命令" へのコメントを書く

お名前
ホームページアドレス
コメント