beq
lyszt.netはbeqおよびその他のRISC-V命令をより詳しく扱っています。
エンコーディング形式
説明
beq はプログラムが判断を下せるようにします。プロセッサは通常、リストに現れる順序で命令を実行します。その順序だけでは何かを選択したり繰り返したりすることはできません。分岐はその順序を変えます。条件をテストし、条件が成立すれば、プロセッサは次の行ではなく別の場所から続行します。すべての if 文とループは分岐から作られます。
その別の場所はラベルによって名付けられます。ラベルとは名前に続けてコロンを付けたもので、コード内の位置を示します。例えば例の中の done というラベルです。beq(等しければ分岐)は2つのレジスタを比較します。それらが同じ値を持つとき、ラベルの位置へジャンプします。異なる場合は、次の命令で実行が続きます。形式は以下に示します。
beq rs1, rs2, label
beq は次に実行される命令を変えるだけです。比較の yes か no の結果を数値として格納するには別の命令が必要で、それは slt のページで説明されています。
プロセッサはプログラムカウンタと呼ばれるレジスタで自身の位置を追跡します。これは実行中の命令のアドレスを保持します。分岐が成立するとそのアドレスが変わるため、次の命令はラベルから来ます。
RISC-V のマニュアルには、条件分岐はそのオフセットを2バイトの倍数で数えた12ビット値として格納すると記載されています。オフセットは符号拡張され、分岐命令のアドレスに加算され、プラスマイナス4 KiBの範囲になります。ここで KiB は1024バイトです。分岐命令は2つのレジスタを直接比較し、条件コードを使用しません。マニュアルはその理由として、比較と分岐を組み合わせた命令は通常のパイプラインに適合し、追加の状態や一時レジスタを必要としないことを挙げています。また、ソフトウェアに対して、最も一般的な経路をストレートコードとして保ち、後方分岐は成立すると予測され、前方分岐は成立しないと予測されることを期待するよう助言しています。少なくとも最初に遭遇したときはそうです。
分岐は2つのレジスタを比較し、命令に書かれた定数を取ることはできないため、beq t0, 5, label のような形式は存在しません。レジスタを定数と比較するには、まず li で定数をレジスタにロードし、それから2つのレジスタを比較します。
li t1, 5 beq t0, t1, done
値 0 はロードする必要がありません。なぜならレジスタ zero が常にそれを保持しているからです。
一般的な使用法は、レジスタを常に 0 を保持する zero と比較して、値がゼロに達したかどうかを問い合わせることです。これはカウントダウンループを終わらせ、結果を確認します。例では a0 がゼロまでカウントダウンしたときに done へ分岐します。beq とラベルだけで、プログラム内のすべての判断とループを構築できます。
例
beq a0, zero, done # if a0 == 0, jump to 'done'
