分岐命令
分岐命令(ぶんきめいれい、英: branch instruction)は、プロセッサの命令のうちプログラム制御命令(Program control instruction)[1]の一種である。ジャンプ命令ともいう。条件ジャンプ命令と無条件ジャンプ命令があり、厳密には「分岐」するのは条件ジャンプであって無条件ジャンプは「分岐」と言えないかもしれないが、特に区別しないことが多い。サブルーチン呼出や戻りの命令も分岐命令の一種とすることもある。
一般的なプロセッサでは、機械語の命令列はアドレスの昇順に逐次実行されるが、分岐命令が実行されると次に実行される命令が切り替わる。高水準言語のコンパイラは、条件文・Goto文・サブルーチン呼出などの制御構造から分岐命令を生成する。
たいていの分岐命令は[2]引数として少なくともターゲットアドレスを持つ。ターゲットアドレスは、分岐命令の実行によりプログラムカウンタに代入される。
命令パイプラインが深い一方で、先読みが浅いプロセッサでは、ジャンプによりパイプラインにバブルが発生しペナルティとなる設計にならざるをえないことがある。そのペナルティを軽減するため、分岐命令の直後を「遅延スロット」と称し、そこにある命令は分岐処理の直前に実行されるものとする、遅延分岐という方式がある。MIPS、SH、SPARCなど、初期のいわゆるRISCに採用例が多いが、1986年にNECから発表されたμPD77230、1988年にTIから発表されたTMS320C30、デジタルシグナルプロセッサにも(その前から)多い。ディレイスロット(にある命令)の数は、μPD77230の場合で 1 、TMS320C30の場合で 3 であった。大多数の(遅延スロットを採用している場合の)RISCのディレイスロットは 1 である。
パイプライン処理では命令のフェッチが重要であり、分岐予測が用いられることがある。分岐予測は失敗時のコストが大きいので、これを減らすために投機的実行などの技術が用いられる。
「汎用レジスタの内1つをプログラムカウンタにする」「全ての命令を条件実行可能とする」という、分岐命令の必要性を低減したり、パイプラインストールの可能性を低くする[3]工夫がある。ARMはこの両方を採用し、IA-64は後者をプリディケートで実現している(また前者は古くはPDP-8やPDP-11などで使われDECの特許[4]でもあったため、技術的な理由でなく特許回避という観点が非採用の理由としてあった。一例としてTRONCHIP#特許)。前者は分岐命令のバリエーションを増やすことなく単純な命令セットで複雑な機能を実現できることが、DECの発明であってアーキテクトを魅了した[5]。
しかし、命令セットは単純でも複雑な機能というのはRISC原理に反することもあり、RISCではARMなど採用例はあるが下火となった。RISC-Vでは命令のデコード・実行を複雑化させ、性能を低下させるとして前者・後者共に採用されなかった。ARMでも、64ビット化の際に両者とも廃止された(AArch64を参照)。
ただし、後者のごく部分的な実装である「条件実行命令を一部に用意する」のはRISCの観点にも適っており、AArch64では分岐の他に比較・選択といった命令に条件実行が残り、RISC-VのZicond拡張や、Pentium Pro以降のx86(P6マイクロアーキテクチャ、俗に686)にて、CISCだからというよりは内部RISCアーキテクチャでのソフトウェア的な性能向上のために実装されたCMOV命令なども同様である。
脚注・出典
[編集]- ^ P.HAYES, JOHN (1978,1979). Computer Architecture and Organization. pp. 169. ISBN 0-07-027363-4
- ^ 命令セットアーキテクチャにも依り、例えばスタックマシンにおいてスタックのトップを暗黙の引数とするため引数を持たない、という設計もあるかもしれない。またサブルーチンからの戻りを分岐命令とする場合、多くの設計で特定のレジスタかコールスタックのトップが暗黙の引数であり、命令自体は引数を持たない。
- ^ 後者はともかく、前者はPCへの任意の代入があり得ることから、パイプラインストールのペナルティは悪化しうる。
- ^ w11: PDP-11/70 CPU and SoC の DEC Patents(2024年9月4日閲覧)のページで PC as general register とある特許・他。
- ^ うんちく:アドレッシングモードの色々2024年9月4日閲覧「3. さらなる一般化:汎用レジスタをPCにしたら?」