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:
parent
353b7e66a1
commit
c5ad7d9af1
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user