]> git.sur5r.net Git - cc65/commitdiff
Fixed the inlined strlen function
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 12 Dec 2002 17:40:58 +0000 (17:40 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Thu, 12 Dec 2002 17:40:58 +0000 (17:40 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@1738 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/expr.c
src/cc65/expr.h
src/cc65/exprdesc.h
src/cc65/stdfunc.c

index afdcf42a78fa2da878923b8bb8de5adffe518763..48675d99bf548a42847aa5da8da79d872da426aa 100644 (file)
@@ -8,7 +8,6 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
 
 /* common */
 #include "check.h"
@@ -87,6 +86,9 @@ static GenDesc GenOASGN  = { TOK_OR_ASSIGN,   GEN_NOPUSH,     g_or  };
 
 
 
+static int hie0 (ExprDesc *lval);
+/* Parse comma operator. */
+
 static int expr (int (*func) (ExprDesc*), ExprDesc *lval);
 /* Expression parser; func is either hie0 or hie1. */
 
@@ -183,7 +185,7 @@ static unsigned typeadjust (ExprDesc* lhs, ExprDesc* rhs, int NoPush)
     }
     flags = g_typeadjust (ltype, rtype);
 
-    /* Set the type of the result */            
+    /* Set the type of the result */
     lhs->Type = promoteint (lhst, rhst);
 
     /* Return the code generator flags */
@@ -465,7 +467,7 @@ void ConstSubExpr (int (*F) (ExprDesc*), ExprDesc* Expr)
  * from this input error.
  */
 {
-    memset (Expr, 0, sizeof (*Expr));
+    InitExprDesc (Expr);
     if (F (Expr) != 0 || Expr->Flags != E_MCONST) {
                Error ("Constant expression expected");
                /* To avoid any compiler errors, make the expression a valid const */
@@ -858,7 +860,7 @@ static int primary (ExprDesc* lval)
      */
     if (CurTok.Tok == TOK_LPAREN) {
        NextToken ();
-       memset (lval, 0, sizeof (*lval));       /* Remove any attributes */
+       InitExprDesc (lval);            /* Remove any attributes */
        k = hie0 (lval);
                ConsumeRParen ();
        return k;
@@ -915,7 +917,7 @@ static int primary (ExprDesc* lval)
            /* Check for legal symbol types */
                    if ((Sym->Flags & SC_CONST) == SC_CONST) {
                /* Enum or some other numeric constant */
-               lval->Flags = E_MCONST;
+               lval->Flags = E_MCONST | E_TCONST;
                lval->ConstVal = Sym->V.ConstVal;
                return 0;
            } else if ((Sym->Flags & SC_FUNC) == SC_FUNC) {
@@ -1232,7 +1234,7 @@ static int arrayref (int k, ExprDesc* lval)
                if (rflags == E_MLOCAL) {
                    g_addlocal (flags, lval2.ConstVal);
                } else {
-                   flags |= GlobalModeFlags (lval2.Flags);
+                   flags |= GlobalModeFlags (lval2.Flags);
                    g_addstatic (flags, lval2.Name, lval2.ConstVal);
                }
            } else {
@@ -1241,20 +1243,20 @@ static int arrayref (int k, ExprDesc* lval)
                    g_inc (CF_INT | CF_UNSIGNED, lval->ConstVal);
                } else if (lflags == E_MLOCAL) {
                    /* Base address is a local variable address */
-                   if (IsTypeArray (tptr1)) {
+                   if (IsTypeArray (tptr1)) {
                        g_addaddr_local (CF_INT, lval->ConstVal);
-                   } else {
+                   } else {
                        g_addlocal (CF_PTR, lval->ConstVal);
-                   }
+                   }
                } else {
                    /* Base address is a static variable address */
                    unsigned flags = CF_INT;
-                   flags |= GlobalModeFlags (lval->Flags);
-                   if (IsTypeArray (tptr1)) {
+                   flags |= GlobalModeFlags (lval->Flags);
+                   if (IsTypeArray (tptr1)) {
                        g_addaddr_static (flags, lval->Name, lval->ConstVal);
-                   } else {
-                       g_addstatic (flags, lval->Name, lval->ConstVal);
-                   }
+                   } else {
+                       g_addstatic (flags, lval->Name, lval->ConstVal);
+                   }
                }
            }
        }
@@ -3003,7 +3005,7 @@ int hie1 (ExprDesc* lval)
 
 
 
-int hie0 (ExprDesc *lval)
+static int hie0 (ExprDesc *lval)
 /* Parse comma operator. */
 {
     int k;
@@ -3069,7 +3071,7 @@ void expression1 (ExprDesc* lval)
  * the primary register
  */
 {
-    memset (lval, 0, sizeof (*lval));
+    InitExprDesc (lval);
     exprhs (CF_NONE, expr (hie1, lval), lval);
 }
 
@@ -3078,7 +3080,7 @@ void expression1 (ExprDesc* lval)
 void expression (ExprDesc* lval)
 /* Evaluate an expression and put it into the primary register */
 {
-    memset (lval, 0, sizeof (*lval));
+    InitExprDesc (lval);
     exprhs (CF_NONE, expr (hie0, lval), lval);
 }
 
@@ -3087,7 +3089,7 @@ void expression (ExprDesc* lval)
 void ConstExpr (ExprDesc* lval)
 /* Get a constant value */
 {
-    memset (lval, 0, sizeof (*lval));
+    InitExprDesc (lval);
     if (expr (hie1, lval) != 0 || (lval->Flags & E_MCONST) == 0) {
        Error ("Constant expression expected");
        /* To avoid any compiler errors, make the expression a valid const */
@@ -3100,7 +3102,7 @@ void ConstExpr (ExprDesc* lval)
 void ConstIntExpr (ExprDesc* Val)
 /* Get a constant int value */
 {
-    memset (Val, 0, sizeof (*Val));
+    InitExprDesc (Val);
     if (expr (hie1, Val) != 0        ||
        (Val->Flags & E_MCONST) == 0 ||
        !IsClassInt (Val->Type)) {
@@ -3134,8 +3136,7 @@ void Test (unsigned Label, int Invert)
     ExprDesc lval;
 
     /* Evaluate the expression */
-    memset (&lval, 0, sizeof (lval));
-    k = expr (hie0, &lval);
+    k = expr (hie0, InitExprDesc (&lval));
 
     /* Check for a boolean expression */
     CheckBoolExpr (&lval);
index 7068be05cb7414e5fa0b212a99f451ce78f31a7b..efd1777e66bf2a2be7161ebd67dd20ed72956aa8 100644 (file)
@@ -88,9 +88,6 @@ int hie10 (ExprDesc* lval);
 int hie1 (ExprDesc* lval);
 /* Parse first level of expression hierarchy. */
 
-int hie0 (ExprDesc* lval);
-/* Parse comma operator (highest level of expression hierarchy) */
-
 void DefineData (ExprDesc* lval);
 /* Output a data definition for the given expression */
 
index bdd29f703eb69142edeabefad5cac7d042d2351c..02a6e0e9317c946bcbc490e2453ee74d55212e54 100644 (file)
 
 
 
+#include <string.h>
+
+/* common */
+#include "inline.h"
+
 /* cc65 */
 #include "datatype.h"
 
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
@@ -83,11 +88,21 @@ struct ExprDesc {
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                  Code                                    */
 /*****************************************************************************/
 
 
 
+#if defined(HAVE_INLINE)
+INLINE ExprDesc* InitExprDesc (ExprDesc* Expr)
+/* Initialize an ExprDesc */
+{
+    return memset (Expr, 0, sizeof (*Expr));
+}
+#else
+#  define InitExprDesc(E)       memset ((E), 0, sizeof (*(E)))
+#endif
+
 void MakeConstIntExpr (ExprDesc* Expr, long Value);
 /* Make Expr a constant integer expression with the given value */
 
index 6d1c1844063958ca87251ba6a8fa1f6f9a877425..219ad470676da2404e15c010d87da75a8f04371c 100644 (file)
@@ -45,6 +45,7 @@
 #include "error.h"
 #include "funcdesc.h"
 #include "global.h"
+#include "litpool.h"
 #include "scanner.h"
 #include "stdfunc.h"
 
@@ -181,7 +182,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)),
         /* Push the argument */
         g_push (Flags, Arg.ConstVal);
         ParamSize += SizeOf (Arg2Type);
-    }               
+    }
     ConsumeComma ();
 
     /* Argument #3. Since memset is a fastcall function, we must load the
@@ -207,42 +208,86 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
                             ExprDesc* lval attribute ((unused)))
 /* Handle the strlen function */
 {
-    ExprDesc pval;
-    static type ArgType[] = { T_PTR, T_SCHAR, T_END };
+    static type ParamType[] = { T_PTR, T_SCHAR, T_END };
 
+    ExprDesc Param;
+    unsigned CodeFlags;
+    unsigned long ParamName;
 
     /* Fetch the parameter */
-    int k = hie1 (&pval);
-
-    /* Check if the parameter is a const address */
-    unsigned flags = 0;
-    unsigned pflags = pval.Flags & ~E_MCTYPE;
-    if (pflags == E_MCONST) {
-       /* Constant numeric address */
-       flags |= CF_CONST | CF_ABSOLUTE;
-    } else if (k == 0 && ((pflags & E_MGLOBAL) != 0 || pval.Flags == E_MEOFFS)) {
-       /* Global array with or without offset */
-       flags |= CF_CONST;
-       if (pval.Flags & E_TGLAB) {
-           /* External linkage */
-           flags |= CF_EXTERNAL;
-       } else {
-           flags |= CF_STATIC;
-       }
-    } else {
-       /* Not const, load parameter into primary */
-       exprhs (CF_NONE, k, &pval);
-    }
+    int k = hie1 (InitExprDesc (&Param));
 
     /* Setup the argument type string */
-    ArgType[1] = GetDefaultChar () | T_QUAL_CONST;
+    ParamType[1] = GetDefaultChar () | T_QUAL_CONST;
 
     /* Convert the parameter type to the type needed, check for mismatches */
-    assignadjust (ArgType, &pval);
+    assignadjust (ParamType, &Param);
+
+    /* Check if the parameter is a constant array of some type, or a numeric
+     * address cast to a pointer.
+     */
+    CodeFlags = 0;
+    ParamName = Param.Name;
+    if ((IsTypeArray (Param.Type) && (Param.Flags & E_MCONST) != 0) ||
+        (IsTypePtr (Param.Type) && Param.Flags == (E_MCONST | E_TCONST))) {
+
+        /* Check which type of constant it is */
+        switch (Param.Flags & E_MCTYPE) {
+
+            case E_TCONST:
+                /* Numerical address */
+                CodeFlags |= CF_CONST | CF_ABSOLUTE;
+                break;
+
+            case E_TREGISTER:
+                /* Register variable */
+                CodeFlags |= CF_CONST | CF_REGVAR;
+                break;
+
+            case E_TGLAB:
+                /* Global label */
+                CodeFlags |= CF_CONST | CF_EXTERNAL;
+                break;
+
+            case E_TLLAB:
+                /* Local symbol */
+                CodeFlags |= CF_CONST | CF_STATIC;
+                break;
+
+            case E_TLIT:
+                /* A literal of some kind. If string literals are read only,
+                 * we can calculate the length of the string and remove it
+                 * from the literal pool. Otherwise we have to calculate the
+                 * length at runtime.
+                 */
+                if (!WriteableStrings) {
+                    /* String literals are const */
+                    ExprDesc Length;
+                    MakeConstIntExpr (&Length, strlen (GetLiteral (Param.ConstVal)));
+                    ResetLiteralPoolOffs (Param.ConstVal);
+                    exprhs (CF_NONE, 0, &Length);
+                    goto ExitPoint;
+                } else {
+                    CodeFlags |= CF_CONST | CF_STATIC;
+                    ParamName = LiteralPoolLabel;
+                }
+                break;
+
+            default:
+                Internal ("Unknown constant type: %04X", Param.Flags);
+        }
+
+    } else {
+
+       /* Not an array with a constant address. Load parameter into primary */
+       exprhs (CF_NONE, k, &Param);
+
+    }
 
     /* Generate the strlen code */
-    g_strlen (flags, pval.Name, pval.ConstVal);
+    g_strlen (CodeFlags, ParamName, Param.ConstVal);
 
+ExitPoint:
     /* We expect the closing brace */
     ConsumeRParen ();
 }