It seems to me there is an issue in SDCC's handling of local static constants.
The generated code is correct, but unnecessarily complex in terms of RAM,
ROM/flash, and execution time.
A simple example follows. I also attach the Z80 assembly output generated by
SDCC, as well as the corresponding x86 assembly output provided by GCC 4.4.3
in Ubuntu 10.04. It seems to me this is not specific to the Z80, however.
SDCC version from SVN rev #5892:
mcs51/gbz80/z80/ds390/pic16/pic14/TININative/ds400/hc08 2.9.7 #5892 (Jul 26 2010) (Mac OS X ppc)
Example code (compiled using 'sdcc -mz80 statics.c -o statics'):
----------------------------------------------------------------
static const int t1 = 3; /* As expected, t1 resides in the CODE segment.*/
static int t2 = 5; /* As expected, t2 resides in the DATA segment, and
* initialization code is generated. */
int main(void)
{
/* However, both t3 and t4 end up in the DATA segment, and initialization
* code is generated for both. For t4, this is required, but for t3 this is
* unnecessary. Instead, t3 should be treated just like t1 above. */
static const int t3 = 7;
static int t4 = 11;
return 0;
}
Z80 assembly output for example
x86 assembly output from GCC
Moving to feature requests, since it's not a bug.
Increasing priority since this is an importatn issue - especially considering that it affects arrays, too.
Philipp
I just added a patch ('local-static-const.patch') that makes SDCC put t3 in the code area, and the regression tests still run just as fine as without the patch.
It seems to me that using 'sym->level' to check whether it is a static-lifetime variable is a bit inprecise. Am I understanding the code right? Looking forward to comments from someone more experienced with the SDCC codebase.
Revised patch (rev2)
Seems I was a bit too fast with the previous patch -- global non-static variables were accidentally omitted.
Here's a revised patch (rev2), ensuring that global constants (static and non-static) as well as local static constants end up in the CODE segment.
Also, a clarification: the attached Z80 assembly output is from the _unpatched_ SDCC, to clarify the issue rather than the patch.
Looking forward to your comments.
We shall look into this after the sdcc 3.0.0 release scheduled for october.
However there currently is another problem in sdcc, which prevents implementing this: Contrary to the C99 standard, verse 1644, sdcc alows initializers for static objects other than constant expressions and string literals. Obviously we can't place the static constant in ROM, if it's initialized at runtime by a non-constant expression.
I just opened bug report #3073647 for this problem.
Philipp
Implemented in revision #7279.
Philipp
P.S.: Maybe this should be extended to non-static local const variables that are initialized to constant expressions?