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 <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:
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