SPRUIG8J January 2018 – March 2024
The C7000 device has PC-relative call and PC-relative branch instructions whose range is smaller than the entire address space. When these instructions are used, the destination address must be near enough to the instruction that the difference between the call and the destination fits in the available encoding bits. If the called function is too far away from the calling function, the linker generates an error or generates a trampoline, depending on the setting of the --trampolines option (on or off).
The alternative to a PC-relative call is an absolute call, which is often implemented as an indirect call: load the called address into a register, and call that register. This is often undesirable because it takes more instructions (speed- and size-wise) and requires an extra register to contain the address.
By default, the compiler generates calls that may require a trampoline if the destination is too far away. On some architectures, this type of call is called a "near call."
The --trampolines option allows you to control the generation of trampolines. When set to "on", this option causes the linker to generate a trampoline code section for each call that is linked out-of-range of its called destination. The trampoline code section contains a sequence of instructions that performs a transparent long branch to the original called address. Each calling instruction that is out-of-range from the called function is redirected to the trampoline.
The syntax for this option is:
--trampolines[=on|off]
The default setting is on. For C7000, trampolines are turned on by default.
For example, in a section of C code the bar function calls the foo function. The compiler generates this code for the function:
bar:
...
CALL .B1 foo ; call the function "foo"
...
If the foo function is placed out-of-range from the call to foo that is inside of bar, then with --trampolines the linker changes the original call to foo into a call to foo_trampoline as shown:
bar:
...
CALL .B1 $Tramp$L$PI$$myfunc ; call a trampoline for foo
...
The above code generates a trampoline code section called foo_trampoline, which contains code that executes a long branch to the original called function, foo. For example:
$Tramp$L$PI$$myfunc:
BE .B1 foo ; long branch to foo (with constant extension)
Trampolines can be shared among calls to the same called function. The only requirement is that all calls to the called function be linked near the called function's trampoline.
When the linker produces a map file (the --map_file option) and it has produced one or more trampolines, then the map file will contain statistics about what trampolines were generated to reach which functions. A list of calls for each trampoline is also provided in the map file.
Assembly language programmers must be aware that the linker assumes D15 contains the stack pointer. The linker must save and restore values on the stack in trampoline code that it generates. If you do not use D15 as the stack pointer, you should use the linker option that disables trampolines, --trampolines=off. Otherwise, trampolines could corrupt memory and overwrite register values.