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
This commit is contained in:
cuz
2003-11-30 21:47:40 +00:00
parent cf7b4e227a
commit 9ebc3d1f01
6 changed files with 109 additions and 144 deletions

View File

@@ -58,7 +58,8 @@ void DoEnum (void)
/* Handle the .ENUM command */ /* Handle the .ENUM command */
{ {
/* Start at zero */ /* Start at zero */
ExprNode* NextExpr = GenLiteralExpr (0); long Offs = 0;
ExprNode* BaseExpr = GenLiteralExpr (0);
/* Check for a name */ /* Check for a name */
int Anon = (Tok != TOK_IDENT); int Anon = (Tok != TOK_IDENT);
@@ -104,25 +105,27 @@ void DoEnum (void)
/* Skip the equal sign */ /* Skip the equal sign */
NextTok (); NextTok ();
/* Delete the old next expression */ /* Read the new expression */
FreeExpr (NextExpr);
/* Read the new one */
EnumExpr = Expression (); EnumExpr = Expression ();
/* Reset the base expression and the offset */
FreeExpr (BaseExpr);
BaseExpr = CloneExpr (EnumExpr);
Offs = 0;
} else { } 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 */ /* Assign the value to the enum member */
SymDef (Sym, EnumExpr, ADDR_SIZE_DEFAULT, SF_NONE); SymDef (Sym, EnumExpr, ADDR_SIZE_DEFAULT, SF_NONE);
/* Increment the offset for the next member */
++Offs;
/* Expect end of line */ /* Expect end of line */
ConsumeSep (); ConsumeSep ();
} }
@@ -136,8 +139,8 @@ void DoEnum (void)
/* End of enum definition */ /* End of enum definition */
Consume (TOK_ENDENUM, "`.ENDENUM' expected"); Consume (TOK_ENDENUM, "`.ENDENUM' expected");
/* Free the last (unused) enum expression */ /* Free the base expression */
FreeExpr (NextExpr); FreeExpr (BaseExpr);
} }

View File

@@ -204,14 +204,9 @@ static ExprNode* Symbol (SymEntry* S)
} else { } else {
/* Mark the symbol as referenced */ /* Mark the symbol as referenced */
SymRef (S); SymRef (S);
/* Remove the symbol if possible */
if (SymHasExpr (S)) {
return CloneExpr (GetSymExpr (S));
} else {
/* Create symbol node */ /* Create symbol node */
return GenSymExpr (S); return GenSymExpr (S);
} }
}
} }
@@ -1117,16 +1112,7 @@ ExprNode* Expression (void)
* a pointer to the root of the tree. * a pointer to the root of the tree.
*/ */
{ {
#if 1 return Expr0 ();
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
} }
@@ -1139,13 +1125,8 @@ long ConstExpression (void)
{ {
long Val; long Val;
#if 1
/* Read the expression */ /* Read the expression */
ExprNode* Expr = Expr0 ();
#else
/* Test code */
ExprNode* Expr = Expression (); ExprNode* Expr = Expression ();
#endif
/* Study the expression */ /* Study the expression */
ExprDesc D; 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 */ /* Try to simplify the given expression tree */
{ {
if (Expr && Expr->Op != EXPR_LITERAL) { if (Expr->Op != EXPR_LITERAL && ED_IsConst (D)) {
/* 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 */ /* No external references */
FreeExpr (Expr); FreeExpr (Expr);
Expr = GenLiteralExpr (D.Val); Expr = GenLiteralExpr (D->Val);
}
/* Free allocated memory */
ED_Done (&D);
} }
return Expr; return Expr;
} }
@@ -1243,10 +1210,19 @@ static ExprNode* GenSectionExpr (unsigned SegNum)
ExprNode* GenAddExpr (ExprNode* Left, ExprNode* Right) ExprNode* GenAddExpr (ExprNode* Left, ExprNode* Right)
/* Generate an addition from the two operands */ /* Generate an addition from the two operands */
{ {
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); ExprNode* Root = NewExprNode (EXPR_PLUS);
Root->Left = Left; Root->Left = Left;
Root->Right = Right; Root->Right = Right;
return Root; return Root;
}
} }

View File

@@ -43,6 +43,16 @@
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
struct ExprDesc;
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
@@ -63,7 +73,7 @@ long ConstExpression (void);
void FreeExpr (ExprNode* Root); void FreeExpr (ExprNode* Root);
/* Free the expression tree, Root is pointing to. */ /* 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 */ /* Try to simplify the given expression tree */
ExprNode* GenLiteralExpr (long Val); ExprNode* GenLiteralExpr (long Val);

View File

