i960 Processor Compiler User's Guide
7-28
7
Runtime Decompression
During program execution secondary functions reside in memory in
compressed form. Every call to a secondary function is intercepted at
runtime by a special dispatcher routine. The dispatch routine is contained
in the
libc library supplied with the tools. To ensure interception of all
secondary functions, including invocations through indirect calls or
interrupts, the compiler generates interceptor entries in the
.text section,
preceding the function bodies in the
cave section as follows:
.section .text
_foo:
lda L1,reg
call __dispatcher
ret
.section cave
.word L2-L1,0
L1:
function body
L2:
Here the location L1 of the secondary function body is passed to the
dispatcher. The word preceding the function body is set by the assembler
to indicate the uncompressed size.
The dispatcher performs the following steps:
1. Allocates a decompression buffer on the current runtime stack.
2. Saves the caller’s context.
3. Performs decompression.
4. Restores the caller’s context.
5. Invalidates the instruction cache.
6. Calls the decompressed secondary function.
The dispatcher prevents the runtime stack from being overrun by a long
chain of recursive invocations by reusing the functions that are already
active on the stack. The interceptor’s invocation of the dispatcher pushes
a unique return address on the runtime stack. The return address is then