ack icon indicating copy to clipboard operation
ack copied to clipboard

Add support for building multiple libcs

Open davidgiven opened this issue 6 years ago • 10 comments

Platforms like CP/M are very resource constrained, and the full libc (with printf/float rendering/stdio) is huge --- about 25kB!. We should build multiple copies of the libc for these platforms with restricted feature sets (like an integer-only printf which calls write() directly) to reduce footprint.

See https://github.com/davidgiven/ack/issues/128#issuecomment-419741032.

davidgiven avatar Sep 10 '18 08:09 davidgiven

Maybe just separating floats from the rest would already make a huge impact.

Fabrizio-Caruso avatar Sep 10 '18 08:09 Fabrizio-Caruso

Turns out the i80 already has optional floating-point; compile with -fp to enable it. The libc is configured for floating point so that it'll work with -fp. Without -fp you get a stub implementation of all the floating point code (see https://github.com/davidgiven/ack/blob/default/mach/i80/libem/flp.s), but the printf float stuff is still there.

Yes, building two copies of the libc, one with floats and one without, and then selecting the right one depending on -fp, should be entirely feasible.

(But you'll still get all the printf integer stuff, and stdio, and malloc/free, etc.)

davidgiven avatar Sep 10 '18 09:09 davidgiven

@davidgiven There must be a fully modular way to prevent the linker from linking unused stuff. Many small libs?, each of which implements a portion of libc?

Fabrizio-Caruso avatar Sep 10 '18 09:09 Fabrizio-Caruso

Unfortunately, no --- there's no way the linker can tell whether you're going to call printf with %f in the format string or not.

davidgiven avatar Sep 10 '18 09:09 davidgiven

Maybe the optimizer can remove uncalled functions as postprocessing.

Fabrizio-Caruso avatar Sep 10 '18 09:09 Fabrizio-Caruso

printf is an interpreter which reads the format spec out of a string. There's no way to tell which formatting specifications are used because the format spec can be created dynamically.

davidgiven avatar Sep 10 '18 10:09 davidgiven

Sure but something could be cut out (after compilation, while linking) without telling printf.

Fabrizio-Caruso avatar Sep 10 '18 11:09 Fabrizio-Caruso

@davidgiven Would building the lib at compilation time with the right bits make any sense? Are you considering pre-building all the possible combinations? The possible combinations for just the formatters "%s", "%c", "%d",... would probably generate too many libraries.

Fabrizio-Caruso avatar Sep 12 '18 20:09 Fabrizio-Caruso

CP/M programs that use both ack -fp and printf() have 2 copies of some float code, because lang/cem/libcc.ansi/core/stdlib/ext_comp.c duplicates some code from mach/proto/fp to add, compare, and multiply 80-bit floats. One might save space by sharing the code.

One might build a libc.a with ACKCONF_WANT_STDIO_FLOAT = 0, and build a small libc_fp.a with only those few functions that differ when ACKCONF_WANT_STDIO_FLOAT = 1. Then ack -fp would just add libc_fp.a to the link.

kernigh avatar Oct 27 '18 23:10 kernigh

@kernigh I have no idea how Z88DK implements this: Z88DK can even remove converters ("%f", "%d", etc...) that are known to be unused by the coder. This is done through some pragma directives set by the user. I suppose that these pragma directives are used by the linker or optimizer to remove these converters. It could be that libc is split in many portions. The result is very compact binaries (at least half the size obtained by ACK for the 8080 target).

Fabrizio-Caruso avatar Oct 28 '18 09:10 Fabrizio-Caruso