mirror of
https://github.com/cc65/cc65.git
synced 2025-08-08 06:25:17 +00:00
Stopped cc65 from putting redundant .segment directives into its Assembly output.
This commit is contained in:
@@ -243,19 +243,20 @@ static void Parse (void)
|
|||||||
}
|
}
|
||||||
Entry->Flags &= ~(SC_STORAGE | SC_DEF);
|
Entry->Flags &= ~(SC_STORAGE | SC_DEF);
|
||||||
} else {
|
} else {
|
||||||
/* A global (including static) uninitialized variable
|
/* A global (including static) uninitialized variable is
|
||||||
** is only a tentative definition. For example, this is valid:
|
** only a tentative definition. For example, this is valid:
|
||||||
** int i;
|
** int i;
|
||||||
** int i;
|
** int i;
|
||||||
** static int j;
|
** static int j;
|
||||||
** static int j = 42;
|
** 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
|
** 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);
|
const char* bssName = GetSegName (SEG_BSS);
|
||||||
|
|
||||||
if (Entry->V.BssName && strcmp (Entry->V.BssName, bssName) != 0) {
|
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->Name, Entry->V.BssName);
|
||||||
}
|
}
|
||||||
Entry->V.BssName = xstrdup (bssName);
|
Entry->V.BssName = xstrdup (bssName);
|
||||||
@@ -419,7 +420,7 @@ void FinishCompile (void)
|
|||||||
SymEntry* Entry;
|
SymEntry* Entry;
|
||||||
|
|
||||||
/* Walk over all global symbols:
|
/* Walk over all global symbols:
|
||||||
** - for functions do cleanup, optimizations ...
|
** - for functions, do clean-up and optimizations
|
||||||
** - generate code for uninitialized global variables
|
** - generate code for uninitialized global variables
|
||||||
*/
|
*/
|
||||||
for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
|
for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
|
||||||
@@ -429,13 +430,17 @@ void FinishCompile (void)
|
|||||||
CS_MergeLabels (Entry->V.F.Seg->Code);
|
CS_MergeLabels (Entry->V.F.Seg->Code);
|
||||||
RunOpt (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)) {
|
} 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 ();
|
g_usebss ();
|
||||||
SetSegName (SEG_BSS, Entry->V.BssName);
|
|
||||||
g_segname (SEG_BSS); /* TODO: skip if same as before */
|
|
||||||
g_defgloblabel (Entry->Name);
|
g_defgloblabel (Entry->Name);
|
||||||
g_res (SizeOf (Entry->Type));
|
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;
|
Entry->Flags |= SC_DEF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -386,11 +386,11 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*))
|
|||||||
static void SegNamePragma (StrBuf* B, segment_t Seg)
|
static void SegNamePragma (StrBuf* B, segment_t Seg)
|
||||||
/* Handle a pragma that expects a segment name parameter */
|
/* Handle a pragma that expects a segment name parameter */
|
||||||
{
|
{
|
||||||
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
|
||||||
const char* Name;
|
const char* Name;
|
||||||
|
StrBuf S = AUTO_STRBUF_INITIALIZER;
|
||||||
|
int Push = 0;
|
||||||
|
|
||||||
/* Check for the "push" or "pop" keywords */
|
/* Check for the "push" or "pop" keywords */
|
||||||
int Push = 0;
|
|
||||||
switch (ParsePushPop (B)) {
|
switch (ParsePushPop (B)) {
|
||||||
|
|
||||||
case PP_NONE:
|
case PP_NONE:
|
||||||
@@ -403,7 +403,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
|
|||||||
case PP_POP:
|
case PP_POP:
|
||||||
/* Pop the old value and output it */
|
/* Pop the old value and output it */
|
||||||
PopSegName (Seg);
|
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 */
|
/* Done */
|
||||||
goto ExitPoint;
|
goto ExitPoint;
|
||||||
@@ -434,7 +440,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
|
|||||||
} else {
|
} else {
|
||||||
SetSegName (Seg, Name);
|
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 {
|
} else {
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user