}
Entry->Flags &= ~(SC_STORAGE | SC_DEF);
} else {
- /* A global (including static) uninitialized variable
- ** is only a tentative definition. For example, this is valid:
+ /* A global (including static) uninitialized variable is
+ ** only a tentative definition. For example, this is valid:
** int i;
** int i;
** static int j;
** static int j = 42;
- ** Code for these will be generated in FinishCompile.
+ ** Code for them will be generated by FinishCompile().
** For now, just save the BSS segment name
- ** (can be set with #pragma bss-name)
+ ** (can be set by #pragma bss-name).
*/
const char* bssName = GetSegName (SEG_BSS);
+
if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) {
- Error ("Global variable `%s' has already been defined in `%s' segment",
+ Error ("Global variable `%s' already was defined in the `%s' segment.",
Entry->Name, Entry->V.BssName);
}
Entry->V.BssName = xstrdup (bssName);
SymEntry* Entry;
/* Walk over all global symbols:
- ** - for functions do cleanup, optimizations ...
+ ** - for functions, do clean-up and optimizations
** - generate code for uninitialized global variables
*/
for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
CS_MergeLabels (Entry->V.F.Seg->Code);
RunOpt (Entry->V.F.Seg->Code);
} else if ((Entry->Flags & (SC_STORAGE | SC_DEF | SC_STATIC)) == (SC_STORAGE | SC_STATIC)) {
- /* Tentative definition of uninitialized global variable */
+ /* Assembly definition of uninitialized global variable */
+
+ /* Set the segment name only when it changes */
+ if (strcmp (GetSegName (SEG_BSS), Entry->V.BssName) != 0) {
+ SetSegName (SEG_BSS, Entry->V.BssName);
+ g_segname (SEG_BSS);
+ }
g_usebss ();
- SetSegName (SEG_BSS, Entry->V.BssName);
- g_segname (SEG_BSS); /* TODO: skip if same as before */
g_defgloblabel (Entry->Name);
g_res (SizeOf (Entry->Type));
- /* Mark as defined, so that it will be exported not imported */
+ /* Mark as defined; so that it will be exported, not imported */
Entry->Flags |= SC_DEF;
}
}
static void SegNamePragma (StrBuf* B, segment_t Seg)
/* Handle a pragma that expects a segment name parameter */
{
- StrBuf S = AUTO_STRBUF_INITIALIZER;
const char* Name;
+ StrBuf S = AUTO_STRBUF_INITIALIZER;
+ int Push = 0;
/* Check for the "push" or "pop" keywords */
- int Push = 0;
switch (ParsePushPop (B)) {
case PP_NONE:
case PP_POP:
/* Pop the old value and output it */
PopSegName (Seg);
- g_segname (Seg);
+
+ /* BSS variables are output at the end of the compilation. Don't
+ ** bother to change their segment, now.
+ */
+ if (Seg != SEG_BSS) {
+ g_segname (Seg);
+ }
/* Done */
goto ExitPoint;
} else {
SetSegName (Seg, Name);
}
- g_segname (Seg);
+
+ /* BSS variables are output at the end of the compilation. Don't
+ ** bother to change their segment, now.
+ */
+ if (Seg != SEG_BSS) {
+ g_segname (Seg);
+ }
} else {