]> git.sur5r.net Git - cc65/blobdiff - src/cc65/exprdesc.c
Fix a problem with error handling: The E_HAVE_MARKS flag must not be removed
[cc65] / src / cc65 / exprdesc.c
index 14200a9e1953a7d2a572d35eb821fe5782be02cf..1bde63abff683e5d67e5957a25d9a78003e85d69 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2002-2004 Ullrich von Bassewitz                                       */
-/*               Römerstraße 52                                              */
-/*               D-70794 Filderstadt                                         */
-/* EMail:        uz@cc65.org                                                 */
+/* (C) 2002-2009, Ullrich von Bassewitz                                      */
+/*                Roemerstrasse 52                                           */
+/*                D-70794 Filderstadt                                        */
+/* EMail:         uz@cc65.org                                                */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 /* common */
-#include "xsprintf.h"
+#include "check.h"
+#include "strbuf.h"
 
 /* cc65 */
 #include "asmlabel.h"
 #include "datatype.h"
 #include "error.h"
+#include "exprdesc.h"
+#include "stackptr.h"
 #include "symentry.h"
 #include "exprdesc.h"
 
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                  Code                                    */
 /*****************************************************************************/
 
 
 ExprDesc* ED_Init (ExprDesc* Expr)
 /* Initialize an ExprDesc */
 {
-    Expr->Sym   = 0;
-    Expr->Type  = 0;
-    Expr->Val   = 0;
-    Expr->Flags = 0;
-    Expr->Test  = 0;
-    Expr->Name  = 0;
+    Expr->Sym       = 0;
+    Expr->Type      = 0;
+    Expr->Flags     = 0;
+    Expr->Name      = 0;
+    Expr->IVal      = 0;
+    Expr->FVal      = FP_D_Make (0.0);
+    Expr->BitOffs   = 0;
+    Expr->BitWidth  = 0;
     return Expr;
 }
 
 
 
+void ED_MakeBitField (ExprDesc* Expr, unsigned BitOffs, unsigned BitWidth)
+/* Make this expression a bit field expression */
+{
+    Expr->Flags   |= E_BITFIELD;
+    Expr->BitOffs  = BitOffs;
+    Expr->BitWidth = BitWidth;
+}
+
+
+
+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);
+}
+
+
+
 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.
  */
 {
-    static char Buf[256];
+    static StrBuf Buf = STATIC_STRBUF_INITIALIZER;
 
     /* Expr may have it's own offset, adjust Offs accordingly */
-    Offs += Expr->Val;
+    Offs += Expr->IVal;
 
     /* Generate a label depending on the location */
     switch (ED_GetLoc (Expr)) {
 
         case E_LOC_ABS:
             /* Absolute: numeric address or const */
-           xsprintf (Buf, sizeof (Buf), "$%04X", (int)(Offs & 0xFFFF));
+                   SB_Printf (&Buf, "$%04X", (int)(Offs & 0xFFFF));
             break;
 
         case E_LOC_GLOBAL:
         case E_LOC_STATIC:
             /* Global or static variable */
-           if (Offs) {
-               xsprintf (Buf, sizeof (Buf), "%s%+ld",
-                          SymGetAsmName (Expr->Sym), Offs);
-           } else {
-               xsprintf (Buf, sizeof (Buf), "%s",
-                          SymGetAsmName (Expr->Sym));
-           }
+           if (Offs) {
+               SB_Printf (&Buf, "%s%+ld", SymGetAsmName (Expr->Sym), Offs);
+           } else {
+               SB_Printf (&Buf, "%s", SymGetAsmName (Expr->Sym));
+           }
             break;
 
         case E_LOC_REGISTER:
             /* Register variable */
-           xsprintf (Buf, sizeof (Buf), "regbank+%u",
-                      (unsigned)(Offs & 0xFFFFU));
+           SB_Printf (&Buf, "regbank+%u", (unsigned)((Offs + Expr->Name) & 0xFFFFU));
             break;
 
         case E_LOC_LITERAL:
             /* Literal in the literal pool */
-           if (Offs) {
-               xsprintf (Buf, sizeof (Buf), "%s%+ld",
-                          LocalLabelName (Expr->Name), Offs);
-           } else {
-                       xsprintf (Buf, sizeof (Buf), "%s",
-                          LocalLabelName (Expr->Name));
+           if (Offs) {
+               SB_Printf (&Buf, "%s%+ld", LocalLabelName (Expr->Name), Offs);
+           } else {
+                       SB_Printf (&Buf, "%s", LocalLabelName (Expr->Name));
            }
             break;
 
@@ -118,20 +149,33 @@ const char* ED_GetLabelName (const ExprDesc* Expr, long Offs)
     }
 
     /* Return a pointer to the static buffer */
-    return Buf;
+    return SB_GetConstBuf (&Buf);
 }
 
 
 
-ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, type* Type)
+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.
+ */
+{
+    PRECONDITION (ED_IsLocStack (Expr));
+    Offs += ((int) Expr->IVal) - StackPtr;
+    CHECK (Offs >= 0);          /* Cannot handle negative stack offsets */
+    return Offs;
+}
+
+
+
+ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, Type* Type)
 /* Make Expr an absolute const with the given value and type. */
 {
     Expr->Sym   = 0;
     Expr->Type  = Type;
-    Expr->Val   = Value;
-    Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
-    Expr->Test  = 0;
+    Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS);
     Expr->Name  = 0;
+    Expr->IVal  = Value;
+    Expr->FVal  = FP_D_Make (0.0);
     return Expr;
 }
 
@@ -142,10 +186,10 @@ ExprDesc* ED_MakeConstAbsInt (ExprDesc* Expr, long Value)
 {
     Expr->Sym   = 0;
     Expr->Type  = type_int;
-    Expr->Val   = Value;
-    Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL;
-    Expr->Test  = 0;
+    Expr->Flags = E_LOC_ABS | E_RTYPE_RVAL | (Expr->Flags & E_HAVE_MARKS);
     Expr->Name  = 0;
+    Expr->IVal  = Value;
+    Expr->FVal  = FP_D_Make (0.0);
     return Expr;
 }
 
@@ -157,10 +201,11 @@ ExprDesc* ED_MakeRValExpr (ExprDesc* Expr)
  */
 {
     Expr->Sym   = 0;
-    Expr->Val   = 0;    /* No offset */
-    Expr->Flags = (Expr->Flags & ~(E_MASK_LOC|E_MASK_RTYPE)) | (E_LOC_EXPR|E_RTYPE_RVAL);
-    Expr->Test  = 0;
+    Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_BITFIELD | E_NEED_TEST | E_CC_SET);
+    Expr->Flags |= (E_LOC_EXPR | E_RTYPE_RVAL);
     Expr->Name  = 0;
+    Expr->IVal  = 0;    /* No offset */
+    Expr->FVal  = FP_D_Make (0.0);
     return Expr;
 }
 
@@ -172,10 +217,11 @@ ExprDesc* ED_MakeLValExpr (ExprDesc* Expr)
  */
 {
     Expr->Sym   = 0;
-    Expr->Val   = 0;    /* No offset */
-    Expr->Flags = (Expr->Flags & ~(E_MASK_LOC|E_MASK_RTYPE)) | (E_LOC_EXPR|E_RTYPE_LVAL);
-    Expr->Test  = 0;
+    Expr->Flags &= ~(E_MASK_LOC | E_MASK_RTYPE | E_BITFIELD | E_NEED_TEST | E_CC_SET);
+    Expr->Flags |= (E_LOC_EXPR | E_RTYPE_LVAL);
     Expr->Name  = 0;
+    Expr->IVal  = 0;    /* No offset */
+    Expr->FVal  = FP_D_Make (0.0);
     return Expr;
 }
 
@@ -192,16 +238,6 @@ int ED_IsConst (const ExprDesc* Expr)
 
 
 
-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_IsConst (Expr) && ED_IsLocAbs (Expr);
-}
-
-
-
 int ED_IsConstAbsInt (const ExprDesc* Expr)
 /* Return true if the expression is a constant (numeric) integer. */
 {
@@ -214,8 +250,9 @@ int ED_IsConstAbsInt (const ExprDesc* 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_ABS|E_RTYPE_RVAL) &&
-           Expr->Val == 0                                                        &&
+    return (Expr->Flags & (E_MASK_LOC|E_MASK_RTYPE|E_BITFIELD)) ==
+                                (E_LOC_ABS|E_RTYPE_RVAL) &&
+           Expr->IVal == 0                               &&
            IsClassInt (Expr->Type);
 }
 
@@ -250,7 +287,8 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
         fprintf (F, "Type:     (unknown)\n"
                     "Raw type: (unknown)\n");
     }
-    fprintf (F, "Value:    0x%08lX\n", E->Val);
+    fprintf (F, "IVal:     0x%08lX\n", E->IVal);
+    fprintf (F, "FVal:     %f\n", FP_D_ToFloat (E->FVal));
 
     Flags = E->Flags;
     Sep   = '(';
@@ -300,6 +338,21 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
         Flags &= ~E_RTYPE_LVAL;
         Sep = ',';
     }
+    if (Flags & E_BITFIELD) {
+        fprintf (F, "%cE_BITFIELD", Sep);
+        Flags &= ~E_BITFIELD;
+        Sep = ',';
+    }
+    if (Flags & E_NEED_TEST) {
+        fprintf (F, "%cE_NEED_TEST", Sep);
+        Flags &= ~E_NEED_TEST;
+        Sep = ',';
+    }
+    if (Flags & E_CC_SET) {
+        fprintf (F, "%cE_CC_SET", Sep);
+        Flags &= ~E_CC_SET;
+        Sep = ',';
+    }
     if (Flags) {
         fprintf (F, "%c,0x%04X", Sep, Flags);
         Sep = ',';
@@ -307,25 +360,15 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
     if (Sep != '(') {
         fputc (')', F);
     }
-    fputc ('\n', F);
-
-    fprintf (F, "\nTest:     ");
-    if (E->Test & E_CC) {
-        fprintf (F, "E_CC ");
-    }
-    if (E->Test & E_FORCETEST) {
-        fprintf (F, "E_FORCETEST ");
-    }
-
     fprintf (F, "\nName:     0x%08lX\n", E->Name);
 }
 
 
 
-type* ReplaceType (ExprDesc* Expr, const type* NewType)
+Type* ReplaceType (ExprDesc* Expr, const Type* NewType)
 /* Replace the type of Expr by a copy of Newtype and return the old type string */
 {
-    type* OldType = Expr->Type;
+    Type* OldType = Expr->Type;
     Expr->Type = TypeDup (NewType);
     return OldType;
 }