/* 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 */
 
 
 
-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 */
 {
             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);
 
  * 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 */
 
 
 
                } else {
 
-                    /* Finalize the expression */
-                    F->V.Expr = FinalizeExpr (F->V.Expr, &F->LI);
-
                     /* Simplify the expression */
                     /* ### F->V.Expr = SimplifyExpr (F->V.Expr, &ED); */
 
 
 
 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);
             StudyULabel (Expr, D);
             break;
 
-        case EXPR_BANK:
-            StudyBank (Expr, D);
-            break;
-
        case EXPR_PLUS:
             StudyPlus (Expr, D);
            break;
             StudyBoolNot (Expr, D);
             break;
 
-        case EXPR_BANKRAW:
-            StudyBankRaw (Expr, D);
+        case EXPR_BANK:
+            StudyBank (Expr, D);
             break;
 
         case EXPR_BYTE0:
 
 #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)
 #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)
 
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998-2011, Ullrich von Bassewitz                                      */
+/* (C) 1998-2012, Ullrich von Bassewitz                                      */
 /*                Roemerstrasse 52                                           */
 /*                D-70794 Filderstadt                                        */
 /* EMail:         uz@cc65.org                                                */
 
 /* 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)
 
 
 /* Segment flags */
 #define SEG_FLAG_NONE           0x00
-#define SEG_FLAG_BANKREF        0x01    /* Segment is referenced by .BANK */
 
 
 
 
                     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.
 
                 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;
 
     } 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 {
 
                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 */
 /* 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
     long        Val;
     Section*    S;
     Export*     E;
+    SegExprDesc D;
 
     switch (Expr->Op) {
 
         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);
 
            Left  = GetExprVal (Expr->Left);
            Right = GetExprVal (Expr->Right);
            if (Right == 0) {
-               Error ("Division by zero");
+               Error ("Division by zero");
            }
            return Left / Right;
 
             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;
 
         default:
                    Internal ("Unknown expression Op type: %u", Expr->Op);
            /* NOTREACHED */
-           return 0;
+           return 0;
     }
 }
 
                break;
 
            case EXPR_SECTION:
-            case EXPR_BANK:
                /* Read the section number */
                Expr->V.SecNum = ReadVar (F);
                break;
 
     /* 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 */
 
     /* 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);