From 6c34eeb93d7adb325c668a2287e7a46ac9bbc1cc Mon Sep 17 00:00:00 2001 From: cuz Date: Tue, 17 Jul 2001 12:50:38 +0000 Subject: [PATCH] Move the increment code of a for loop after the loop body. git-svn-id: svn://svn.cc65.org/cc65/trunk@799 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/cc65/asmcode.c | 10 ++++++++++ src/cc65/asmcode.h | 5 +++++ src/cc65/codeseg.c | 35 +++++++---------------------------- src/cc65/codeseg.h | 24 +++++++++++++++++++++++- src/cc65/stmt.c | 30 ++++++++++++++++++++++++------ 5 files changed, 69 insertions(+), 35 deletions(-) diff --git a/src/cc65/asmcode.c b/src/cc65/asmcode.c index 8308249e4..39092092f 100644 --- a/src/cc65/asmcode.c +++ b/src/cc65/asmcode.c @@ -68,6 +68,16 @@ void RemoveCode (CodeMark M) +void MoveCode (CodeMark Start, CodeMark End, CodeMark Target) +/* Move the code between Start (inclusive) and End (exclusive) to + * (before) Target. + */ +{ + CS_MoveEntries (CS->Code, Start, End - Start, Target); +} + + + void WriteOutput (FILE* F) /* Write the final output to a file */ { diff --git a/src/cc65/asmcode.h b/src/cc65/asmcode.h index 47ea65586..2db1ecbd4 100644 --- a/src/cc65/asmcode.h +++ b/src/cc65/asmcode.h @@ -68,6 +68,11 @@ CodeMark GetCodePos (void); void RemoveCode (CodeMark M); /* Remove all code after the given code marker */ +void MoveCode (CodeMark Start, CodeMark End, CodeMark Target); +/* Move the code between Start (inclusive) and End (exclusive) to + * (before) Target. + */ + void WriteOutput (FILE* F); /* Write the final output to a file */ diff --git a/src/cc65/codeseg.c b/src/cc65/codeseg.c index 17457768f..e06c508ad 100644 --- a/src/cc65/codeseg.c +++ b/src/cc65/codeseg.c @@ -235,7 +235,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) L = ReadToken (L+1, ",)", Arg, sizeof (Arg)); /* Check for errors */ - if (*L == '\0') { + if (*L == '\0') { Error ("ASM code error: syntax error"); return 0; } @@ -278,7 +278,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) AM = AM65_ZP_IND; } else { Error ("ASM code error: syntax error"); - return 0; + return 0; } } break; @@ -321,7 +321,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, LineInfo* LI, const char* L) AM = AM65_ABSX; } } else if (Reg == 'Y') { - AM = AM65_ABSY; + AM = AM65_ABSY; } else { Error ("ASM code error: syntax error"); return 0; @@ -545,43 +545,22 @@ void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count) * memory moving. */ while (Count--) { - CS_DelEntry (S, Start + Count); + CS_DelEntry (S, Start + Count); } } -void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos) -/* Move an entry from one position to another. OldPos is the current position - * of the entry, NewPos is the new position of the entry. - */ -{ - /* Get the code entry and remove it from the collection */ - CodeEntry* E = CS_GetEntry (S, OldPos); - CollDelete (&S->Entries, OldPos); - - /* Correct NewPos if needed */ - if (NewPos >= OldPos) { - /* Position has changed with removal */ - --NewPos; - } - - /* Now insert it at the new position */ - CollInsert (&S->Entries, E, NewPos); -} - - - struct CodeEntry* CS_GetNextEntry (CodeSeg* S, unsigned Index) /* Get the code entry following the one with the index Index. If there is no * following code entry, return NULL. */ { if (Index >= CollCount (&S->Entries)-1) { - /* This is the last entry */ - return 0; + /* This is the last entry */ + return 0; } else { - /* Code entries left */ + /* Code entries left */ return CollAtUnchecked (&S->Entries, Index+1); } } diff --git a/src/cc65/codeseg.h b/src/cc65/codeseg.h index a157a79d4..fd842847d 100644 --- a/src/cc65/codeseg.h +++ b/src/cc65/codeseg.h @@ -116,10 +116,32 @@ void CS_DelEntries (CodeSeg* S, unsigned Start, unsigned Count); * labels attached to the entries and so on. */ -void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos); +#if defined(HAVE_INLINE) +INLINE void CS_MoveEntry (CodeSeg* S, unsigned OldPos, unsigned NewPos) /* Move an entry from one position to another. OldPos is the current position * of the entry, NewPos is the new position of the entry. */ +{ + CollMove (&S->Entries, OldPos, NewPos); +} +#else +# define CS_MoveEntry(S, OldPos, NewPos) CollMove (&(S)->Entries, OldPos, NewPos) +#endif + +#if defined(HAVE_INLINE) +INLINE void CS_MoveEntries (CodeSeg* S, unsigned Start, unsigned Count, unsigned NewPos) +/* Move a range of entries from one position to another. Start is the index + * of the first entry to move, Count is the number of entries and NewPos is + * the index of the target entry. The entry with the index Start will later + * have the index NewPos. All entries with indices NewPos and above are + * moved to higher indices. + */ +{ + CollMoveMultiple (&S->Entries, Start, Count, NewPos); +} +#else +# define CS_MoveEntries(S, Start, Count, NewPos) CollMoveMultiple (&(S)->Entries, Start, Count, NewPos) +#endif #if defined(HAVE_INLINE) INLINE struct CodeEntry* CS_GetEntry (CodeSeg* S, unsigned Index) diff --git a/src/cc65/stmt.c b/src/cc65/stmt.c index 0de58c6d2..2ec08dcc2 100644 --- a/src/cc65/stmt.c +++ b/src/cc65/stmt.c @@ -81,7 +81,7 @@ static void CheckSemi (int* PendingToken) static void SkipPending (int PendingToken) /* Skip the pending token if we have one */ { - if (PendingToken) { + if (PendingToken) { NextToken (); } } @@ -641,6 +641,9 @@ static void ForStatement (void) struct expent lval1; struct expent lval2; struct expent lval3; + int HaveIncExpr; + CodeMark IncExprStart; + CodeMark IncExprEnd; int PendingToken; /* Get several local labels needed later */ @@ -649,7 +652,7 @@ static void ForStatement (void) unsigned IncLabel = GetLocalLabel (); unsigned lstat = GetLocalLabel (); - /* Skip the FOR token */ + /* Skip the FOR token */ NextToken (); /* Add the loop to the loop stack */ @@ -677,17 +680,24 @@ static void ForStatement (void) } ConsumeSemi (); + /* Remember the start of the increment expression */ + IncExprStart = GetCodePos(); + /* Label for the increment expression */ g_defcodelabel (IncLabel); /* Parse the increment expression */ - if (CurTok.Tok != TOK_RPAREN) { + HaveIncExpr = (CurTok.Tok != TOK_RPAREN); + if (HaveIncExpr) { expression (&lval3); } /* Jump to the test */ g_jump (TestLabel); + /* Remember the end of the increment expression */ + IncExprEnd = GetCodePos(); + /* Skip the closing paren */ ConsumeRParen (); @@ -695,9 +705,17 @@ static void ForStatement (void) g_defcodelabel (lstat); Statement (&PendingToken); - /* Jump back to the increment expression */ - g_jump (IncLabel); - + /* If we had an increment expression, move the code to the bottom of + * the loop. In this case we don't need to jump there at the end of + * the loop body. + */ + if (HaveIncExpr) { + MoveCode (IncExprStart, IncExprEnd, GetCodePos()); + } else { + /* Jump back to the increment expression */ + g_jump (IncLabel); + } + /* Skip a pending token if we have one */ SkipPending (PendingToken);