1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-23 04:30:10 +00:00

Replace address mode detection for expressions

git-svn-id: svn://svn.cc65.org/cc65/trunk@2670 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-11-17 12:56:44 +00:00
parent 353b7e66a1
commit c5ad7d9af1

View File

@ -1815,11 +1815,14 @@ int IsConstExpr (ExprNode* Expr, long* Val)
static void CheckByteExpr (const ExprNode* N, int* IsByte) static void CheckAddrSize (const ExprNode* N, unsigned char* AddrSize)
/* Internal routine that is recursively called to check if there is a zeropage /* Internal routine that is recursively called to check for the address size
* symbol in the expression tree. * of the expression tree.
*/ */
{ {
unsigned char A;
unsigned char Left, Right;
if (N) { if (N) {
switch (N->Op & EXPR_TYPEMASK) { switch (N->Op & EXPR_TYPEMASK) {
@ -1827,30 +1830,68 @@ static void CheckByteExpr (const ExprNode* N, int* IsByte)
switch (N->Op) { switch (N->Op) {
case EXPR_SYMBOL: case EXPR_SYMBOL:
if (SymIsZP (N->V.Sym)) { if (SymIsZP (N->V.Sym)) {
*IsByte = 1; if (*AddrSize < ADDR_SIZE_ZP) {
*AddrSize = ADDR_SIZE_ZP;
}
} else if (SymHasExpr (N->V.Sym)) { } else if (SymHasExpr (N->V.Sym)) {
/* Check if this expression is a byte expression */ /* Check if this expression is a byte expression */
CheckByteExpr (GetSymExpr (N->V.Sym), IsByte); CheckAddrSize (GetSymExpr (N->V.Sym), AddrSize);
} } else {
break; /* Undefined symbol, use absolute */
if (*AddrSize < ADDR_SIZE_ABS) {
*AddrSize = ADDR_SIZE_ABS;
}
}
break;
case EXPR_SECTION: case EXPR_SECTION:
if (GetSegAddrSize (N->V.SegNum) == ADDR_SIZE_ZP) { A = GetSegAddrSize (N->V.SegNum);
*IsByte = 1; if (A > *AddrSize) {
} *AddrSize = A;
}
break; break;
} }
break; break;
case EXPR_UNARYNODE: case EXPR_UNARYNODE:
CheckByteExpr (N->Left, IsByte); switch (N->Op) {
break;
case EXPR_BYTE0:
case EXPR_BYTE1:
case EXPR_BYTE2:
case EXPR_BYTE3:
/* No need to look at the expression */
*AddrSize = ADDR_SIZE_ZP;
break;
case EXPR_WORD0:
case EXPR_WORD1:
case EXPR_FORCEWORD:
/* No need to look at the expression */
*AddrSize = ADDR_SIZE_ABS;
break;
case EXPR_FORCEFAR:
/* No need to look at the expression */
*AddrSize = ADDR_SIZE_FAR;
break;
default:
CheckAddrSize (N->Left, AddrSize);
break;
}
break;
case EXPR_BINARYNODE: case EXPR_BINARYNODE:
CheckByteExpr (N->Left, IsByte); Left = Right = ADDR_SIZE_DEFAULT;
CheckByteExpr (N->Right, IsByte); CheckAddrSize (N->Left, &Left);
CheckAddrSize (N->Right, &Right);
A = (Left > Right)? Left : Right;
if (A > *AddrSize) {
*AddrSize = A;
}
break; break;
default: default:
@ -1864,26 +1905,15 @@ static void CheckByteExpr (const ExprNode* N, int* IsByte)
int IsByteExpr (ExprNode* Root) int IsByteExpr (ExprNode* Root)
/* Return true if this is a byte expression */ /* Return true if this is a byte expression */
{ {
int IsByte;
long Val; long Val;
if (IsConstExpr (Root, &Val)) { if (IsConstExpr (Root, &Val)) {
IsByte = IsByteRange (Val); return IsByteRange (Val);
} else if (Root->Op == EXPR_BYTE0 || Root->Op == EXPR_BYTE1 ||
Root->Op == EXPR_BYTE2 || Root->Op == EXPR_BYTE3) {
/* Symbol forced to have byte range */
IsByte = 1;
} else { } else {
/* We have undefined symbols in the expression. Assume that the unsigned char AddrSize = ADDR_SIZE_DEFAULT;
* expression is a byte expression if there is at least one symbol CheckAddrSize (Root, &AddrSize);
* declared as zeropage in it. Being wrong here is not a very big return (AddrSize == ADDR_SIZE_ZP);
* problem since the linker knows about all symbols and detects
* error like mixing absolute and zeropage labels.
*/
IsByte = 0;
CheckByteExpr (Root, &IsByte);
} }
return IsByte;
} }