Suppose, in our assembly program, we need to jump to a given 64 bit address. To do that, we have to use the "Jump and Link" instruction among all those jump/branch instructions. A reason behind that is that other instructions are designed to do different kind of branches/jumps which ususally have less number of bits for the target address i.e., relative distance/offset from
PC (program counter).
For example, "Branch on Integer Register with Prediction (BPr)" (A.3 sparc v9 doc) instructions have 14 bits to specify address. The Address is sign extended, multiplied with 4 and then, added with Program Counter for a branch which finally gives us the target address.
Similarly, Branch Instructions on Floating-Point Condition Codes (FBfcc) (A.4 sparc v9 doc) have 22 bits to specify the address. "Branch on Floating-Point Condition Codes with Prediction (FBPfcc)" (A.5 sparc v9 doc) instructions have 19 bits for the address field. Moreover, "Branch on Integer Condition Codes (Bicc)" (A.6 sparc v9 doc) instructions have 22 bits. Similarly, "Branch on Integer Condition Codes with Prediction (BPcc)" (A.7 sparc v9 doc) instructions have 19 bits.
Mentioned branch instructions above do not require more bits because they perform jump to addresses which are relative to the
PC (program counter). On the other hand, "Jump and Link" instructions were included in the architecture to branch to a direct 64 bit address.
Jump and Link
Here is an example of using jmpl instruction,
/* assuming the target address is provided in %g1 */ jmpl %g1, %o7
The example program above reads the target address from the Reigster and then jump. It also saves current
PC in register O7.
Instead of providing the register with the value loaded if we are given a 64-bit address to jump we can do following,
setx %g1, %l0, 0xff...... jmpl %g1, %o7
In the program above, we are doing similar thing compared to previous program. In addition, we are loading a 64-bit value into the register.
The jmpl instruction uses an absolute address to branch. There are 2 formats of the jmpl instruction for two values of i: 0 and 1. When
i=0 format is what we use mostly to perform jump to a 64 bit address.
RET pseudo instruction uses simm13 format,
jmpl %i7+8, %g0
rd=0=G0 which is used return from a subroutine. When we use
rd=15=O7 that enables us to do an indirect register call where the return address is stored in
%O7 so that optionally the called subroutine can return to the caller.
Here, 8 bytes are reserved for delay slot.
Follwing should be noted regarding Branch Instructions,
- Branch Instructions are delayed control transfer instructions (delay slot is executed first).
- Uses a label to branch based on the condition. This also means use of relative addressing in these instructions.
brz instruction looks like following,
brz,pt %i3, foo_label
All of these branch functions require a delay slot following the call.Therefore we have the
In comparison to
jmpl these branch instructions do relative addressing. Therefore, ba(0x58) means jump to PC + 0x58. An example
ba call is below,
Or in a more comprehensive way,
ba(f00); /* code */ foo: /* code */
The function we implement has an
nop inside it following the branch instruction.
Acknowledgement: Peter Schow
- Section A.3 (page 161) till Section A.7 (page 174) of The SPARC Architecture Manual V9
- Section A.24 - Jump and Link (page 196) of The SPARC Architecture Manual V9
- Section 2.9.2 - Branches of SPARC Architecture, Assembly Language Programming, and C (2nd Edition)
- Section 8.5.1 - Branch Instructions of SPARC Architecture, Assembly Language Programming, and C (2nd Edition)
- Appendix D.9 - Control Instructions of SPARC Architecture, Assembly Language Programming, and C (2nd Edition)
- SO - Call vs. JMPL in SPARC