diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index 3d7b7c384..5924ab6cf 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -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); } diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index f1f121cc4..2ef8b617f 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -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