]> git.sur5r.net Git - cc65/blobdiff - src/cc65/codeseg.c
Changed names of the pragmas to be identical to the corresponding command line
[cc65] / src / cc65 / codeseg.c
index 55b7aa697d56e98d688cd01d98fa0a2a883b64d5..492a322b969438dac42b5304b59dac928f207168 100644 (file)
@@ -337,13 +337,13 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
                if (*L == ',') {
                    L = SkipSpace (L+1);
                    if (toupper (*L) != 'Y') {
-                       Error ("ASM code error: `Y' expected");
+                       Error ("ASM code error: `Y' expected");
                        return 0;
                    }
                    L = SkipSpace (L+1);
                    if (*L != '\0') {
-                       Error ("ASM code error: syntax error");
-                       return 0;
+                       Error ("ASM code error: syntax error");
+                       return 0;
                    }
                    AM = AM65_ZP_INDY;
                } else if (*L == '\0') {
@@ -375,6 +375,12 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
                } else if (GetZPInfo(Arg) != 0) {
                    AM = AM65_ZP;
                } else {
+                    /* Check for subroutine call to local label */
+                    if ((OPC->Info & OF_CALL) && IsLocalLabelName (Arg)) {
+                        Error ("ASM code error: "
+                               "Cannot use local label `%s' in subroutine call",
+                               Arg);
+                    }
                    AM = AM65_ABS;
                }
            } else if (*L == ',') {
@@ -387,20 +393,20 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L)
                    Reg = toupper (*L);
                    L = SkipSpace (L+1);
                    if (Reg == 'X') {
-                       if (GetZPInfo(Arg) != 0) {
-                           AM = AM65_ZPX;
-                       } else {
-                           AM = AM65_ABSX;
-                       }
+                       if (GetZPInfo(Arg) != 0) {
+                           AM = AM65_ZPX;
+                       } else {
+                           AM = AM65_ABSX;
+                       }
                    } else if (Reg == 'Y') {
-                       AM = AM65_ABSY;
+                       AM = AM65_ABSY;
                    } else {
-                       Error ("ASM code error: syntax error");
-                       return 0;
+                       Error ("ASM code error: syntax error");
+                       return 0;
                    }
                    if (*L != '\0') {
-                       Error ("ASM code error: syntax error");
-                       return 0;
+                       Error ("ASM code error: syntax error");
+                       return 0;
                    }
                }
            }
@@ -1044,6 +1050,86 @@ void CS_MoveLabelRef (CodeSeg* S, struct CodeEntry* E, CodeLabel* L)
 
 
 
+void CS_DelCodeRange (CodeSeg* S, unsigned First, unsigned Last)
+/* Delete all entries between first and last, both inclusive. The function
+ * can only handle basic blocks (First is the only entry, Last the only exit)
+ * and no open labels. It will call FAIL if any of these preconditions are
+ * violated.
+ */
+{
+    unsigned   I;
+    CodeEntry* FirstEntry;
+
+    /* Do some sanity checks */
+    CHECK (First <= Last && Last < CS_GetEntryCount (S));
+
+    /* If Last is actually the last insn, call CS_DelCodeAfter instead, which
+     * is more flexible in this case.
+     */
+    if (Last == CS_GetEntryCount (S) - 1) {
+        CS_DelCodeAfter (S, First);
+        return;
+    }
+
+    /* Get the first entry and check if it has any labels. If it has, move
+     * them to the insn following Last. If Last is the last insn of the code
+     * segment, make them ownerless and move them to the label pool.
+     */
+    FirstEntry = CS_GetEntry (S, First);
+    if (CE_HasLabel (FirstEntry)) {
+        /* Get the entry following last */
+        CodeEntry* FollowingEntry = CS_GetNextEntry (S, Last);
+        if (FollowingEntry) {
+            /* There is an entry after Last - move the labels */
+            CS_MoveLabels (S, FirstEntry, FollowingEntry);
+        } else {
+           /* Move the labels to the pool and clear the owner pointer */
+           CS_MoveLabelsToPool (S, FirstEntry);
+        }
+    }
+
+    /* First pass: Delete all references to labels. If the reference count
+     * for a label drops to zero, delete it.
+     */
+    for (I = Last; I >= First; --I) {
+
+               /* Get the next entry */
+               CodeEntry* E = CS_GetEntry (S, I);
+
+               /* Check if this entry has a label reference */
+               if (E->JumpTo) {
+
+                   /* If the label is a label in the label pool, this is an error */
+                   CodeLabel* L = E->JumpTo;
+                   CHECK (CollIndex (&S->Labels, L) < 0);
+
+           /* Remove the reference to the label */
+           CS_RemoveLabelRef (S, E);
+       }
+    }
+
+    /* Second pass: Delete the instructions. If a label attached to an
+     * instruction still has references, it must be references from outside
+     * the deleted area, which is an error.
+     */
+    for (I = Last; I >= First; --I) {
+
+       /* Get the next entry */
+       CodeEntry* E = CS_GetEntry (S, I);
+
+               /* Check if this entry has a label attached */
+       CHECK (!CE_HasLabel (E));
+
+       /* Delete the pointer to the entry */
+       CollDelete (&S->Entries, I);
+
+       /* Delete the entry itself */
+       FreeCodeEntry (E);
+    }
+}
+
+
+
 void CS_DelCodeAfter (CodeSeg* S, unsigned Last)
 /* Delete all entries including the given one */
 {
@@ -1309,7 +1395,7 @@ void CS_Output (CodeSeg* S)
                     const char* N = strchr (L, '\n');
                     if (N) {
                         /* We have a newline, just write the first part */
-                        WriteOutput ("%.*s\n; ", N - L, L);
+                        WriteOutput ("%.*s\n; ", (int) (N - L), L);
                         L = N+1;
                     } else {
                         /* No Newline, write as is */
@@ -1317,7 +1403,7 @@ void CS_Output (CodeSeg* S)
                         break;
                     }
                 }
-                WriteOutput ("\n;\n");
+                WriteOutput (";\n");
            }
 
            /* Add line debug info */