]> git.sur5r.net Git - cc65/commitdiff
Don't remove symbols or otherwise simplify expressions while assembly is
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 30 Nov 2003 21:47:40 +0000 (21:47 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sun, 30 Nov 2003 21:47:40 +0000 (21:47 +0000)
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

src/ca65/enum.c
src/ca65/expr.c
src/ca65/expr.h
src/ca65/objcode.c
src/ca65/segment.c
src/ca65/studyexpr.c

index f226e4433f125652ecaa2b648bd0461a0755bd42..0383cada13a2508123569b0683c23f47e1899fbb 100644 (file)
@@ -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);
 }
 
 
index f8e80be480e65594243548f6ea271fb6c93e2754..8280cc4e137802d9a5f1aafae632d56bdfb577be 100644 (file)
@@ -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;
+    }
 }
 
 
index a3827e873af53a9fbd7bd9e83320a39c2b6bbd32..de03e19ba5cf18df96d2cce3d1db09105c69616a 100644 (file)
 
 
 
+/*****************************************************************************/
+/*                                 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);
index 890b52ceede625370fc0cd0a1e162df72ec24c8c..35d4dd841697fdf75e432b2ebf45bc9cb5a01321 100644 (file)
@@ -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;
 }
 
 
index 66f67e57ffc5c470ce2b9cb1a2d0d49fd3c0e9f8..c0e64b5018b66c8b117f13d3d8f8f3e27edbf102 100644 (file)
@@ -37,6 +37,7 @@
 #include <errno.h>
 
 /* 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:
index 2421b35659265e89c18b4ff127570d4eef6e1068..c71a27109f509e6e305c1a0e3b5fa887c6443120 100644 (file)
@@ -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