1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 20:29:34 +00:00

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 */
{
/* 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);
}

View 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;
}
}

View File

@ -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);

View 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;
}

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

View 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