@@ -145,21 +145,11 @@ void EmitData (const unsigned char* Data, unsigned Size)
void EmitByte (ExprNode* Expr) void EmitByte (ExprNode* Expr)
/* Emit one byte */ /* 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 */ /* Create a new fragment */
Fragment* F = GenFragment (FRAG_EXPR, 1); Fragment* F = GenFragment (FRAG_EXPR, 1);
/* Set the data */ /* Set the data */
F->V.Expr = Expr; F->V.Expr = Expr;
}
} }
@@ -167,22 +157,11 @@ void EmitByte (ExprNode* Expr)
void EmitWord (ExprNode* Expr) void EmitWord (ExprNode* Expr)
/* Emit one word */ /* 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 */ /* Create a new fragment */
Fragment* F = GenFragment (FRAG_EXPR, 2); Fragment* F = GenFragment (FRAG_EXPR, 2);
/* Set the data */ /* Set the data */
F->V.Expr = Expr; F->V.Expr = Expr;
}
} }
@@ -190,23 +169,11 @@ void EmitWord (ExprNode* Expr)
void EmitFarAddr (ExprNode* Expr) void EmitFarAddr (ExprNode* Expr)
/* Emit a 24 bit expression */ /* 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 */ /* Create a new fragment */
Fragment* F = GenFragment (FRAG_EXPR, 3); Fragment* F = GenFragment (FRAG_EXPR, 3);
/* Set the data */ /* Set the data */
F->V.Expr = Expr; F->V.Expr = Expr;
}
} }
@@ -214,21 +181,11 @@ void EmitFarAddr (ExprNode* Expr)
void EmitDWord (ExprNode* Expr) void EmitDWord (ExprNode* Expr)
/* Emit one dword */ /* 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 */ /* Create a new fragment */
Fragment* F = GenFragment (FRAG_EXPR, 4); Fragment* F = GenFragment (FRAG_EXPR, 4);
/* Set the data */ /* Set the data */
F->V.Expr = Expr; F->V.Expr = Expr;
}
} }

View File

@@ -37,6 +37,7 @@
#include <errno.h> #include <errno.h>
/* common */ /* common */
#include "addrsize.h"
#include "mmodel.h" #include "mmodel.h"
#include "segnames.h" #include "segnames.h"
#include "xmalloc.h" #include "xmalloc.h"
@@ -51,6 +52,7 @@
#include "objfile.h" #include "objfile.h"
#include "segment.h" #include "segment.h"
#include "spool.h" #include "spool.h"
#include "studyexpr.h"
#include "symtab.h" #include "symtab.h"
@@ -291,13 +293,22 @@ void SegCheck (void)
Fragment* F = S->Root; Fragment* F = S->Root;
while (F) { while (F) {
if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) { if (F->Type == FRAG_EXPR || F->Type == FRAG_SEXPR) {
long Val;
if (IsConstExpr (F->V.Expr, &Val)) { /* We have an expression, study it */
/* We are able to evaluate the expression. Check for ExprDesc ED;
* range errors. ED_Init (&ED);
*/ StudyExpr (F->V.Expr, &ED);
unsigned I;
/* 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); int Abs = (F->Type != FRAG_SEXPR);
long Val = ED.Val;
unsigned I;
if (F->Len == 1) { if (F->Len == 1) {
if (Abs) { if (Abs) {
@@ -334,15 +345,22 @@ void SegCheck (void)
Val >>= 8; Val >>= 8;
} }
F->Type = FRAG_LITERAL; F->Type = FRAG_LITERAL;
} else {
} else if (ED.AddrSize != ADDR_SIZE_DEFAULT) {
/* We cannot evaluate the expression now, leave the job for /* We cannot evaluate the expression now, leave the job for
* the linker. However, we are able to check for explicit * the linker. However, we can check if the address size
* byte expressions and we will do so. * 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"); PError (&F->Pos, "Range error");
} }
} }
/* Release memory allocated for the expression decriptor */
ED_Done (&ED);
} }
F = F->Next; F = F->Next;
} }

View File

@@ -441,6 +441,7 @@ static void StudySymbol (ExprNode* Expr, ExprDesc* D)
SymMarkUser (Sym); SymMarkUser (Sym);
StudyExprInternal (GetSymExpr (Sym), D); StudyExprInternal (GetSymExpr (Sym), D);
SymUnmarkUser (Sym); SymUnmarkUser (Sym);
ED_UpdateAddrSize (D, GetSymAddrSize (Sym));
} }
} else { } else {
/* The symbol is either undefined or an import. In both cases, track /* The symbol is either undefined or an import. In both cases, track