特に SPARC アセンブリの場合、廃止されたブランチは通常のブランチとどう違うのですか?
分岐命令の nop 遅延スロットを埋める必要がある場合は、分岐命令を無効にする必要があると常に考えていました。ただし、ブランチを無効にすることなく nop を埋めることができるため、この部分については正しいとは思いません。
特に SPARC アセンブリの場合、廃止されたブランチは通常のブランチとどう違うのですか?
分岐命令の nop 遅延スロットを埋める必要がある場合は、分岐命令を無効にする必要があると常に考えていました。ただし、ブランチを無効にすることなく nop を埋めることができるため、この部分については正しいとは思いません。
無効化された分岐命令により、分岐が実行されない場合、遅延スロット内の命令 (分岐後の命令) が無視されます。
なぜこれが重要なのですか?通常、分岐が発生しても、分岐後の命令が実行されるためです。これは、PC と NPC の 2 つのプログラム カウンターがあるためです。実行中の命令を示す PC は、NPC が分岐命令のターゲットに更新されると同時に、PC + 4 である NPC に更新されます。したがって、これらのイベントのタイミングにより、次の命令をロードする必要があります。そのサイクルをただ捨てるよりも、できればそのサイクルを利用した方が有益です。次に、その命令をループの一部にします。
loop: someOp
someOtherOp
branch loop ;
delayslotOp ; will actually be executed, before someOp, after branch
分岐後に命令スロットを使用できない場合は、そこに nop を挿入し、そのサイクルでは何もしません。
では、なぜ無効化された分岐オプションと無効化されていない分岐オプションで異なる命令があるのでしょうか? ループの終了時に何が起こるかを選択できるようにします。遅延スロットをループ アクティビティの一部にした場合、ループから出るときにその op を実行したくない場合があります。したがって、分岐命令の最後に「,a」を追加します。
SPARC Architecture Manual (v9)によると:
3.2.3 コントロール転送
[...]
制御転送命令のほとんどは遅延します。つまり、論理シーケンスでコントロール転送命令の直後にある命令が、ターゲット アドレスへのコントロール転送が完了する前にディスパッチされます。
[...]
遅延制御転送命令に続く命令を遅延命令と呼びます。遅延制御転送命令のビット (無効ビット) は、分岐が発生しない場合、遅延命令を無効にする (つまり、無効にする) ことができます。
6.3.4 制御転送命令 (CTI)
[...]
プログラミング上の注意: アンヌル ビットは、コンパイラが分岐後に遅延スロットを満たす有用な命令を見つける可能性を高め、それによってプログラムによって実行される命令の数を減らします。たとえば、無効ビットを使用してループ内から命令を移動し、ループを閉じる分岐の遅延スロットを埋めることができます。同様に、無効ビットを使用して、「ifthen-else」プログラム ブロックの「else」分岐または「then」分岐から、それらの間で選択する分岐の遅延スロットに命令を移動できます。条件の完全なセットが提供されるため、コンパイラはコードを調整して (場合によっては条件の意味を逆にする)、「else」分岐または「then」分岐のいずれかからの命令を遅延スロットに移動できるようにします。
次のコードは 2 つの分岐を示しています。最初の分岐では遅延命令が常に実行され、2 番目の分岐では遅延命令が実行されない場合は無効になります。
cmp %i3, %i0
ble %icc, -0x5c
ld [%l0 - 0x4], %i5 ; executed whether the branch is taken or not
...
cmp %l1, 0x80
bl,a %icc, +0x40
ld [%fp + 0x7c7], %g2 ; annulled if the branch is not taken, executed otherwise