printf() presently is a hack through to prom_printf(). This makes assumptions that you are writing to the screen, and is limited by the 16-bit support in vsprintf_internal() which forms the heart of prom_printf().
The proposal is to support 3 printf variants:
1) printf_tiny(). This is an identical implementation to prom_printf(), implemented using the same assembler (possibly the same file to save duplicating code), but is limited to %c, %s, %d/%u/%x (16-bit values only).
2) printf_long(). This would be the same as printf_tiny(), but with support for 32-bit values.
3) printf_normal(). This would theoretically be a pass-thru to the native printf() implementation, supporting whatever is compiled in. A putchar() routine has to be defined, but this can be a wrapper round "write(1, &c, 1)".
Testing #3 shows that it works, but it is horribly slow. Therefore, it should probably not be the default. Tests need to be carried out on the performance of printf_long() to see whether it could be used as the default.
Glue code should be provided for at least printf_tiny() and printf_long(), so we can catch integer length errors in the native run case for testing purposes. Arguably, printf_large should be implemented this way as well, as the SDCC-supplied printf() may support a subset of the native environment (for example, the default is to compile with no float support).
The possibility of vectorising both the printf/sprint variations need investigating too, i.e. using the same common formatting code, but pass a function pointer and a callback arg so we can support printing to strings and/or file descriptor as required.
Diff: