mirror of
https://github.com/cc65/cc65.git
synced 2025-01-10 19:29:45 +00:00
Fixed and cleaned up codegen logic with arithmetic conversion in addition and subtraction.
This commit is contained in:
parent
cd116e5ba0
commit
6974c1ff12
@ -2861,17 +2861,18 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
|
|||||||
AddDone = -1;
|
AddDone = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do constant calculation if we can */
|
||||||
if (ED_IsAbs (&Expr2) &&
|
if (ED_IsAbs (&Expr2) &&
|
||||||
(ED_IsAbs (Expr) || lscale == 1)) {
|
(ED_IsAbs (Expr) || lscale == 1)) {
|
||||||
if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
typeadjust (Expr, &Expr2, 1);
|
Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type);
|
||||||
}
|
}
|
||||||
Expr->IVal = Expr->IVal * lscale + Expr2.IVal * rscale;
|
Expr->IVal = Expr->IVal * lscale + Expr2.IVal * rscale;
|
||||||
AddDone = 1;
|
AddDone = 1;
|
||||||
} else if (ED_IsAbs (Expr) &&
|
} else if (ED_IsAbs (Expr) &&
|
||||||
(ED_IsAbs (&Expr2) || rscale == 1)) {
|
(ED_IsAbs (&Expr2) || rscale == 1)) {
|
||||||
if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
typeadjust (&Expr2, Expr, 1);
|
Expr2.Type = ArithmeticConvert (Expr2.Type, Expr->Type);
|
||||||
}
|
}
|
||||||
Expr2.IVal = Expr->IVal * lscale + Expr2.IVal * rscale;
|
Expr2.IVal = Expr->IVal * lscale + Expr2.IVal * rscale;
|
||||||
/* Adjust the flags */
|
/* Adjust the flags */
|
||||||
@ -3053,7 +3054,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
|
|||||||
/* Check for a constant rhs expression */
|
/* Check for a constant rhs expression */
|
||||||
if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
|
if (ED_IsConstAbs (&Expr2) && ED_CodeRangeIsEmpty (&Expr2)) {
|
||||||
|
|
||||||
/* Rhs is a constant. Remove pushed lhs from stack. */
|
/* Rhs is a numeric constant. Remove pushed lhs from stack. */
|
||||||
RemoveCode (&Mark);
|
RemoveCode (&Mark);
|
||||||
|
|
||||||
/* Check for pointer arithmetic */
|
/* Check for pointer arithmetic */
|
||||||
@ -3081,7 +3082,7 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Lhs and rhs are not so constant. Check for pointer arithmetic. */
|
/* Lhs and rhs are not so "numeric constant". Check for pointer arithmetic. */
|
||||||
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
if (IsClassPtr (lhst) && IsClassInt (rhst)) {
|
||||||
/* Left is pointer, right is int, must scale rhs */
|
/* Left is pointer, right is int, must scale rhs */
|
||||||
rscale = CheckedPSizeOf (lhst);
|
rscale = CheckedPSizeOf (lhst);
|
||||||
@ -3116,16 +3117,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
|
|||||||
flags = CF_PTR;
|
flags = CF_PTR;
|
||||||
Expr->Type = Expr2.Type;
|
Expr->Type = Expr2.Type;
|
||||||
} else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) {
|
} else if (!DoArrayRef && IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
/* Integer addition. Note: Result is never constant.
|
/* Integer addition */
|
||||||
** Problem here is that typeadjust does not know if the
|
flags = typeadjust (Expr, &Expr2, 0);
|
||||||
** variable is an rvalue or lvalue, so if both operands
|
|
||||||
** are dereferenced constant numeric addresses, typeadjust
|
|
||||||
** thinks the operation works on constants. Removing
|
|
||||||
** CF_CONST here means handling the symptoms, however, the
|
|
||||||
** whole parser is such a mess that I fear to break anything
|
|
||||||
** when trying to apply another solution.
|
|
||||||
*/
|
|
||||||
flags = typeadjust (Expr, &Expr2, 0) & ~CF_CONST;
|
|
||||||
/* Load rhs into the primary */
|
/* Load rhs into the primary */
|
||||||
LoadExpr (CF_NONE, &Expr2);
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
} else {
|
} else {
|
||||||
@ -3134,8 +3127,8 @@ static void parseadd (ExprDesc* Expr, int DoArrayRef)
|
|||||||
/* We can't just goto End as that would leave the stack unbalanced */
|
/* We can't just goto End as that would leave the stack unbalanced */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Generate code for the add */
|
/* Generate code for the add (the & is a hack here) */
|
||||||
g_add (flags, 0);
|
g_add (flags & ~CF_CONST, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3348,8 +3341,7 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
/* Operate on pointers, result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
flags = CF_PTR;
|
flags = CF_PTR;
|
||||||
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
/* Integer subtraction */
|
/* Integer subtraction. We'll adjust the types later */
|
||||||
flags = typeadjust (Expr, &Expr2, 1);
|
|
||||||
} else {
|
} else {
|
||||||
/* OOPS */
|
/* OOPS */
|
||||||
Error ("Invalid operands for binary operator '-'");
|
Error ("Invalid operands for binary operator '-'");
|
||||||
@ -3370,10 +3362,12 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (SubDone) {
|
if (SubDone) {
|
||||||
/* Remove pushed value from stack */
|
/* Remove loaded and pushed value from stack */
|
||||||
RemoveCode (&Mark1);
|
RemoveCode (&Mark1);
|
||||||
if (IsClassInt (lhst)) {
|
if (IsClassInt (lhst)) {
|
||||||
/* Limit the calculated value to the range of its type */
|
/* Just adjust the result type */
|
||||||
|
Expr->Type = ArithmeticConvert (Expr->Type, Expr2.Type);
|
||||||
|
/* And limit the calculated value to the range of it */
|
||||||
LimitExprValue (Expr);
|
LimitExprValue (Expr);
|
||||||
}
|
}
|
||||||
/* The result is always an rvalue */
|
/* The result is always an rvalue */
|
||||||
@ -3382,10 +3376,18 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
if (ED_IsConstAbs (&Expr2)) {
|
if (ED_IsConstAbs (&Expr2)) {
|
||||||
/* Remove pushed value from stack */
|
/* Remove pushed value from stack */
|
||||||
RemoveCode (&Mark2);
|
RemoveCode (&Mark2);
|
||||||
|
if (IsClassInt (lhst)) {
|
||||||
|
/* Adjust the types */
|
||||||
|
flags = typeadjust (Expr, &Expr2, 1);
|
||||||
|
}
|
||||||
/* Do the subtraction */
|
/* Do the subtraction */
|
||||||
g_dec (flags | CF_CONST, Expr2.IVal);
|
g_dec (flags | CF_CONST, Expr2.IVal);
|
||||||
} else {
|
} else {
|
||||||
/* Load into the primary */
|
if (IsClassInt (lhst)) {
|
||||||
|
/* Adjust the types */
|
||||||
|
flags = typeadjust (Expr, &Expr2, 0);
|
||||||
|
}
|
||||||
|
/* Load rhs into the primary */
|
||||||
LoadExpr (CF_NONE, &Expr2);
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
/* Generate code for the sub (the & is a hack here) */
|
/* Generate code for the sub (the & is a hack here) */
|
||||||
g_sub (flags & ~CF_CONST, 0);
|
g_sub (flags & ~CF_CONST, 0);
|
||||||
@ -3403,8 +3405,7 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
/* Operate on pointers, result type is a pointer */
|
/* Operate on pointers, result type is a pointer */
|
||||||
flags = CF_PTR;
|
flags = CF_PTR;
|
||||||
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
} else if (IsClassInt (lhst) && IsClassInt (rhst)) {
|
||||||
/* Integer subtraction */
|
/* Integer subtraction. We'll adjust the types later */
|
||||||
flags = typeadjust (Expr, &Expr2, 1);
|
|
||||||
} else {
|
} else {
|
||||||
/* OOPS */
|
/* OOPS */
|
||||||
Error ("Invalid operands for binary operator '-'");
|
Error ("Invalid operands for binary operator '-'");
|
||||||
@ -3414,10 +3415,18 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
if (ED_IsConstAbs (&Expr2)) {
|
if (ED_IsConstAbs (&Expr2)) {
|
||||||
/* Remove pushed value from stack */
|
/* Remove pushed value from stack */
|
||||||
RemoveCode (&Mark2);
|
RemoveCode (&Mark2);
|
||||||
|
if (IsClassInt (lhst)) {
|
||||||
|
/* Adjust the types */
|
||||||
|
flags = typeadjust (Expr, &Expr2, 1);
|
||||||
|
}
|
||||||
/* Do the subtraction */
|
/* Do the subtraction */
|
||||||
g_dec (flags | CF_CONST, Expr2.IVal);
|
g_dec (flags | CF_CONST, Expr2.IVal);
|
||||||
} else {
|
} else {
|
||||||
/* Rhs is not numeric, load into the primary */
|
if (IsClassInt (lhst)) {
|
||||||
|
/* Adjust the types */
|
||||||
|
flags = typeadjust (Expr, &Expr2, 0);
|
||||||
|
}
|
||||||
|
/* Load rhs into the primary */
|
||||||
LoadExpr (CF_NONE, &Expr2);
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
/* Generate code for the sub (the & is a hack here) */
|
/* Generate code for the sub (the & is a hack here) */
|
||||||
g_sub (flags & ~CF_CONST, 0);
|
g_sub (flags & ~CF_CONST, 0);
|
||||||
@ -3429,6 +3438,9 @@ static void parsesub (ExprDesc* Expr)
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
/* We'll use the pushed lhs on stack instead of the original source */
|
||||||
|
ED_FinalizeRValLoad (Expr);
|
||||||
|
|
||||||
/* Right hand side is not constant, load into the primary */
|
/* Right hand side is not constant, load into the primary */
|
||||||
LoadExpr (CF_NONE, &Expr2);
|
LoadExpr (CF_NONE, &Expr2);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user