]> git.sur5r.net Git - cc65/commitdiff
Move evaluation of the argument for .BANK into the linker. It is otherwise too
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 30 Jun 2012 17:18:03 +0000 (17:18 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 30 Jun 2012 17:18:03 +0000 (17:18 +0000)
restricted, since no imported symbols may be used.

git-svn-id: svn://svn.cc65.org/cc65/trunk@5746 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/ca65/expr.c
src/ca65/expr.h
src/ca65/segment.c
src/ca65/studyexpr.c
src/common/exprdefs.h
src/common/objdefs.h
src/common/segdefs.h
src/ld65/config.c
src/ld65/expr.c
src/ld65/segments.c

index 740db2aae3342871721916ede1b624e3a5f759b3..6c68dd8d692c56c347aa36683c9ac4e184a82134 100644 (file)
@@ -243,7 +243,7 @@ static ExprNode* Bank (ExprNode* Operand)
 /* Return the bank of the given segmented expression */
 {
     /* Generate the bank expression */
-    ExprNode* Expr = NewExprNode (EXPR_BANKRAW);
+    ExprNode* Expr = NewExprNode (EXPR_BANK);
     Expr->Left = Operand;
 
     /* Return the result */
@@ -1833,76 +1833,6 @@ ExprNode* CloneExpr (ExprNode* Expr)
 
 
 
-ExprNode* FinalizeExpr (ExprNode* Expr, const Collection* LineInfos)
-/* Finalize an expression tree before it is written to the file. This will
- * replace EXPR_BANKRAW nodes by EXPR_BANK nodes, and replace constant
- * expressions by their result. The LineInfos are used when diagnosing errors.
- * Beware: The expression tree may get replaced in future versions, so don't
- * use Expr after calling this function.
- */
-{
-    ExprDesc ED;
-
-    /* Check the type code */
-    switch (EXPR_NODETYPE (Expr->Op)) {
-
-        case EXPR_LEAFNODE:
-            /* Nothing to do for leaf nodes */
-            break;
-
-        case EXPR_BINARYNODE:
-            Expr->Left  = FinalizeExpr (Expr->Left, LineInfos);
-            Expr->Right = FinalizeExpr (Expr->Right, LineInfos);
-            /* FALLTHROUGH */
-
-        case EXPR_UNARYNODE:
-            Expr->Left = FinalizeExpr (Expr->Left, LineInfos);
-
-            /* Special handling for BANKRAW */
-            if (Expr->Op == EXPR_BANKRAW) {
-
-                /* Study the expression */
-                ED_Init (&ED);
-                StudyExpr (Expr->Left, &ED);
-
-                /* The expression must be ok and must have exactly one segment
-                 * reference.
-                 */
-                if (ED.Flags & ED_TOO_COMPLEX) {
-                    LIError (LineInfos,
-                             "Cannot evaluate expression");
-                } else if (ED.SecCount == 0) {
-                    LIError (LineInfos,
-                             ".BANK expects a segment reference");
-                } else if (ED.SecCount > 1 || ED.SecRef[0].Count > 1) {
-                    LIError (LineInfos,
-                             "Too many segment references in argument to .BANK");
-                } else {
-                    Segment* S;
-
-                    FreeExpr (Expr->Left);
-                    Expr->Op = EXPR_BANK;
-                    Expr->Left = 0;
-                    Expr->V.SecNum = ED.SecRef[0].Ref;
-
-                    /* Mark the segment */
-                    S = CollAt (&SegmentList, Expr->V.SecNum);
-                    S->Flags |= SEG_FLAG_BANKREF;
-                }
-
-                /* Cleanup */
-                ED_Done (&ED);
-
-            }
-            break;
-    }
-
-    /* Return the (partial) tree */
-    return Expr;
-}
-
-
-
 void WriteExpr (ExprNode* Expr)
 /* Write the given expression to the object file */
 {
@@ -1940,11 +1870,6 @@ void WriteExpr (ExprNode* Expr)
             WriteExpr (ULabResolve (Expr->V.IVal));
            break;
 
-        case EXPR_BANK:
-            ObjWrite8 (EXPR_BANK);
-            ObjWriteVar (Expr->V.SecNum);
-            break;
-
         default:
            /* Not a leaf node */
             ObjWrite8 (Expr->Op);
index 1bcaba3a06443eb25469722f437b47c888546f65..1011b825d9aeb665fc80850f95ecd213620eca76 100644 (file)
@@ -147,14 +147,6 @@ ExprNode* CloneExpr (ExprNode* Expr);
  * nodes, it will not resolve them.
  */
 
-ExprNode* FinalizeExpr (ExprNode* Expr, const Collection* LineInfos);
-/* Finalize an expression tree before it is written to the file. This will
- * replace EXPR_BANKRAW nodes by EXPR_BANK nodes, and replace constant
- * expressions by their result. The LineInfos are used when diagnosing errors.
- * Beware: The expression tree may get replaced in future versions, so don't
- * use Expr after calling this function.
- */
-
 void WriteExpr (ExprNode* Expr);
 /* Write the given expression to the object file */
 
index c6a08b56d1e5f52f72f0c9c3aec27fcbf2d833f7..d0367ce326ddfb6b8e9976c64b275483fcd64a4f 100644 (file)
@@ -409,9 +409,6 @@ void SegDone (void)
 
                } else {
 
-                    /* Finalize the expression */
-                    F->V.Expr = FinalizeExpr (F->V.Expr, &F->LI);
-
                     /* Simplify the expression */
                     /* ### F->V.Expr = SimplifyExpr (F->V.Expr, &ED); */
 
index 0a2986f2a2cb1eccbd6f5a52e133225d2358961a..76d56359443448a3f62a78c880008fa1352811cf 100644 (file)
@@ -1097,21 +1097,6 @@ static void StudyBoolNot (ExprNode* Expr, ExprDesc* D)
 
 static void StudyBank (ExprNode* Expr, ExprDesc* D)
 /* Study an EXPR_BANK expression node */
-{
-    /* Get the section reference */
-    ED_SecRef* SecRef = ED_GetSecRef (D, Expr->V.SecNum);
-
-    /* Update the data and the address size */
-    ++SecRef->Count;
-
-    /* The expression is always linker evaluated, so invalidate it */
-    ED_Invalidate (D);
-}
-
-
-
-static void StudyBankRaw (ExprNode* Expr, ExprDesc* D)
-/* Study an EXPR_BANKRAW expression node */
 {
     /* Study the expression extracting section references */
     StudyExprInternal (Expr->Left, D);
@@ -1296,10 +1281,6 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
             StudyULabel (Expr, D);
             break;
 
-        case EXPR_BANK:
-            StudyBank (Expr, D);
-            break;
-
        case EXPR_PLUS:
             StudyPlus (Expr, D);
            break;
@@ -1400,8 +1381,8 @@ static void StudyExprInternal (ExprNode* Expr, ExprDesc* D)
             StudyBoolNot (Expr, D);
             break;
 
-        case EXPR_BANKRAW:
-            StudyBankRaw (Expr, D);
+        case EXPR_BANK:
+            StudyBank (Expr, D);
             break;
 
         case EXPR_BYTE0:
index 50a5a25b6365f61cf5a7fbb7058a378e70246d30..fd899d9003f458093bd5bc2d726060d31fcbbe0f 100644 (file)
@@ -60,7 +60,6 @@
 #define EXPR_SEGMENT                   (EXPR_LEAFNODE | 0x04)  /* Linker only */
 #define EXPR_MEMAREA                   (EXPR_LEAFNODE | 0x05)  /* Linker only */
 #define EXPR_ULABEL            (EXPR_LEAFNODE | 0x06)  /* Assembler only */
-#define EXPR_BANK               (EXPR_LEAFNODE | 0x07)
 
 /* Binary operations, left and right hand sides are valid */
 #define EXPR_PLUS                      (EXPR_BINARYNODE | 0x01)
@@ -90,7 +89,7 @@
 #define EXPR_NOT                       (EXPR_UNARYNODE | 0x02)
 #define EXPR_SWAP                      (EXPR_UNARYNODE | 0x03)
 #define EXPR_BOOLNOT           (EXPR_UNARYNODE | 0x04)
-#define EXPR_BANKRAW            (EXPR_UNARYNODE | 0x05) /* Assembler only */
+#define EXPR_BANK               (EXPR_UNARYNODE | 0x05)
 
 #define EXPR_BYTE0             (EXPR_UNARYNODE | 0x08)
 #define EXPR_BYTE1             (EXPR_UNARYNODE | 0x09)
index 8f026cf2728aace9cab3cccb091c01f1dfb84769..aa3c4a198041fb1b393cada95494dc2edda0cb5a 100644 (file)
@@ -6,7 +6,7 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/* (C) 1998-2012, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
@@ -46,7 +46,7 @@
 
 /* Defines for magic and version */
 #define OBJ_MAGIC      0x616E7A55
-#define OBJ_VERSION    0x0010
+#define OBJ_VERSION    0x0011
 
 /* Size of an object file header */
 #define        OBJ_HDR_SIZE    (24*4)
index d12e6017127907c92ba85d210a44145f7fe02db2..62fb7d557f8cd675196af93dbb971ccd804a57b8 100644 (file)
@@ -46,7 +46,6 @@
 
 /* Segment flags */
 #define SEG_FLAG_NONE           0x00
-#define SEG_FLAG_BANKREF        0x01    /* Segment is referenced by .BANK */
 
 
 
index 54d88e6b8a0e8401e30e58fae97225fc9d166618..bb2691407d339c4ca6b35d00aff0e9e5fd4f95b2 100644 (file)
@@ -1870,19 +1870,6 @@ unsigned CfgProcess (void)
                     Addr = NewAddr;
                 }
 
-                /* If the segment has .BANK expressions referring to it, it
-                 * must be placed into a memory area that has the bank
-                 * attribute.
-                 */
-                if ((S->Seg->Flags & SEG_FLAG_BANKREF) != 0 && M->BankExpr == 0) {
-                    CfgError (GetSourcePos (S->LI),
-                              "Segment `%s' is refered to by .BANK, but the "
-                              "memory area `%s' it is placed into has no BANK "
-                              "attribute",
-                              GetString (S->Name),
-                              GetString (M->Name));
-                }
-
                 /* Set the start address of this segment, set the readonly flag
                  * in the segment and and remember if the segment is in a
                  * relocatable file or not.
index 966c40698d39706b944c7b92d1d196f280b8f9ff..bfcb852ea6c0212f059f5edb183fd70891ed1b8b 100644 (file)
@@ -142,16 +142,6 @@ int IsConstExpr (ExprNode* Root)
                 return !Root->V.Mem->Relocatable &&
                        (Root->V.Mem->Flags & MF_PLACED);
 
-            case EXPR_BANK:
-                /* A bank expression is const if the section, the segment is
-                 * part of, is already placed, and the memory area has a
-                 * constant bank expression.
-                 */
-                S = GetExprSection (Root);
-                M = S->Seg->MemArea;
-                return M != 0 && (M->Flags & MF_PLACED) != 0 &&
-                       M->BankExpr != 0 && IsConstExpr (M->BankExpr);
-
            default:
                 /* Anything else is not const */
                return 0;
@@ -160,7 +150,30 @@ int IsConstExpr (ExprNode* Root)
 
     } else if (EXPR_IS_UNARY (Root->Op)) {
 
-       return IsConstExpr (Root->Left);
+        SegExprDesc D;
+
+        /* Special handling for the BANK pseudo function */
+        switch (Root->Op) {
+
+            case EXPR_BANK:
+                /* Get segment references for the expression */
+                GetSegExprVal (Root->Left, &D);
+
+                /* The expression is const if the expression contains exactly
+                 * one segment that is assigned to a memory area which has a
+                 * bank attribute that is constant.
+                 */
+                return (D.TooComplex              == 0  &&
+                        D.Seg                     != 0  &&
+                        D.Seg->MemArea            != 0  &&
+                        D.Seg->MemArea->BankExpr  != 0  &&
+                        IsConstExpr (D.Seg->MemArea->BankExpr));
+
+            default:
+                /* All others handled normal */
+                return IsConstExpr (Root->Left);
+
+        }
 
     } else {
 
@@ -171,9 +184,9 @@ int IsConstExpr (ExprNode* Root)
                if (IsConstExpr (Root->Left)) {
                    /* lhs is const, if it is zero, don't eval right */
                    if (GetExprVal (Root->Left) == 0) {
-                       return 1;
+                       return 1;
                    } else {
-                       return IsConstExpr (Root->Right);
+                       return IsConstExpr (Root->Right);
                    }
                } else {
                    /* lhs not const --> tree not const */
@@ -240,7 +253,7 @@ Section* GetExprSection (ExprNode* Expr)
 /* Get the segment for a section expression node */
 {
     /* Check that this is really a section node */
-    PRECONDITION (Expr->Op == EXPR_SECTION || Expr->Op == EXPR_BANK);
+    PRECONDITION (Expr->Op == EXPR_SECTION);
 
     /* If we have an object file, get the section from it, otherwise
      * (internally generated expressions), get the section from the
@@ -264,6 +277,7 @@ long GetExprVal (ExprNode* Expr)
     long        Val;
     Section*    S;
     Export*     E;
+    SegExprDesc D;
 
     switch (Expr->Op) {
 
@@ -297,10 +311,6 @@ long GetExprVal (ExprNode* Expr)
         case EXPR_MEMAREA:
             return Expr->V.Mem->Start;
 
-        case EXPR_BANK:
-                   S = GetExprSection (Expr);
-            return GetExprVal (S->Seg->MemArea->BankExpr);
-
                case EXPR_PLUS:
            return GetExprVal (Expr->Left) + GetExprVal (Expr->Right);
 
@@ -314,7 +324,7 @@ long GetExprVal (ExprNode* Expr)
            Left  = GetExprVal (Expr->Left);
            Right = GetExprVal (Expr->Right);
            if (Right == 0) {
-               Error ("Division by zero");
+               Error ("Division by zero");
            }
            return Left / Right;
 
@@ -379,36 +389,53 @@ long GetExprVal (ExprNode* Expr)
             return (Left < Right)? Left : Right;
 
                case EXPR_UNARY_MINUS:
-           return -GetExprVal (Expr->Left);
+           return -GetExprVal (Expr->Left);
 
                case EXPR_NOT:
-           return ~GetExprVal (Expr->Left);
+           return ~GetExprVal (Expr->Left);
 
         case EXPR_SWAP:
-           Left = GetExprVal (Expr->Left);
-           return ((Left >> 8) & 0x00FF) | ((Left << 8) & 0xFF00);
+           Left = GetExprVal (Expr->Left);
+           return ((Left >> 8) & 0x00FF) | ((Left << 8) & 0xFF00);
 
-       case EXPR_BOOLNOT:
+       case EXPR_BOOLNOT:
                    return !GetExprVal (Expr->Left);
 
+        case EXPR_BANK:
+            GetSegExprVal (Expr->Left, &D);
+            if (D.TooComplex || D.Seg == 0) {
+                Error ("Argument for .BANK is not segment relative or too complex");
+            }
+            if (D.Seg->MemArea == 0) {
+                Error ("Segment `%s' is referenced by .BANK but "
+                       "not assigned to a memory area",
+                       GetString (D.Seg->Name));
+            }
+            if (D.Seg->MemArea->BankExpr == 0) {
+                Error ("Memory area `%s' is referenced by .BANK but "
+                       "has no BANK attribute",
+                       GetString (D.Seg->MemArea->Name));
+            }
+            return GetExprVal (D.Seg->MemArea->BankExpr);
+
                case EXPR_BYTE0:
-           return GetExprVal (Expr->Left) & 0xFF;
+           return GetExprVal (Expr->Left) & 0xFF;
 
                case EXPR_BYTE1:
-           return (GetExprVal (Expr->Left) >> 8) & 0xFF;
+           return (GetExprVal (Expr->Left) >> 8) & 0xFF;
 
                case EXPR_BYTE2:
-           return (GetExprVal (Expr->Left) >> 16) & 0xFF;
+           return (GetExprVal (Expr->Left) >> 16) & 0xFF;
 
                case EXPR_BYTE3:
-           return (GetExprVal (Expr->Left) >> 24) & 0xFF;
+           return (GetExprVal (Expr->Left) >> 24) & 0xFF;
 
                case EXPR_WORD0:
-           return GetExprVal (Expr->Left) & 0xFFFF;
+           return GetExprVal (Expr->Left) & 0xFFFF;
 
                case EXPR_WORD1:
-           return (GetExprVal (Expr->Left) >> 16) & 0xFFFF;
-             
+           return (GetExprVal (Expr->Left) >> 16) & 0xFFFF;
+
         case EXPR_FARADDR:
             return GetExprVal (Expr->Left) & 0xFFFFFF;
 
@@ -418,7 +445,7 @@ long GetExprVal (ExprNode* Expr)
         default:
                    Internal ("Unknown expression Op type: %u", Expr->Op);
            /* NOTREACHED */
-           return 0;
+           return 0;
     }
 }
 
@@ -619,7 +646,6 @@ ExprNode* ReadExpr (FILE* F, ObjData* O)
                break;
 
            case EXPR_SECTION:
-            case EXPR_BANK:
                /* Read the section number */
                Expr->V.SecNum = ReadVar (F);
                break;
index 1474ebe5550f4cba2b108598d110c7b226737575..156fd8100a877fac12d44e032d98327f23b8f12f 100644 (file)
@@ -202,7 +202,7 @@ Section* ReadSection (FILE* F, ObjData* O)
     /* Read the segment data */
     (void) Read32 (F);          /* File size of data */
     Name      = MakeGlobalStringId (O, ReadVar (F));    /* Segment name */
-    Flags     = ReadVar (F);    /* Segment flags */
+    Flags     = ReadVar (F);    /* Segment flags (currently unused) */
     Size      = ReadVar (F);    /* Size of data */
     Alignment = ReadVar (F);    /* Alignment */
     Type      = Read8 (F);      /* Segment type */
@@ -216,11 +216,6 @@ Section* ReadSection (FILE* F, ObjData* O)
 
     /* Get the segment for this section */
     S = GetSegment (Name, Type, GetObjFileName (O));
-                                        
-    /* The only possible flag is currently SEG_FLAG_BANKREF, and it must be
-     * applied to the segment, not the section.
-     */
-    S->Flags |= Flags;
 
     /* Allocate the section we will return later */
     Sec = NewSection (S, Alignment, Type);