X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fcodeseg.c;h=492a322b969438dac42b5304b59dac928f207168;hb=ed2767e65f05b853eda1b071938062126de6f517;hp=55b7aa697d56e98d688cd01d98fa0a2a883b64d5;hpb=82b998117aac8b470e0250458b61d7e804c9ca93;p=cc65 diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 55b7aa697..492a322b9 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -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 */