mirror of
https://github.com/cc65/cc65.git
synced 2024-12-26 08:32:00 +00:00
Organized ExprDesc functions and fixed several comments.
This commit is contained in:
parent
ad7c5a6617
commit
b81e54c1d2
@ -67,75 +67,9 @@ ExprDesc* ED_Init (ExprDesc* Expr)
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsLocQuasiConst (const ExprDesc* Expr)
|
||||
/* Return true if the expression is a constant location of some sort or on the
|
||||
** stack.
|
||||
*/
|
||||
{
|
||||
return ED_IsLocConst (Expr) || ED_IsLocStack (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr)
|
||||
/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */
|
||||
{
|
||||
return ED_IsLocPrimary (Expr) || ED_IsLocExpr (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsIndExpr (const ExprDesc* Expr)
|
||||
/* Check if the expression is a reference to its value */
|
||||
{
|
||||
return (Expr->Flags & E_ADDRESS_OF) == 0 &&
|
||||
!ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int ED_YetToLoad (const ExprDesc* Expr)
|
||||
/* Check if the expression needs to be loaded somehow. */
|
||||
{
|
||||
return ED_NeedsPrimary (Expr) ||
|
||||
ED_YetToTest (Expr) ||
|
||||
(ED_IsLVal (Expr) && IsQualVolatile (Expr->Type));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ED_MarkForUneval (ExprDesc* Expr)
|
||||
/* Mark the expression as not to be evaluated */
|
||||
{
|
||||
Expr->Flags = (Expr->Flags & ~E_MASK_EVAL) | E_EVAL_UNEVAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End)
|
||||
/* Set the code range for this expression */
|
||||
{
|
||||
Expr->Flags |= E_HAVE_MARKS;
|
||||
Expr->Start = *Start;
|
||||
Expr->End = *End;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_CodeRangeIsEmpty (const ExprDesc* Expr)
|
||||
/* Return true if no code was output for this expression */
|
||||
{
|
||||
/* We must have code marks */
|
||||
PRECONDITION (Expr->Flags & E_HAVE_MARKS);
|
||||
|
||||
return CodeRangeIsEmpty (&Expr->Start, &Expr->End);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/* Info Extraction */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@ -215,6 +149,190 @@ int ED_GetStackOffs (const ExprDesc* Expr, int Offs)
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Predicates */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsLocQuasiConst (const ExprDesc* Expr)
|
||||
/* Return true if the expression is a constant location of some sort or on the
|
||||
** stack.
|
||||
*/
|
||||
{
|
||||
return ED_IsLocConst (Expr) || ED_IsLocStack (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr)
|
||||
/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */
|
||||
{
|
||||
return ED_IsLocPrimary (Expr) || ED_IsLocExpr (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsIndExpr (const ExprDesc* Expr)
|
||||
/* Check if the expression is a reference to its value */
|
||||
{
|
||||
return (Expr->Flags & E_ADDRESS_OF) == 0 &&
|
||||
!ED_IsLocNone (Expr) && !ED_IsLocPrimary (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int ED_YetToLoad (const ExprDesc* Expr)
|
||||
/* Check if the expression needs to be loaded somehow. */
|
||||
{
|
||||
return ED_NeedsPrimary (Expr) ||
|
||||
ED_YetToTest (Expr) ||
|
||||
(ED_IsLVal (Expr) && IsQualVolatile (Expr->Type));
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsAbs (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a numeric value or address. */
|
||||
{
|
||||
return (Expr->Flags & (E_MASK_LOC)) == (E_LOC_NONE) ||
|
||||
(Expr->Flags & (E_MASK_LOC|E_ADDRESS_OF)) == (E_LOC_ABS|E_ADDRESS_OF);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsConstAbs (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a constant absolute value. This can be
|
||||
** a numeric constant, cast to any type.
|
||||
*/
|
||||
{
|
||||
return ED_IsRVal (Expr) && ED_IsAbs (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int ED_IsConstAbsInt (const ExprDesc* Expr)
|
||||
/* Return true if the expression is a constant (numeric) integer. */
|
||||
{
|
||||
return ED_IsConstAbs (Expr) && IsClassInt (Expr->Type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConstBool (const ExprDesc* Expr)
|
||||
/* Return true if the expression can be constantly evaluated as a boolean. */
|
||||
{
|
||||
return ED_IsConstAbsInt (Expr) || ED_IsAddrExpr (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConstTrue (const ExprDesc* Expr)
|
||||
/* Return true if the constant expression can be evaluated as boolean true at
|
||||
** compile time.
|
||||
*/
|
||||
{
|
||||
/* Non-zero arithmetics and objects addresses are boolean true */
|
||||
return (ED_IsConstAbsInt (Expr) && Expr->IVal != 0) ||
|
||||
(ED_IsAddrExpr (Expr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConstFalse (const ExprDesc* Expr)
|
||||
/* Return true if the constant expression can be evaluated as boolean false at
|
||||
** compile time.
|
||||
*/
|
||||
{
|
||||
/* Zero arithmetics and null pointers are boolean false */
|
||||
return (ED_IsConstAbsInt (Expr) && Expr->IVal == 0) ||
|
||||
ED_IsNullPtr (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConst (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a constant of some sort. This can be a
|
||||
** numeric constant, the address of a global variable (maybe with offset) or
|
||||
** similar.
|
||||
*/
|
||||
{
|
||||
return (Expr->Flags & E_MASK_LOC) == E_LOC_NONE || ED_IsConstAddr (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsQuasiConst (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a quasi-constant of some sort. This
|
||||
** can be a numeric constant, a constant address or a stack variable address.
|
||||
*/
|
||||
{
|
||||
return (Expr->Flags & E_MASK_LOC) == E_LOC_NONE || ED_IsQuasiConstAddr (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConstAddr (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a constant address of some sort. This
|
||||
** can be the address of a global variable (maybe with offset) or similar.
|
||||
*/
|
||||
{
|
||||
return ED_IsAddrExpr (Expr) && ED_IsLocConst (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsQuasiConstAddr (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a quasi-constant address of some sort.
|
||||
** This can be a constant address or a stack variable address.
|
||||
*/
|
||||
{
|
||||
return ED_IsAddrExpr (Expr) && ED_IsLocQuasiConst (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsNullPtr (const ExprDesc* Expr)
|
||||
/* Return true if the given expression is a NULL pointer constant */
|
||||
{
|
||||
return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) ==
|
||||
(E_LOC_NONE|E_RTYPE_RVAL) &&
|
||||
Expr->IVal == 0 &&
|
||||
IsClassInt (Expr->Type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsBool (const ExprDesc* Expr)
|
||||
/* Return true if the expression can be treated as a boolean, that is, it can
|
||||
** be an operand to a compare operation.
|
||||
*/
|
||||
{
|
||||
/* Either ints, floats, or pointers can be used in a boolean context */
|
||||
return IsClassInt (Expr->Type) ||
|
||||
IsClassFloat (Expr->Type) ||
|
||||
IsClassPtr (Expr->Type) ||
|
||||
IsClassFunc (Expr->Type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Manipulation */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type)
|
||||
/* Replace Expr with an absolute const with the given value and type */
|
||||
{
|
||||
@ -331,7 +449,7 @@ ExprDesc* ED_IndExpr (ExprDesc* Expr)
|
||||
** original address. We simply mark this as E_LOC_EXPR so that
|
||||
** some info about the original location can be retained.
|
||||
** If it's really meant to dereference a "pointer value", it
|
||||
** should be done in two steps where the pointervalue should
|
||||
** should be done in two steps where the pointer value should
|
||||
** be the manually loaded first before a call into this, and
|
||||
** the offset should be manually cleared somewhere outside.
|
||||
*/
|
||||
@ -345,131 +463,27 @@ ExprDesc* ED_IndExpr (ExprDesc* Expr)
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsAbs (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a numeric value or address. */
|
||||
void ED_MarkForUneval (ExprDesc* Expr)
|
||||
/* Mark the expression as not to be evaluated */
|
||||
{
|
||||
return (Expr->Flags & (E_MASK_LOC)) == (E_LOC_NONE) ||
|
||||
(Expr->Flags & (E_MASK_LOC|E_ADDRESS_OF)) == (E_LOC_ABS|E_ADDRESS_OF);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if !defined(HAVE_INLINE)
|
||||
int ED_IsConstAbs (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a constant absolute value. This can be
|
||||
** a numeric constant, cast to any type.
|
||||
*/
|
||||
{
|
||||
return ED_IsRVal (Expr) && ED_IsAbs (Expr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int ED_IsConstAbsInt (const ExprDesc* Expr)
|
||||
/* Return true if the expression is a constant (numeric) integer. */
|
||||
{
|
||||
return ED_IsConstAbs (Expr) && IsClassInt (Expr->Type);
|
||||
Expr->Flags = (Expr->Flags & ~E_MASK_EVAL) | E_EVAL_UNEVAL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConstBool (const ExprDesc* Expr)
|
||||
/* Return true if the expression can be constantly evaluated as a boolean. */
|
||||
const Type* ReplaceType (ExprDesc* Expr, const Type* NewType)
|
||||
/* Replace the type of Expr by a copy of Newtype and return the old type string */
|
||||
{
|
||||
return ED_IsConstAbsInt (Expr) || ED_IsAddrExpr (Expr);
|
||||
const Type* OldType = Expr->Type;
|
||||
Expr->Type = TypeDup (NewType);
|
||||
return OldType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConstTrue (const ExprDesc* Expr)
|
||||
/* Return true if the constant expression can be evaluated as boolean true at
|
||||
** compile time.
|
||||
*/
|
||||
{
|
||||
/* Non-zero arithmetics and objects addresses are boolean true */
|
||||
return (ED_IsConstAbsInt (Expr) && Expr->IVal != 0) ||
|
||||
(ED_IsAddrExpr (Expr));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConstFalse (const ExprDesc* Expr)
|
||||
/* Return true if the constant expression can be evaluated as boolean false at
|
||||
** compile time.
|
||||
*/
|
||||
{
|
||||
/* Zero arithmetics and null pointers are boolean false */
|
||||
return (ED_IsConstAbsInt (Expr) && Expr->IVal == 0) ||
|
||||
ED_IsNullPtr (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsConst (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a constant of some sort. This can be a
|
||||
** numeric constant, the address of a global variable (maybe with offset) or
|
||||
** similar.
|
||||
*/
|
||||
{
|
||||
return (Expr->Flags & E_MASK_LOC) == E_LOC_NONE || ED_IsConstAddr (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsQuasiConst (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a quasi-constant of some sort. This
|
||||
** can be a numeric constant, a constant address or a stack variable address.
|
||||
*/
|
||||
{
|
||||
return (Expr->Flags & E_MASK_LOC) == E_LOC_NONE || ED_IsQuasiConstAddr (Expr);
|
||||
}
|
||||
|
||||
|
||||
int ED_IsConstAddr (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a constant address of some sort. This
|
||||
** can be the address of a global variable (maybe with offset) or similar.
|
||||
*/
|
||||
{
|
||||
return ED_IsAddrExpr (Expr) && ED_IsLocConst (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsQuasiConstAddr (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a quasi-constant address of some sort.
|
||||
** This can be a constant address or a stack variable address.
|
||||
*/
|
||||
{
|
||||
return ED_IsAddrExpr (Expr) && ED_IsLocQuasiConst (Expr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsNullPtr (const ExprDesc* Expr)
|
||||
/* Return true if the given expression is a NULL pointer constant */
|
||||
{
|
||||
return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) ==
|
||||
(E_LOC_NONE|E_RTYPE_RVAL) &&
|
||||
Expr->IVal == 0 &&
|
||||
IsClassInt (Expr->Type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_IsBool (const ExprDesc* Expr)
|
||||
/* Return true if the expression can be treated as a boolean, that is, it can
|
||||
** be an operand to a compare operation.
|
||||
*/
|
||||
{
|
||||
/* Either ints, floats, or pointers can be used in a boolean context */
|
||||
return IsClassInt (Expr->Type) ||
|
||||
IsClassFloat (Expr->Type) ||
|
||||
IsClassPtr (Expr->Type) ||
|
||||
IsClassFunc (Expr->Type);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/* Other Helpers */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
@ -577,10 +591,21 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
|
||||
|
||||
|
||||
|
||||
const Type* ReplaceType (ExprDesc* Expr, const Type* NewType)
|
||||
/* Replace the type of Expr by a copy of Newtype and return the old type string */
|
||||
void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End)
|
||||
/* Set the code range for this expression */
|
||||
{
|
||||
const Type* OldType = Expr->Type;
|
||||
Expr->Type = TypeDup (NewType);
|
||||
return OldType;
|
||||
Expr->Flags |= E_HAVE_MARKS;
|
||||
Expr->Start = *Start;
|
||||
Expr->End = *End;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ED_CodeRangeIsEmpty (const ExprDesc* Expr)
|
||||
/* Return true if no code was output for this expression */
|
||||
{
|
||||
/* We must have code marks */
|
||||
PRECONDITION (Expr->Flags & E_HAVE_MARKS);
|
||||
|
||||
return CodeRangeIsEmpty (&Expr->Start, &Expr->End);
|
||||
}
|
||||
|
@ -227,6 +227,14 @@ struct ExprDesc {
|
||||
ExprDesc* ED_Init (ExprDesc* Expr);
|
||||
/* Initialize an ExprDesc */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Info Extraction */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_GetLoc (const ExprDesc* Expr)
|
||||
/* Return the location flags from the expression */
|
||||
@ -237,6 +245,35 @@ INLINE int ED_GetLoc (const ExprDesc* Expr)
|
||||
# define ED_GetLoc(Expr) ((Expr)->Flags & E_MASK_LOC)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_GetNeeds (const ExprDesc* Expr)
|
||||
/* Get flags about what the expression needs. */
|
||||
{
|
||||
return (Expr->Flags & E_MASK_NEED);
|
||||
}
|
||||
#else
|
||||
# define ED_GetNeeds(Expr) ((Expr)->Flags & E_MASK_NEED)
|
||||
#endif
|
||||
|
||||
const char* ED_GetLabelName (const ExprDesc* Expr, long Offs);
|
||||
/* Return the assembler label name of the given expression. Beware: This
|
||||
** function may use a static buffer, so the name may get "lost" on the second
|
||||
** call to the function.
|
||||
*/
|
||||
|
||||
int ED_GetStackOffs (const ExprDesc* Expr, int Offs);
|
||||
/* Get the stack offset of an address on the stack in Expr taking into account
|
||||
** an additional offset in Offs.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Predicates */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsLocNone (const ExprDesc* Expr)
|
||||
/* Return true if the expression is an absolute value */
|
||||
@ -279,7 +316,7 @@ INLINE int ED_IsLocStack (const ExprDesc* Expr)
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsLocPrimary (const ExprDesc* Expr)
|
||||
/* Return true if the expression is an expression in the register pseudo variable */
|
||||
/* Return true if the expression is an expression in the primary */
|
||||
{
|
||||
return (Expr->Flags & E_MASK_LOC) == E_LOC_PRIMARY;
|
||||
}
|
||||
@ -289,7 +326,7 @@ INLINE int ED_IsLocPrimary (const ExprDesc* Expr)
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsLocExpr (const ExprDesc* Expr)
|
||||
/* Return true if the expression is an expression in the primary */
|
||||
/* Return true if the expression is an expression referenced in the primary */
|
||||
{
|
||||
return (Expr->Flags & E_MASK_LOC) == E_LOC_EXPR;
|
||||
}
|
||||
@ -333,33 +370,14 @@ int ED_IsLocQuasiConst (const ExprDesc* Expr);
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_RequireTest (ExprDesc* Expr)
|
||||
/* Mark the expression for a test. */
|
||||
INLINE int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr)
|
||||
/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */
|
||||
{
|
||||
Expr->Flags |= E_NEED_TEST;
|
||||
return ED_IsLocPrimary (Expr) || ED_IsLocExpr (Expr);
|
||||
}
|
||||
#else
|
||||
# define ED_RequireTest(Expr) do { (Expr)->Flags |= E_NEED_TEST; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_RequireNoTest (ExprDesc* Expr)
|
||||
/* Mark the expression not for a test. */
|
||||
{
|
||||
Expr->Flags &= ~E_NEED_TEST;
|
||||
}
|
||||
#else
|
||||
# define ED_RequireNoTest(Expr) do { (Expr)->Flags &= ~E_NEED_TEST; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_GetNeeds (const ExprDesc* Expr)
|
||||
/* Get flags about what the expression needs. */
|
||||
{
|
||||
return (Expr->Flags & E_MASK_NEED);
|
||||
}
|
||||
#else
|
||||
# define ED_GetNeeds(Expr) ((Expr)->Flags & E_MASK_NEED)
|
||||
int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr);
|
||||
/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
@ -382,27 +400,6 @@ INLINE int ED_NeedsTest (const ExprDesc* Expr)
|
||||
# define ED_NeedsTest(Expr) (((Expr)->Flags & E_NEED_TEST) != 0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_YetToTest (const ExprDesc* Expr)
|
||||
/* Check if the expression needs to be tested but not yet. */
|
||||
{
|
||||
return ((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST;
|
||||
}
|
||||
#else
|
||||
# define ED_YetToTest(Expr) (((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_TestDone (ExprDesc* Expr)
|
||||
/* Mark the expression as tested and condition codes set. */
|
||||
{
|
||||
Expr->Flags |= E_CC_SET;
|
||||
}
|
||||
#else
|
||||
# define ED_TestDone(Expr) \
|
||||
do { (Expr)->Flags |= E_CC_SET; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsTested (const ExprDesc* Expr)
|
||||
/* Check if the expression has set the condition codes. */
|
||||
@ -414,13 +411,13 @@ INLINE int ED_IsTested (const ExprDesc* Expr)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_MarkAsUntested (ExprDesc* Expr)
|
||||
/* Mark the expression as not tested (condition codes not set). */
|
||||
INLINE int ED_YetToTest (const ExprDesc* Expr)
|
||||
/* Check if the expression needs to be tested but not yet. */
|
||||
{
|
||||
Expr->Flags &= ~E_CC_SET;
|
||||
return ((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST;
|
||||
}
|
||||
#else
|
||||
# define ED_MarkAsUntested(Expr) do { (Expr)->Flags &= ~E_CC_SET; } while (0)
|
||||
# define ED_YetToTest(Expr) (((Expr)->Flags & (E_NEED_TEST | E_CC_SET)) == E_NEED_TEST)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
@ -448,9 +445,6 @@ INLINE int ED_NeedsConst (const ExprDesc* Expr)
|
||||
# define ED_NeedsConst(Expr) (((Expr)->Flags & E_EVAL_IMMUTABLE_RESULT) == E_EVAL_IMMUTABLE_RESULT)
|
||||
#endif
|
||||
|
||||
void ED_MarkForUneval (ExprDesc* Expr);
|
||||
/* Mark the expression as not to be evaluated */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsUneval (const ExprDesc* Expr)
|
||||
/* Check if the expression is not to be evaluated */
|
||||
@ -471,27 +465,6 @@ INLINE int ED_MayHaveNoEffect (const ExprDesc* Expr)
|
||||
# define ED_MayHaveNoEffect(Expr) (((Expr)->Flags & E_EVAL_MAYBE_UNUSED) == E_EVAL_MAYBE_UNUSED)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_PropagateFrom (ExprDesc* Expr, const ExprDesc* SubExpr)
|
||||
/* Propagate viral flags from subexpression */
|
||||
{
|
||||
Expr->Flags |= SubExpr->Flags & E_MASK_VIRAL;
|
||||
}
|
||||
#else
|
||||
# define ED_PropagateFrom(Expr, SubExpr) (void)((Expr)->Flags |= (SubExpr)->Flags & E_MASK_VIRAL)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr)
|
||||
/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */
|
||||
{
|
||||
return ED_IsLocPrimary (Expr) || ED_IsLocExpr (Expr);
|
||||
}
|
||||
#else
|
||||
int ED_IsLocPrimaryOrExpr (const ExprDesc* Expr);
|
||||
/* Return true if the expression is E_LOC_PRIMARY or E_LOC_EXPR */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsAddrExpr (const ExprDesc* Expr)
|
||||
/* Check if the expression is taken address of instead of its value.
|
||||
@ -515,35 +488,6 @@ int ED_IsIndExpr (const ExprDesc* Expr);
|
||||
/* Check if the expression is a reference to its value */
|
||||
#endif
|
||||
|
||||
void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End);
|
||||
/* Set the code range for this expression */
|
||||
|
||||
int ED_CodeRangeIsEmpty (const ExprDesc* Expr);
|
||||
/* Return true if no code was output for this expression */
|
||||
|
||||
const char* ED_GetLabelName (const ExprDesc* Expr, long Offs);
|
||||
/* Return the assembler label name of the given expression. Beware: This
|
||||
** function may use a static buffer, so the name may get "lost" on the second
|
||||
** call to the function.
|
||||
*/
|
||||
|
||||
int ED_GetStackOffs (const ExprDesc* Expr, int Offs);
|
||||
/* Get the stack offset of an address on the stack in Expr taking into account
|
||||
** an additional offset in Offs.
|
||||
*/
|
||||
|
||||
ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type);
|
||||
/* Replace Expr with an absolute const with the given value and type */
|
||||
|
||||
ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value);
|
||||
/* Replace Expr with an constant integer with the given value */
|
||||
|
||||
ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value);
|
||||
/* Replace Expr with a constant boolean expression with the given value */
|
||||
|
||||
ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr);
|
||||
/* Finalize the result of LoadExpr to be an rvalue in the primary register */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsLVal (const ExprDesc* Expr)
|
||||
/* Return true if the expression is a reference */
|
||||
@ -564,40 +508,6 @@ INLINE int ED_IsRVal (const ExprDesc* Expr)
|
||||
# define ED_IsRVal(Expr) (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_MarkExprAsLVal (ExprDesc* Expr)
|
||||
/* Mark the expression as an lvalue.
|
||||
** HINT: Consider using ED_IndExpr instead of this, unless you know what
|
||||
** consequence there will be, as there are both a big part in the code
|
||||
** assuming rvalue = const and a big part assuming rvalue = address.
|
||||
*/
|
||||
{
|
||||
Expr->Flags |= E_RTYPE_LVAL;
|
||||
}
|
||||
#else
|
||||
# define ED_MarkExprAsLVal(Expr) do { (Expr)->Flags |= E_RTYPE_LVAL; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_MarkExprAsRVal (ExprDesc* Expr)
|
||||
/* Mark the expression as an rvalue.
|
||||
** HINT: Consider using ED_AddrExpr instead of this, unless you know what
|
||||
** consequence there will be, as there are both a big part in the code
|
||||
** assuming rvalue = const and a big part assuming rvalue = address.
|
||||
*/
|
||||
{
|
||||
Expr->Flags &= ~E_RTYPE_LVAL;
|
||||
}
|
||||
#else
|
||||
# define ED_MarkExprAsRVal(Expr) do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0)
|
||||
#endif
|
||||
|
||||
ExprDesc* ED_AddrExpr (ExprDesc* Expr);
|
||||
/* Take address of Expr */
|
||||
|
||||
ExprDesc* ED_IndExpr (ExprDesc* Expr);
|
||||
/* Dereference Expr */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE int ED_IsAbs (const ExprDesc* Expr)
|
||||
/* Return true if the expression denotes a numeric value or address. */
|
||||
@ -670,14 +580,136 @@ int ED_IsBool (const ExprDesc* Expr);
|
||||
** be an operand to a compare operation with 0/NULL.
|
||||
*/
|
||||
|
||||
void PrintExprDesc (FILE* F, ExprDesc* Expr);
|
||||
/* Print an ExprDesc */
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Manipulation */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, const Type* Type);
|
||||
/* Replace Expr with an absolute const with the given value and type */
|
||||
|
||||
ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value);
|
||||
/* Replace Expr with an constant integer with the given value */
|
||||
|
||||
ExprDesc* ED_MakeConstBool (ExprDesc* Expr, long Value);
|
||||
/* Replace Expr with a constant boolean expression with the given value */
|
||||
|
||||
ExprDesc* ED_FinalizeRValLoad (ExprDesc* Expr);
|
||||
/* Finalize the result of LoadExpr to be an rvalue in the primary register */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_MarkExprAsLVal (ExprDesc* Expr)
|
||||
/* Mark the expression as an lvalue.
|
||||
** HINT: Consider using ED_IndExpr instead of this, unless you know what
|
||||
** consequence there will be, as there are both a big part in the code
|
||||
** assuming rvalue = const and a big part assuming rvalue = address.
|
||||
*/
|
||||
{
|
||||
Expr->Flags |= E_RTYPE_LVAL;
|
||||
}
|
||||
#else
|
||||
# define ED_MarkExprAsLVal(Expr) do { (Expr)->Flags |= E_RTYPE_LVAL; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_MarkExprAsRVal (ExprDesc* Expr)
|
||||
/* Mark the expression as an rvalue.
|
||||
** HINT: Consider using ED_AddrExpr instead of this, unless you know what
|
||||
** consequence there will be, as there are both a big part in the code
|
||||
** assuming rvalue = const and a big part assuming rvalue = address.
|
||||
*/
|
||||
{
|
||||
Expr->Flags &= ~E_RTYPE_LVAL;
|
||||
}
|
||||
#else
|
||||
# define ED_MarkExprAsRVal(Expr) do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0)
|
||||
#endif
|
||||
|
||||
ExprDesc* ED_AddrExpr (ExprDesc* Expr);
|
||||
/* Take address of Expr */
|
||||
|
||||
ExprDesc* ED_IndExpr (ExprDesc* Expr);
|
||||
/* Dereference Expr */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_RequireTest (ExprDesc* Expr)
|
||||
/* Mark the expression for a test. */
|
||||
{
|
||||
Expr->Flags |= E_NEED_TEST;
|
||||
}
|
||||
#else
|
||||
# define ED_RequireTest(Expr) do { (Expr)->Flags |= E_NEED_TEST; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_RequireNoTest (ExprDesc* Expr)
|
||||
/* Mark the expression not for a test. */
|
||||
{
|
||||
Expr->Flags &= ~E_NEED_TEST;
|
||||
}
|
||||
#else
|
||||
# define ED_RequireNoTest(Expr) do { (Expr)->Flags &= ~E_NEED_TEST; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_TestDone (ExprDesc* Expr)
|
||||
/* Mark the expression as tested and condition codes set. */
|
||||
{
|
||||
Expr->Flags |= E_CC_SET;
|
||||
}
|
||||
#else
|
||||
# define ED_TestDone(Expr) \
|
||||
do { (Expr)->Flags |= E_CC_SET; } while (0)
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_MarkAsUntested (ExprDesc* Expr)
|
||||
/* Mark the expression as not tested (condition codes not set). */
|
||||
{
|
||||
Expr->Flags &= ~E_CC_SET;
|
||||
}
|
||||
#else
|
||||
# define ED_MarkAsUntested(Expr) do { (Expr)->Flags &= ~E_CC_SET; } while (0)
|
||||
#endif
|
||||
|
||||
void ED_MarkForUneval (ExprDesc* Expr);
|
||||
/* Mark the expression as not to be evaluated */
|
||||
|
||||
#if defined(HAVE_INLINE)
|
||||
INLINE void ED_PropagateFrom (ExprDesc* Expr, const ExprDesc* SubExpr)
|
||||
/* Propagate viral flags from subexpression */
|
||||
{
|
||||
Expr->Flags |= SubExpr->Flags & E_MASK_VIRAL;
|
||||
}
|
||||
#else
|
||||
# define ED_PropagateFrom(Expr, SubExpr) (void)((Expr)->Flags |= (SubExpr)->Flags & E_MASK_VIRAL)
|
||||
#endif
|
||||
|
||||
const Type* ReplaceType (ExprDesc* Expr, const Type* NewType);
|
||||
/* Replace the type of Expr by a copy of Newtype and return the old type string */
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Other Helpers */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void PrintExprDesc (FILE* F, ExprDesc* Expr);
|
||||
/* Print an ExprDesc */
|
||||
|
||||
void ED_SetCodeRange (ExprDesc* Expr, const CodeMark* Start, const CodeMark* End);
|
||||
/* Set the code range for this expression */
|
||||
|
||||
int ED_CodeRangeIsEmpty (const ExprDesc* Expr);
|
||||
/* Return true if no code was output for this expression */
|
||||
|
||||
|
||||
|
||||
/* End of exprdesc.h */
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user