#405 Z80's stubs.s pulls in ~1Kb unneeded library code

None
closed-fixed
None
5
2015-01-02
2013-10-04
No

Fiddling with the simple random function from Numerical recipies, when compiling the function alone, it looked reasonable (70-ish bytes) but after linking, there would be >1600 bytes in the code section.

Test case:

/* stubs.c */
unsigned long idum = 0;

unsigned long
rnd(void)
{
        idum = 1664525L * idum + 1013904223L;

        return (idum);
}

int
main(void)
{
    long myval = rnd();

    return (1);
}

stubs.lst shows rnd() occupies 4C (76) bytes, main() only takes up only 7 bytes, yet the stubs.map file shows the _CODE section is 1617 bytes:

$ grep bytes stubs.map
.  .ABS.                            00000000    00000000 =           0. bytes (ABS,CON)
_CODE                               00000200    00000651 =        1617. bytes (REL,CON)
_CODE                               00000200    00000651 =        1617. bytes (REL,CON)
_HEADER0                            00000000    00000003 =           3. bytes (ABS,CON)
_HEADER1                            00000000    00000002 =           2. bytes (ABS,CON)
_HEADER2                            00000000    00000002 =           2. bytes (ABS,CON)
_HEADER3                            00000000    00000002 =           2. bytes (ABS,CON)
_HEADER4                            00000000    00000002 =           2. bytes (ABS,CON)
_HEADER5                            00000000    00000002 =           2. bytes (ABS,CON)
_HEADER6                            00000000    00000002 =           2. bytes (ABS,CON)
_HEADER7                            00000000    00000002 =           2. bytes (ABS,CON)
_HEADER8                            00000000    0000000C =          12. bytes (ABS,CON)
_INITIALIZER                        00000851    00000004 =           4. bytes (REL,CON)
_GSINIT                             00000855    0000000F =          15. bytes (REL,CON)
_GSFINAL                            00000864    00000001 =           1. bytes (REL,CON)
_INITIALIZED                        00008000    00000004 =           4. bytes (REL,CON)

It is the inclusion of the long multiplication which calls __mullong_rrx_s, but this label is only defined in stubs.s, which causes the linker to pull in many other similar functions which are also listed in stubs.s, regardless of whether or not they are used.

stubs.s mullong_rrx_s entry point simply jp's to mullong, and tracking the calls manually from there gives me:

jp _mullong (from stubs.s) - 3 bytes
_mullong - 0x1A9 bytes (425)
__mulint_rrx_s - 0x1B bytes (27)

So I would expect the inclusion of a long multiplication to add around 450 bytes, not 1600.

Can stubs.s be split up please, leaving the linker to only pull in what is actually required?

(The above code was generated using sdcc "SDCC : z80 3.3.1 #8787 (Jul 30 2013) (Solaris i386)")

Discussion

  • Philipp Klaus Krause

    Well, this stubs thing looks like some mechanism to help a debugger to me. But I don't see it documented anywhere, and other ports don't seem to use it. Even when split up there's still an extra indirection.
    So why not just kill the stubs and call the functions directly?

    Philipp

     
  • Philipp Klaus Krause

    • assigned_to: Philipp Klaus Krause
    • Group: -->
     
  • Philipp Klaus Krause

    • status: open --> closed-fixed
     
  • Philipp Klaus Krause

    The stubs are gone in revision #8987.

    Philipp

    P.S.: It would be possible to split support routines into more files to save a few more bytes; for the gbz80 a lot could be saved, since the support rotines are in few big files.

     

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks