]> git.sur5r.net Git - cc65/blobdiff - src/cc65/exprdesc.h
Merge pull request #205 from greg-king5/typo
[cc65] / src / cc65 / exprdesc.h
index 039a46ff81e99558a91038faec4bf466165b6f69..99a17313e169dfd44ae19358f54cbcb5200596e1 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2002      Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2002-2010, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 #define EXPRDESC_H
 
 
-                     
+
+#include <string.h>
+
+/* common */
+#include "fp.h"
+#include "inline.h"
+
 /* cc65 */
+#include "asmcode.h"
 #include "datatype.h"
 
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                   Data                                    */
 /*****************************************************************************/
 
 
 
 /* Defines for the flags field of the expression descriptor */
-#define E_MREG                 0x0110U /* Special: Expression is primary register */
-#define E_MGLOBAL              0x0080U /* Reference to static variable */
-#define E_MLOCAL       0x0040U /* Reference to local variable (stack offset) */
-#define E_MCONST       0x0020U /* Constant value */
-#define E_MEXPR                0x0010U /* Result is in primary register */
-#define E_MEOFFS               0x0011U /* Base is in primary register, const offset */
-
-#define E_MCTYPE               0x0007U /* Type of a constant */
-#define E_TCONST               0x0000U /* Constant */
-#define E_TGLAB                0x0001U /* Global label */
-#define E_TLIT                 0x0002U /* Literal of some kind */
-#define E_TLOFFS               0x0003U /* Constant stack offset */
-#define E_TLLAB                0x0004U /* Local label */
-#define E_TREGISTER            0x0005U /* Register variable */
-
-/* Defines for the test field of the expression descriptor */
-#define E_CC                   0x0001U /* expr has set cond codes apropos result value */
-#define E_FORCETEST            0x0002U /* if expr has NOT set CC, force a test */
+enum {
+    /* Location: Where is the value we're talking about? */
+    E_MASK_LOC          = 0x00FF,
+    E_LOC_ABS           = 0x0001,       /* Absolute: numeric address or const */
+    E_LOC_GLOBAL        = 0x0002,       /* Global variable */
+    E_LOC_STATIC        = 0x0004,       /* Static variable */
+    E_LOC_REGISTER      = 0x0008,       /* Register variable */
+    E_LOC_STACK         = 0x0010,       /* Value on the stack */
+    E_LOC_PRIMARY       = 0x0020,       /* The primary register */
+    E_LOC_EXPR          = 0x0040,       /* An expression in the primary register */
+    E_LOC_LITERAL       = 0x0080,       /* Literal in the literal pool */
+
+    /* Constant location of some sort (only if rval) */
+    E_LOC_CONST         = E_LOC_ABS | E_LOC_GLOBAL | E_LOC_STATIC |
+                          E_LOC_REGISTER | E_LOC_LITERAL,
+
+    /* Reference? */
+    E_MASK_RTYPE        = 0x0100,
+    E_RTYPE_RVAL        = 0x0000,
+    E_RTYPE_LVAL        = 0x0100,
+
+    /* Bit-field? */
+    E_BITFIELD          = 0x0200,
+
+    /* Test */
+    E_NEED_TEST         = 0x0400,       /* Expression needs a test to set cc */
+    E_CC_SET            = 0x0800,       /* Condition codes are set */
+
+    E_HAVE_MARKS        = 0x1000,       /* Code marks are valid */
+
+};
+
+/* Forward */
+struct Literal;
 
 /* Describe the result of an expression */
 typedef struct ExprDesc ExprDesc;
 struct ExprDesc {
-    struct SymEntry*   Sym;     /* Symbol table entry if known */
-    type*              Type;    /* Type array of expression */
-    long                       ConstVal;/* Value if expression constant */
-    unsigned short             Flags;
-    unsigned short     Test;    /* */
-    unsigned long      Name;    /* Name or label number */
+    struct SymEntry*    Sym;            /* Symbol table entry if known */
+    Type*               Type;           /* Type array of expression */
+    unsigned            Flags;
+    unsigned long       Name;           /* Name or label number */
+    long                IVal;           /* Integer value if expression constant */
+    Double              FVal;           /* Floating point value */
+    struct Literal*     LVal;           /* Literal value */
+
+    /* Bit field stuff */
+    unsigned            BitOffs;        /* Bit offset for bit fields */
+    unsigned            BitWidth;       /* Bit width for bit fields */
+
+    /* Start and end of generated code */
+    CodeMark            Start;
+    CodeMark            End;
 };
 
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                   Code                                    */
 /*****************************************************************************/
 
 
 
-void MakeConstIntExpr (ExprDesc* Expr, long Value);
+ExprDesc* ED_Init (ExprDesc* Expr);
+/* Initialize an ExprDesc */
+
+#if defined(HAVE_INLINE)
+INLINE int ED_GetLoc (const ExprDesc* Expr)
+/* Return the location flags from the expression */
+{
+    return (Expr->Flags & E_MASK_LOC);
+}
+#else
+#  define ED_GetLoc(Expr)       ((Expr)->Flags & E_MASK_LOC)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsLocAbs (const ExprDesc* Expr)
+/* Return true if the expression is an absolute value */
+{
+    return (Expr->Flags & E_MASK_LOC) == E_LOC_ABS;
+}
+#else
+#  define ED_IsLocAbs(Expr)     (((Expr)->Flags & E_MASK_LOC) == E_LOC_ABS)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsLocRegister (const ExprDesc* Expr)
+/* Return true if the expression is located in a register */
+{
+    return (Expr->Flags & E_MASK_LOC) == E_LOC_REGISTER;
+}
+#else
+#  define ED_IsLocRegister(Expr)    (((Expr)->Flags & E_MASK_LOC) == E_LOC_REGISTER)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsLocStack (const ExprDesc* Expr)
+/* Return true if the expression is located on the stack */
+{
+    return (Expr->Flags & E_MASK_LOC) == E_LOC_STACK;
+}
+#else
+#  define ED_IsLocStack(Expr)     (((Expr)->Flags & E_MASK_LOC) == E_LOC_STACK)
+#endif
+
+#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 (Expr->Flags & E_MASK_LOC) == E_LOC_PRIMARY;
+}
+#else
+#  define ED_IsLocPrimary(Expr)  (((Expr)->Flags & E_MASK_LOC) == E_LOC_PRIMARY)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsLocExpr (const ExprDesc* Expr)
+/* Return true if the expression is an expression in the primary */
+{
+    return (Expr->Flags & E_MASK_LOC) == E_LOC_EXPR;
+}
+#else
+#  define ED_IsLocExpr(Expr)     (((Expr)->Flags & E_MASK_LOC) == E_LOC_EXPR)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsLocLiteral (const ExprDesc* Expr)
+/* Return true if the expression is a string from the literal pool */
+{               
+    return (Expr->Flags & E_MASK_LOC) == E_LOC_LITERAL;
+}
+#else
+#  define ED_IsLocLiteral(Expr)   (((Expr)->Flags & E_MASK_LOC) == E_LOC_LITERAL)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsLocConst (const ExprDesc* Expr)
+/* Return true if the expression is a constant location of some sort */
+{
+    return (Expr->Flags & E_LOC_CONST) != 0;
+}
+#else
+#  define ED_IsLocConst(Expr)  (((Expr)->Flags & E_LOC_CONST) != 0)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsLVal (const ExprDesc* Expr)
+/* Return true if the expression is a reference */
+{
+    return (Expr->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL;
+}
+#else
+#  define ED_IsLVal(Expr)       (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_LVAL)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsRVal (const ExprDesc* Expr)
+/* Return true if the expression is a rvalue */
+{
+    return (Expr->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL;
+}
+#else
+#  define ED_IsRVal(Expr)       (((Expr)->Flags & E_MASK_RTYPE) == E_RTYPE_RVAL)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE void ED_MakeLVal (ExprDesc* Expr)
+/* Make the expression a lvalue. */
+{
+    Expr->Flags |= E_RTYPE_LVAL;
+}
+#else
+#  define ED_MakeLVal(Expr)     do { (Expr)->Flags |= E_RTYPE_LVAL; } while (0)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE void ED_MakeRVal (ExprDesc* Expr)
+/* Make the expression a rvalue. */
+{
+    Expr->Flags &= ~E_RTYPE_LVAL;
+}
+#else
+#  define ED_MakeRVal(Expr)     do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_IsBitField (const ExprDesc* Expr)
+/* Return true if the expression is a bit field */
+{
+    return (Expr->Flags & E_BITFIELD) != 0;
+}
+#else
+#  define ED_IsBitField(Expr)   (((Expr)->Flags & E_BITFIELD) != 0)
+#endif
+
+void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth);
+/* Make this expression a bit field expression */
+
+#if defined(HAVE_INLINE)
+INLINE void ED_MarkForTest (ExprDesc* Expr)
+/* Mark the expression for a test. */
+{
+    Expr->Flags |= E_NEED_TEST;
+}
+#else
+#  define ED_MarkForTest(Expr)  do { (Expr)->Flags |= E_NEED_TEST; } while (0)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE int ED_NeedsTest (const ExprDesc* Expr)
+/* Check if the expression needs a test. */
+{
+    return (Expr->Flags & E_NEED_TEST) != 0;
+}
+#else
+#  define ED_NeedsTest(Expr)    (((Expr)->Flags & E_NEED_TEST) != 0)
+#endif
+
+#if defined(HAVE_INLINE)
+INLINE void ED_TestDone (ExprDesc* Expr)
+/* Mark the expression as tested and condition codes set. */
+{
+    Expr->Flags = (Expr->Flags & ~E_NEED_TEST) | E_CC_SET;
+}
+#else
+#  define ED_TestDone(Expr)     \
+    do { (Expr)->Flags = ((Expr)->Flags & ~E_NEED_TEST) | 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. */
+{
+    return (Expr->Flags & E_CC_SET) != 0;
+}
+#else
+#  define ED_IsTested(Expr)   (((Expr)->Flags & E_CC_SET) != 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_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, Type* Type);
+/* Make Expr an absolute const with the given value and type. */
+
+ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value);
 /* Make Expr a constant integer expression with the given value */
 
-void PrintExprDesc (FILE* F, ExprDesc* Expr);
-/* Print an ExprDesc */
+ExprDesc* ED_MakeRValExpr (ExprDesc* Expr);
+/* Convert Expr into a rvalue which is in the primary register without an
+** offset.
+*/
 
+ExprDesc* ED_MakeLValExpr (ExprDesc* Expr);
+/* Convert Expr into a lvalue which is in the primary register without an
+** offset.
+*/
 
+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.
+*/
 
-/* End of exprdesc.h */
+#if defined(HAVE_INLINE)
+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 (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL);
+}
+#else
+#  define ED_IsConstAbs(E)      \
+        (((E)->Flags & (E_MASK_LOC|E_MASK_RTYPE)) == (E_LOC_ABS|E_RTYPE_RVAL))
 #endif
 
+int ED_IsConstAbsInt (const ExprDesc* Expr);
+/* Return true if the expression is a constant (numeric) integer. */
 
+int ED_IsNullPtr (const ExprDesc* Expr);
+/* Return true if the given expression is a NULL pointer constant */
 
+int ED_IsBool (const ExprDesc* Expr);
+/* Return true of the expression can be treated as a boolean, that is, it can
+** be an operand to a compare operation.
+*/
+
+void PrintExprDesc (FILE* F, ExprDesc* Expr);
+/* Print an ExprDesc */
+
+Type* ReplaceType (ExprDesc* Expr, const Type* NewType);
+/* Replace the type of Expr by a copy of Newtype and return the old type string */
+
+
+
+/* End of exprdesc.h */
+
+#endif