User`s guide

How the MACRO Compiler Functions on Different Platforms
2.6 Declaring a Routine’s Register Use
It is recommended that the .CALL_ENTRY, .JSB_ENTRY, and .JSB32_ENTRY
register arguments reflect the routine interface, as described in the routine’s
text header. Wherever possible, you should declare input, output, scratch,
and preserve register arguments for all routines. You only need to provide the
argument when there are registers to be declared (for instance, input=<> is not
necessary).
2.7 Branching Between Local Routines
The compiler allows a branch from the body of one routine into the body of
another routine in the same module and psect. However, because this may result
in additional overhead in both routines, the compiler reports an information-level
message.
Note
The compiler does not recognize a call to $EXIT as terminating a routine.
Add an extra RET or RSB, whichever is applicable, after $EXIT to
terminate the routine.
If a CALL routine branches into a code path that executes an RSB, an error
message is reported. Such a CALL routine, if not corrected, will fail at run time.
If a JSB routine branches into a code path that executes a RET instruction, and
the JSB routine preserves any registers, an informational message is issued. This
construct will work at run time, but the registers saved by the JSB routine will
not be restored.
If routines that share a code path have different register declarations, the register
restores will be done conditionally. That is, the registers saved at routine entry
will be the same for both routines, but whether or not the register is restored will
depend upon which entry point was invoked.
For example:
rout1: .jsb_entry output=r3
movl r1, r3 ! R3 is output, not preserved
movl r2, r4 ! R4 should be preserved
blss lab1
rsb
rout2: .jsb_entry ! R3 is not output, and
movl #4, r3 ! should be auto-preserved
movl r0, r4 ! R4 should be preserved
lab1: clrl r0
rsb
For both routines, R3 will be included in the registers saved at entry. However,
at exit, a mask (also saved at entry) will be tested before restoring R3. The mask
will not be tested before R4 is restored, because R4 should be restored for both
entry points.
Note that declaring registers that are destroyed in two routines that share code
as scratch in one but not the other is actually more expensive than letting them
be saved and restored. In this case, declare them as scratch in both, or if one
routine requires that they be preserved, as preserve in both.
2–16 How the MACRO Compiler Functions on Different Platforms