mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
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
This commit is contained in:
parent
db707db0f1
commit
6c34eeb93d
@ -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 */
|
||||
{
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user