As such, they suffer from the same "delay branching" phenomenom observed in the branching instruction.
So when you program in SPARC, follow every "call" and "jmpl" instructions with a nop instruction to avoid executing an extra instruction unintentially (will cause a lot of hadache to track down this bug...)
Code in Java/C/C++: ============================================================ main(...) ----> int func(int x, int y, int z) { / { ... / ... ... / ... r = func(a, b, c) return(value); ^ } | | | +--------------------------------------+ ... } Assembler code in SPARC: ============================================================ main: ... func: + Save frame pointer of ... my caller ... + Obtain my own copy of Put parameters in local registers Output registers + Allocate space on stack Call func .... .... (function body) Assign return value to .... its destination ... Pass return value in an input register + Return local registers + Deallocate locaL variables from stack + Restore frame pointer of my caller Return to my caller
 
Syntax: call Label xxx yyy Effect: 1. "Pass" the return address (the value in the PC) in output register o7 2. Load PC with the destination address of the call (address associated with "Label") NOTE: the instruction "xxx" following "call Label" will be executed before SPARC can make the jump to "Label" Thus: always put a nop instruction after the "call" instruction NOTE: the return address stored in o7 is the address of the call Label instruction !
The "call" instruction of SPARC is similar to the "bsr" or "jsr" instruction of M68000:
There is one important different between the "call" instruction of SPARC the "bsr" or "jsr" instruction of M68000:
Suppose we have a call/bsr instruction located at address 5000 in memory: M68000 SPARC ================= ================== .... .... 5000 bsr Label 5000 call Label 5004 xxx 5004 xxx yyy 5008 yyy
The reason for doing this is beyond the sope of this class, it is related to "instruction abortion" and "instruction redo" techniques used in "interrupt handling".
The bottom line is: SPARC has the ability to return to different places from a function call.
But because the instruction "xxx" following the "call Label" have been executed by SPARC before it could branch to "Label", the "normal" return location is not the instruction "xxx" following the "call Label" instruction, but the instruction "yyy" !
Notice that the address of the instruction "yyy" is 8 more than the address of the "call Label" instruction.
The value "8" will be very significant in the "return from subroutine" instruction - discussed next....
 
Syntax: jmpl %r1 + constant, %r3 jmpl %r1 + %r2, %r3 xxx xxx yyy yyy Effect: 1. Store the return address in register %r3 2. Load PC with the (destination) address "r1 + constant" or "r1 + r2" NOTE: the instruction "xxx" following "jmpl" will be executed before SPARC can make the jump to address "r1 + constant" or address "r1 + r2" Thus: always put a nop instruction after the "jmpl" instruction NOTE: if you use for register r3 the output register o7, then the "jmpl" instruction will store the return address in the same place as the call instruction ! (In other words, you can use "jmpl" to replace the "call" instruction - if you so desire)
jmpl %o7 + 8, %g0is used to load "o7 + 8" into the Program Counter (PC) to return to the caller.
jmpl %i7 + 8, %g0is used to load "i7 + 8" into the Program Counter (PC) to return to the caller.