A section of code in the bootrom uses another scheme.
I am going to mark these as Xsubroutine and Xcall in the sun 3/60 annotation (I called these "ODD" in the sun 3/80).
The idea is to place the return address into the fp register, and then use a jmp instruction to return. Here is a typical example that calls a printf routine of this flavor:
fefe73f4: 49fa 037e lea %pc@(0xfefe7774),%a4 fefe73f8: 4dfa 0008 lea %pc@(0xfefe7402),%fp fefe73fc: 60ff 0000 2fd6 bral 0xfefea3d4 fefe7402: 6000 0002 braw 0xfefe7406
It seems that the a4 register is always used for subroutine arguments.
The first instruction loads the address of the string we want "printf" to print into the a4 register. The second loads the address that we want to return to into the fp register. Both of these use PC relative addressing to generate those addresses. This is neither here nor there really, and in the first case would be done that way even with the usual "jsr" style calls. Then we do a branch to the routine we want to call. Note that the address placed into fp is the address of the instruction we want to return to.
Why take these pains? The reason is to avoid using the stack. This code is used during the testing of RAM memory, and the bootrom wants to test all of it, and that would conflict with use of some of it for the stack.
Note also that these scheme does not allow subroutines to be recursive. In fact it requires all subroutines to be leaf routines, and we cannot call other subroutines from a subroutine. The strings used by this section of code always have "\r\n" in them. The normal printf only will have "\n" and uses a recursion to expand it to "\r\n" as is often done.
The return from subroutines coded to use this scheme look like:
fefe9628: 4ed6 jmp %fp@A jump to the address saved in the "fp" register.
Tom's Computer Info / tom@mmto.org