]> git.sur5r.net Git - cc65/commitdiff
Stopped cc65 from putting redundant .segment directives into its Assembly output. 454/head
authorGreg King <gregdk@users.sf.net>
Sat, 17 Jun 2017 01:53:50 +0000 (21:53 -0400)
committerGreg King <gregdk@users.sf.net>
Sat, 17 Jun 2017 01:53:50 +0000 (21:53 -0400)
src/cc65/compile.c
src/cc65/pragma.c

index 3c104215448f1700593b3e4794b0991c0441e268..d79ef350b9ff102d86afc8b45f787bf0d5c5065b 100644 (file)
@@ -243,19 +243,20 @@ static void Parse (void)
                         }
                         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);
@@ -419,7 +420,7 @@ void FinishCompile (void)
     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) {
@@ -429,13 +430,17 @@ void FinishCompile (void)
             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;
         }
     }
index 3dfc6266824cb9fd3de7d04fffbea84257185867..de1979c12569b15559578e03c0024bf5247b4240 100644 (file)
@@ -386,11 +386,11 @@ static void StringPragma (StrBuf* B, void (*Func) (const char*))
 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:
@@ -403,7 +403,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
         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;
@@ -434,7 +440,13 @@ static void SegNamePragma (StrBuf* B, segment_t Seg)
         } 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 {