In the old subroutine calling convention, a BAL in the caller pointed to the start of the subroutine, and a BAL_r to the end. We have already pointed out that this was ugly.
In the new call mechanism, a single BRA (or J if it is kept) points to a single point in the subroutine called the entry/exit point or portal. At this point is an instruction called SWAPBR which exchanges the contents of the branch register times the direction sign with the contents of another register. That is,
If you branch to a SWAPBR while going forwards, you will end up going forwards from the SWAPBR with the original offset stored in the given register. If you now negate that register (using NEG), branch to just above the SWAPBR, and execute it again (coming into it from above), now the value in the branch register will be the exact right offset to return you to the caller. The BRA (or whatever) in the caller will cancel this offset and normal execution will continue from the caller.
When branching to a SWAPBR while in reverse, note that we will come out above the SWAPBR with the negative of the offset in the given register. Note this exactly mirrors the state of that register just before returning when running forwards. Thus, the behavior of SWAPBR makes the direction of execution invisible to the user, and the subroutine cannot do anything when run in reverse except exactly undo what it did when running forwards.
Since all subroutine entry points will want to negate the given register after doing a SWAPBR on it, we could merge the negation functionality into the SWAPBR instruction and call it SWAPBRN. But this would require that we take care in implementation to do the two steps in the opposite order --- first negate, then swap --- when SWAPBRN is executed in reverse.
The BRA/SWAPBR combination can easily be used in sort of an inverted way to implement switch statements as well as subroutines, similar to how I described doing this in my earlier memo using BAL/BAL_r/JR/JR_r.