From: cuz Date: Thu, 12 Dec 2002 17:40:58 +0000 (+0000) Subject: Fixed the inlined strlen function X-Git-Tag: V2.12.0~1919 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=4e2110a7a9ab0d054acb784b8585e9c7c6f4f399;p=cc65 Fixed the inlined strlen function git-svn-id: svn://svn.cc65.org/cc65/trunk@1738 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- diff --git a/src/cc65/expr.c b/src/cc65/expr.c index afdcf42a7..48675d99b 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -8,7 +8,6 @@ #include #include -#include /* 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); diff --git a/src/cc65/expr.h b/src/cc65/expr.h index 7068be05c..efd1777e6 100644 --- a/src/cc65/expr.h +++ b/src/cc65/expr.h @@ -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 */ diff --git a/src/cc65/exprdesc.h b/src/cc65/exprdesc.h index bdd29f703..02a6e0e93 100644 --- a/src/cc65/exprdesc.h +++ b/src/cc65/exprdesc.h @@ -38,13 +38,18 @@ +#include + +/* 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 */ diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 6d1c18440..219ad4706 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -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 (); }