Question

For SPARC Assembly particularly, how are annulled branches different from regular branches?

I always thought that annulling branch instructions is required when I need to fill the nop delay slot for branch instructions. However, I don't think I'm correct on this part, because you can fill the nop without annulling the branch.

Was it helpful?

Solution

The annulled branch instruction causes the instruction in the delay slot -- the instruction after the branch -- to be ignored if the branch is not taken.

Why would this be important? Because normally, the instruction after the branch is executed, even if the branch is taken. This is because there are two program counters, PC and NPC. PC, which indicates the instruction being executed, is updated to NPC, which is PC + 4, at the same time as NPC is being updated to the target of the branch instruction. So because of the timing of these events, the next instruction has to be loaded. Rather than just throw that cycle away, it's more profitable to use that cycle if we can. We would then just make that instruction part of the loop.

loop:   someOp                
        someOtherOp
        branch      loop      ;
        delayslotOp           ; will actually be executed, before someOp, after branch

If we can't use the instruction slot after the branch, then we stick a nop in there, and do nothing on that cycle.

So why then have different instructions with annulled and non-annulled branch options? To give us the choice of what happens on exit from the loop. If we've made the delay slot part of the loop activity, we might not want that op executed upon leaving from the loop. Therefore, we'd add ",a" to the end of the branch instruction.

This page has some nice examples.

OTHER TIPS

According to the SPARC Architecture Manual (v9):

3.2.3 Control Transfer

[...]

Most of the control-transfer instructions are delayed; that is, the instruction immediately following a control-transfer instruction in logical sequence is dispatched before the control transfer to the target address is completed.

[...]

The instruction following a delayed control-transfer instruction is called a delay instruction. A bit in a delayed control-transfer instruction (the annul bit) can cause the delay instruction to be annulled (that is, to have no effect) if the branch is not taken.

6.3.4 Control-Transfer Instructions (CTIs)

[...]

Programming Note: The annul bit increases the likelihood that a compiler can find a useful instruction to fill the delay slot after a branch, thereby reducing the number of instructions executed by a program. For example, the annul bit can be used to move an instruction from within a loop to fill the delay slot of the branch that closes the loop. Likewise, the annul bit can be used to move an instruction from either the “else” or “then” branch of an “ifthen- else” program block to the delay slot of the branch that selects between them. Since a full set of conditions are provided, a compiler can arrange the code (possibly reversing the sense of the condition) so that an instruction from either the “else” branch or the “then” branch can be moved to the delay slot.

The following code shows two branches, in the first one the delay instruction is always executed, in the second one the delay instruction is annulled if the branch is not taken:

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top