From: cuz Date: Sun, 30 Nov 2003 21:47:40 +0000 (+0000) Subject: Don't remove symbols or otherwise simplify expressions while assembly is X-Git-Tag: V2.12.0~1102 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=9ebc3d1f01fd7141bddaa8b04a6f634555abb4a3;p=cc65 Don't remove symbols or otherwise simplify expressions while assembly is still in progress. There may be information that is needed, and when assembly is done it is still time to do so. (Needs more work). Better expression checks for fragments. Stuff that was detected by the linker before is now handled by the assembler. git-svn-id: svn://svn.cc65.org/cc65/trunk@2700 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/ca65/enum.c b/src/ca65/enum.c index f226e4433..0383cada1 100644 --- a/src/ca65/enum.c +++ b/src/ca65/enum.c @@ -58,7 +58,8 @@ void DoEnum (void) /* Handle the .ENUM command */ { /* Start at zero */ - ExprNode* NextExpr = GenLiteralExpr (0); + long Offs = 0; + ExprNode* BaseExpr = GenLiteralExpr (0); /* Check for a name */ int Anon = (Tok != TOK_IDENT); @@ -104,25 +105,27 @@ void DoEnum (void) /* Skip the equal sign */ NextTok (); - /* Delete the old next expression */ - FreeExpr (NextExpr); - - /* Read the new one */ + /* Read the new expression */ EnumExpr = Expression (); + /* Reset the base expression and the offset */ + FreeExpr (BaseExpr); + BaseExpr = CloneExpr (EnumExpr); + Offs = 0; + } else { - EnumExpr = NextExpr; + /* No assignment, use last value + 1 */ + EnumExpr = GenAddExpr (CloneExpr (BaseExpr), GenLiteralExpr (Offs)); } - /* Generate the next expression from the current one */ - NextExpr = GenAddExpr (CloneExpr (EnumExpr), GenLiteralExpr (1)); - NextExpr = SimplifyExpr (NextExpr); - /* Assign the value to the enum member */ SymDef (Sym, EnumExpr, ADDR_SIZE_DEFAULT, SF_NONE); + /* Increment the offset for the next member */ + ++Offs; + /* Expect end of line */ ConsumeSep (); } @@ -136,8 +139,8 @@ void DoEnum (void) /* End of enum definition */ Consume (TOK_ENDENUM, "`.ENDENUM' expected"); - /* Free the last (unused) enum expression */ - FreeExpr (NextExpr); + /* Free the base expression */ + FreeExpr (BaseExpr); } diff --git a/src/ca65/expr.c b/src/ca65/expr.c index f8e80be48..8280cc4e1 100644 --- a/src/ca65/expr.c +++ b/src/ca65/expr.c @@ -204,13 +204,8 @@ static ExprNode* Symbol (SymEntry* S) } else { /* Mark the symbol as referenced */ SymRef (S); - /* Remove the symbol if possible */ - if (SymHasExpr (S)) { - return CloneExpr (GetSymExpr (S)); - } else { - /* Create symbol node */ - return GenSymExpr (S); - } + /* Create symbol node */ + return GenSymExpr (S); } } @@ -1117,16 +1112,7 @@ ExprNode* Expression (void) * a pointer to the root of the tree. */ { -#if 1 - return SimplifyExpr (Expr0 ()); -#else - /* Test code */ - ExprNode* Expr = Expr0 (); - printf ("Before: "); DumpExpr (Expr, SymResolve); - Expr = SimplifyExpr (Expr); - printf ("After: "); DumpExpr (Expr, SymResolve); - return Expr; -#endif + return Expr0 (); } @@ -1139,13 +1125,8 @@ long ConstExpression (void) { long Val; -#if 1 /* Read the expression */ - ExprNode* Expr = Expr0 (); -#else - /* Test code */ ExprNode* Expr = Expression (); -#endif /* Study the expression */ ExprDesc D; @@ -1182,27 +1163,13 @@ void FreeExpr (ExprNode* Root) -ExprNode* SimplifyExpr (ExprNode* Expr) +ExprNode* SimplifyExpr (ExprNode* Expr, const ExprDesc* D) /* Try to simplify the given expression tree */ { - if (Expr && Expr->Op != EXPR_LITERAL) { - - /* Create an expression description and initialize it */ - ExprDesc D; - ED_Init (&D); - - /* Study the expression */ - StudyExpr (Expr, &D); - - /* Now check if we can generate a literal value */ - if (ED_IsConst (&D)) { - /* No external references */ - FreeExpr (Expr); - Expr = GenLiteralExpr (D.Val); - } - - /* Free allocated memory */ - ED_Done (&D); + if (Expr->Op != EXPR_LITERAL && ED_IsConst (D)) { + /* No external references */ + FreeExpr (Expr); + Expr = GenLiteralExpr (D->Val); } return Expr; } @@ -1243,10 +1210,19 @@ static ExprNode* GenSectionExpr (unsigned SegNum) ExprNode* GenAddExpr (ExprNode* Left, ExprNode* Right) /* Generate an addition from the two operands */ { - ExprNode* Root = NewExprNode (EXPR_PLUS); - Root->Left = Left; - Root->Right = Right; - return Root; + long Val; + if (IsEasyConst (Left, &Val) && Val == 0) { + FreeExpr (Left); + return Right; + } else if (IsEasyConst (Right, &Val) && Val == 0) { + FreeExpr (Right); + return Left; + } else { + ExprNode* Root = NewExprNode (EXPR_PLUS); + Root->Left = Left; + Root->Right = Right; + return Root; + } } diff --git a/src/ca65/expr.h b/src/ca65/expr.h index a3827e873..de03e19ba 100644 --- a/src/ca65/expr.h +++ b/src/ca65/expr.h @@ -43,6 +43,16 @@ +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +struct ExprDesc; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ @@ -63,7 +73,7 @@ long ConstExpression (void); void FreeExpr (ExprNode* Root); /* Free the expression tree, Root is pointing to. */ -ExprNode* SimplifyExpr (ExprNode* Expr); +ExprNode* SimplifyExpr (ExprNode* Expr, const struct ExprDesc* D); /* Try to simplify the given expression tree */ ExprNode* GenLiteralExpr (long Val); diff --git a/src/ca65/objcode.c b/src/ca65/objcode.c index 890b52cee..35d4dd841 100644 --- a/src/ca65/objcode.c +++ b/src/ca65/objcode.c @@ -144,22 +144,12 @@ void EmitData (const unsigned char* Data, unsigned Size) void EmitByte (ExprNode* Expr) /* Emit one byte */ -{ - long Val; - if (IsConstExpr (Expr, &Val)) { - /* Constant expression, emit literal byte */ - FreeExpr (Expr); - if ((Val & ~0xFF) != 0) { - Error ("Range error"); - } - Emit0 (Val & 0xFF); - } else { - /* Create a new fragment */ - Fragment* F = GenFragment (FRAG_EXPR, 1); +{ + /* Create a new fragment */ + Fragment* F = GenFragment (FRAG_EXPR, 1); - /* Set the data */ - F->V.Expr = Expr; - } + /* Set the data */ + F->V.Expr = Expr; } @@ -167,22 +157,11 @@ void EmitByte (ExprNode* Expr) void EmitWord (ExprNode* Expr) /* Emit one word */ { - long Val; - if (IsConstExpr (Expr, &Val)) { - /* Constant expression, emit literal byte */ - FreeExpr (Expr); - if ((Val & ~0xFFFF) != 0) { - Error ("Range error"); - } - Emit0 (Val & 0xFF); - Emit0 ((Val >> 8) & 0xFF); - } else { - /* Create a new fragment */ - Fragment* F = GenFragment (FRAG_EXPR, 2); + /* Create a new fragment */ + Fragment* F = GenFragment (FRAG_EXPR, 2); - /* Set the data */ - F->V.Expr = Expr; - } + /* Set the data */ + F->V.Expr = Expr; } @@ -190,23 +169,11 @@ void EmitWord (ExprNode* Expr) void EmitFarAddr (ExprNode* Expr) /* Emit a 24 bit expression */ { - long Val; - if (IsConstExpr (Expr, &Val)) { - /* Constant expression, emit literal byte */ - FreeExpr (Expr); - if ((Val & ~0xFFFFFF) != 0) { - Error ("Range error"); - } - Emit0 (Val & 0xFF); - Emit0 ((Val >> 8) & 0xFF); - Emit0 ((Val >> 16) & 0xFF); - } else { - /* Create a new fragment */ - Fragment* F = GenFragment (FRAG_EXPR, 3); + /* Create a new fragment */ + Fragment* F = GenFragment (FRAG_EXPR, 3); - /* Set the data */ - F->V.Expr = Expr; - } + /* Set the data */ + F->V.Expr = Expr; } @@ -214,21 +181,11 @@ void EmitFarAddr (ExprNode* Expr) void EmitDWord (ExprNode* Expr) /* Emit one dword */ { - long Val; - if (IsConstExpr (Expr, &Val)) { - /* Constant expression, emit literal byte */ - FreeExpr (Expr); - Emit0 (Val & 0xFF); - Emit0 ((Val >> 8) & 0xFF); - Emit0 ((Val >> 16) & 0xFF); - Emit0 ((Val >> 24) & 0xFF); - } else { - /* Create a new fragment */ - Fragment* F = GenFragment (FRAG_EXPR, 4); + /* Create a new fragment */ + Fragment* F = GenFragment (FRAG_EXPR, 4); - /* Set the data */ - F->V.Expr = Expr; - } + /* Set the data */ + F->V.Expr = Expr; } diff --git a/src/ca65/segment.c b/src/ca65/segment.c index 66f67e57f..c0e64b501 100644 --- a/src/ca65/segment.c +++ b/src/ca65/segment.c @@ -37,6 +37,7 @@ #include /* common */ +#include "addrsize.h" #include "mmodel.h" #include "segnames.h" #include "xmalloc.h" @@ -51,6 +52,7 @@ #include "objfile.h" #include "segment.h" #include "spool.h" +#include "studyexpr.h" #include "symtab.h" @@ -291,35 +293,44 @@ void SegCheck (void) Fragment* F = S->Root; while (F) { if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) { - long Val; - if (IsConstExpr (F->V.Expr, &Val)) { - /* We are able to evaluate the expression. Check for - * range errors. - */ - unsigned I; + + /* We have an expression, study it */ + ExprDesc ED; + ED_Init (&ED); + StudyExpr (F->V.Expr, &ED); + + /* Try to simplify it before looking further */ + F->V.Expr = SimplifyExpr (F->V.Expr, &ED); + + /* Check if the expression is constant */ + if (ED_IsConst (&ED)) { + + /* The expression is constant. Check for range errors. */ int Abs = (F->Type != FRAG_SEXPR); + long Val = ED.Val; + unsigned I; if (F->Len == 1) { - if (Abs) { - /* Absolute value */ - if (Val > 255) { + if (Abs) { + /* Absolute value */ + if (Val > 255) { PError (&F->Pos, "Range error"); - } - } else { - /* PC relative value */ - if (Val < -128 || Val > 127) { + } + } else { + /* PC relative value */ + if (Val < -128 || Val > 127) { PError (&F->Pos, "Range error"); - } - } + } + } } else if (F->Len == 2) { if (Abs) { - /* Absolute value */ - if (Val > 65535) { + /* Absolute value */ + if (Val > 65535) { PError (&F->Pos, "Range error"); - } - } else { - /* PC relative value */ - if (Val < -32768 || Val > 32767) { + } + } else { + /* PC relative value */ + if (Val < -32768 || Val > 32767) { PError (&F->Pos, "Range error"); } } @@ -334,15 +345,22 @@ void SegCheck (void) Val >>= 8; } F->Type = FRAG_LITERAL; - } else { + + } else if (ED.AddrSize != ADDR_SIZE_DEFAULT) { + /* We cannot evaluate the expression now, leave the job for - * the linker. However, we are able to check for explicit - * byte expressions and we will do so. + * the linker. However, we can check if the address size + * matches the fragment size, and we will do so. */ - if (F->Type == FRAG_EXPR && F->Len == 1 && !IsByteExpr (F->V.Expr)) { + if ((F->Len == 1 && ED.AddrSize > ADDR_SIZE_ZP) || + (F->Len == 2 && ED.AddrSize > ADDR_SIZE_ABS) || + (F->Len == 3 && ED.AddrSize > ADDR_SIZE_FAR)) { PError (&F->Pos, "Range error"); } } + + /* Release memory allocated for the expression decriptor */ + ED_Done (&ED); } F = F->Next; } @@ -495,7 +513,7 @@ void InitSegments (void) /* Initialize segment sizes. The segment definitions do already contain * the correct values for the default case (near), so we must only change * things that should be different. - */ + */ switch (MemoryModel) { case MMODEL_NEAR: diff --git a/src/ca65/studyexpr.c b/src/ca65/studyexpr.c index 2421b3565..c71a27109 100644 --- a/src/ca65/studyexpr.c +++ b/src/ca65/studyexpr.c @@ -441,6 +441,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D) SymMarkUser (Sym); StudyExprInternal (GetSymExpr (Sym), D); SymUnmarkUser (Sym); + ED_UpdateAddrSize (D, GetSymAddrSize (Sym)); } } else { /* The symbol is either undefined or an import. In both cases, track