4.3.7 Dynamic C calling convention

Functions declared __dynamicc are called using the Dynamic C calling convention. This way assembler routines originally written for Dynamic C or code generated by Dynamic C can be called from SDCC. Currently variable arguments are not yet supported (neither on the caller nor on the callee side).

All arguments are passed on the stack. The first parameter is also passed in hl if it has 8 bits (sign-extended, but callees in Dynamic C don't rely on that) or 16 bits, in bcde if it has arithmetic type and 32 bits. struct and union, and pointers to __far, are passed on the stack only. Arguments of other types are not supported by the convention. Currently, variable arguments are not yet supported by SDCC (neither on the caller nor on the callee side).

8-bit (sign-extended, but callers in Dynamic C don't rely on that) and 16-bit return values are passed in hl, 32-bit return values are passed in bcde (arithmetic types) or px (pointers to __far). struct and union, independent of their size, are returned via the stack. Return values of other types are not supported by the convention, nor is returning struct/union from functions with variable arguments.

After the call, all stack parameters and the space for struct/union return values are cleaned up by the caller. All registers are to be saved/restored by the caller as needed.

Pointers to __far are a feature introduced in Dynamic C 10, which supports Rabbit 4000/5000/6000 only; no Dynamic C version targeting Z180 or Rabbit 2000/3000 supports them.

Support for the Dynamic C calling convention is slightly incomplete in SDCC vs. Dynamic C 10: pointers to __far are not supported as return values. Also, 8-bit parameters are not sign-extended by the caller (i.e. the upper byte, which is not used by Dynamic C callees, has an unspecified value). When passing or returning struct/union or pointers to those to/from a function actually written for Dynamic C, be aware these should only have members of types supported by both SDCC and Dynamic C, and for which both SDCC and Dynamic C use the same layout. This restricts the members to the following types: char, signed char, unsigned char, (signed) int, unsigned int, (signed) long, unsigned long, float, pointers (excluding pointers to __far), struct/union types to which this restriction applies recursively.