Routine Calls: Unnecessary Layers


[Home] | [About McOS Re] | [FAQ] | [Changes] | [Progress] | [Documentation] | [Links]


"A TOC entry for an external routine points to a transition vector
largely so that the calling routine can set up an RTOC with the
called fragment's TOC value. Then, when the called routine
exits, the caller restores the RTOC to its original value,
pointing to the TOC of the calling fragment. This kind
of function call is known as a cross-TOC call."

Note: a possible mixed mode switch ("Call[OSTrap]UinversalProc" --> _Routine) is not shown.

1. Typical compiled code.

Mac OS supports this type of call by exporting glue symbols (like Routine@Symbol shown above) from InterfaceLib.

2. "Xcall" macros.

For multiple calls, this variant has larger code footprints.

3. Calling routines directly (preferred way).

We can just get the trap address and treat it as an UPP. The trap tables are defined to contain UPPs, either addresses of real 68K code, or addresses of a routine descriptor.

Warning: because enough space must be allocated on the stack to hold all parameters (whether they are passed in PPC registers or not), be sure to leave and generally ignore $40 or even more (as for SFPGetFile via CallUP) "mandatory stack bytes". For example, stack space $0(sp)...$3F(sp) is enough to hold 10 parameters: registers GPR3...GPR10 plus two parameters on the stack ($38(sp): param9, $3C(sp): param10).

As a result, the number of branches, imports and occasions when the processor would or may stall while executing a code have been minimized. In loops, cross-TOC preparation [lwz rD,CallUP(rtoc); lwz rtoc,4(rD); lwz rD,0(rD)] is invariant code and can be moved out of loop body. For applications, it is possible to load addresses and TOCs of CallUP/CallOSTrapUP into non-volatile GPRs once at initialization stage and then use them globally.