]> git.sur5r.net Git - cc65/commitdiff
Replace calls to memset with _bzero if the fill value is zero and -Oi in
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 16 Jul 2002 11:01:51 +0000 (11:01 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Tue, 16 Jul 2002 11:01:51 +0000 (11:01 +0000)
effect.

git-svn-id: svn://svn.cc65.org/cc65/trunk@1359 b7a2c559-68d2-44c3-8de9-860c34a00d81

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

index 0f4a6a6575ceff5627c483b4a6786fc79c5107a2..dfebf8adcf5d3eab691980b3b0765bd263a02c9f 100644 (file)
@@ -244,7 +244,7 @@ unsigned assignadjust (type* lhst, ExprDesc* rhs)
                    case TC_INCOMPATIBLE:
                        Error ("Incompatible pointer types");
                        break;
-        
+
                    case TC_QUAL_DIFF:
                        Error ("Pointer types differ in type qualifiers");
                        break;
@@ -756,7 +756,7 @@ static void FunctionCall (int k, ExprDesc* lval)
     } else if (InlineStdFuncs && IsStdFunc ((const char*) lval->Name)) {
 
        /* Inline this function */
-               HandleStdFunc (lval);
+               HandleStdFunc (Func, lval);
                return;
 
     }
index ff554a3938f7db7cc15bd91a5f5859e561ff2b56..6d1c1844063958ca87251ba6a8fa1f6f9a877425 100644 (file)
 #include <string.h>
 
 /* common */
+#include "attrib.h"
 #include "check.h"
 
 /* cc65 */
 #include "codegen.h"
 #include "error.h"
+#include "funcdesc.h"
 #include "global.h"
 #include "scanner.h"
 #include "stdfunc.h"
 
 
 /*****************************************************************************/
-/*                            Function forwards                             */
+/*                            Function forwards                             */
 /*****************************************************************************/
 
 
 
-static void StdFunc_strlen (ExprDesc*);
+static void StdFunc_memset (FuncDesc*, ExprDesc*);
+static void StdFunc_strlen (FuncDesc*, ExprDesc*);
 
 
 
 /*****************************************************************************/
-/*                                  Data                                    */
+/*                                  Data                                    */
 /*****************************************************************************/
 
 
@@ -69,8 +72,9 @@ static void StdFunc_strlen (ExprDesc*);
  */
 static struct StdFuncDesc {
     const char*                Name;
-    void               (*Handler) (ExprDesc*);
+    void               (*Handler) (FuncDesc*, ExprDesc*);
 } StdFuncs [] = {
+    {          "memset",       StdFunc_memset          },
     {          "strlen",       StdFunc_strlen          },
 
 };
@@ -101,13 +105,106 @@ static struct StdFuncDesc* FindFunc (const char* Name)
 
 
 
+static unsigned ParseArg (type* Type, ExprDesc* pval)
+/* Parse one argument but do not push it onto the stack. Return the code
+ * generator flags needed to do the actual push.
+ */
+{
+    unsigned CFlags;
+    unsigned Flags;
+
+    /* Do some optimization: If we have a constant value to push,
+     * use a special function that may optimize.
+     */
+    CFlags = CF_NONE;
+    if (CheckedSizeOf (Type) == 1) {
+        CFlags = CF_FORCECHAR;
+    }
+    Flags = CF_NONE;
+    if (evalexpr (CFlags, hie1, pval) == 0) {
+        /* A constant value */
+        Flags |= CF_CONST;
+    }
+
+    /* Promote the argument if needed */
+    assignadjust (Type, pval);
+
+    /* We have a prototype, so chars may be pushed as chars */
+    Flags |= CF_FORCECHAR;
+
+    /* Use the type of the argument for the push */
+    return (Flags | TypeOf (pval->Type));
+}
+
+
+
 /*****************************************************************************/
 /*                         Handle known functions                           */
 /*****************************************************************************/
 
 
 
-static void StdFunc_strlen (ExprDesc* lval attribute ((unused)))
+static void StdFunc_memset (FuncDesc* F attribute ((unused)),
+                            ExprDesc* lval attribute ((unused)))
+/* Handle the memset function */
+{
+    /* Argument types */
+    static type Arg1Type[] = { T_PTR, T_VOID, T_END };  /* void* */
+    static type Arg2Type[] = { T_INT, T_END };          /* int */
+    static type Arg3Type[] = { T_UINT, T_END };         /* size_t */
+
+    unsigned Flags;
+    ExprDesc Arg;
+    int      MemSet    = 1;             /* Use real memset if true */
+    unsigned ParamSize = 0;
+
+
+    /* Check the prototype of the function against what we know about it, so
+     * we can detect errors.
+     */
+    /* ### */
+
+    /* Argument #1 */
+    Flags = ParseArg (Arg1Type, &Arg);
+    g_push (Flags, Arg.ConstVal);
+    ParamSize += SizeOf (Arg1Type);
+    ConsumeComma ();
+
+    /* Argument #2. This argument is special in that we will call another
+     * function if it is a constant zero.
+     */
+    Flags = ParseArg (Arg2Type, &Arg);
+    if ((Flags & CF_CONST) != 0 && Arg.ConstVal == 0) {
+        /* Don't call memset, call bzero instead */
+        MemSet = 0;
+    } else {
+        /* Push the argument */
+        g_push (Flags, Arg.ConstVal);
+        ParamSize += SizeOf (Arg2Type);
+    }               
+    ConsumeComma ();
+
+    /* Argument #3. Since memset is a fastcall function, we must load the
+     * arg into the primary if it is not already there. This parameter is
+     * also ignored for the calculation of the parameter size, since it is
+     * not passed via the stack.
+     */
+    Flags = ParseArg (Arg3Type, &Arg);
+    if (Flags & CF_CONST) {
+        exprhs (CF_FORCECHAR, 0, &Arg);
+    }
+
+    /* Emit the actual function call */
+    g_call (CF_NONE, MemSet? "memset" : "_bzero", ParamSize);
+
+    /* We expect the closing brace */
+    ConsumeRParen ();
+}
+
+
+
+static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
+                            ExprDesc* lval attribute ((unused)))
 /* Handle the strlen function */
 {
     ExprDesc pval;
@@ -169,15 +266,15 @@ int IsStdFunc (const char* Name)
 
 
 
-void HandleStdFunc (ExprDesc* lval)
+void HandleStdFunc (FuncDesc* F, ExprDesc* lval)
 /* Generate code for a known standard function. */
 {
     /* Get a pointer to the table entry */
-    struct StdFuncDesc* F = FindFunc ((const char*) lval->Name);
-    CHECK (F != 0);
+    struct StdFuncDesc* D = FindFunc ((const char*) lval->Name);
+    CHECK (D != 0);
 
     /* Call the handler function */
-    F->Handler (lval);
+    D->Handler (F, lval);
 }
 
 
index 19bc06c0cbf37de4057dfd406ef8d6160f618df5..809dc617bfb8cead95f9d8ed60b6a85ba87c79f1 100644 (file)
@@ -6,10 +6,10 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 1998     Ullrich von Bassewitz                                        */
-/*              Wacholderweg 14                                              */
-/*              D-70597 Stuttgart                                            */
-/* EMail:       uz@musoftware.de                                             */
+/* (C) 1998-2002 Ullrich von Bassewitz                                       */
+/*               Wacholderweg 14                                             */
+/*               D-70597 Stuttgart                                           */
+/* EMail:        uz@musoftware.de                                            */
 /*                                                                           */
 /*                                                                           */
 /* This software is provided 'as-is', without any expressed or implied       */
 
 
 
-#include "symtab.h"
+/* cc65 */
 #include "expr.h"
+#include "symtab.h"
 
 
 
 /*****************************************************************************/
-/*                                  Code                                    */
+/*                                  Code                                    */
 /*****************************************************************************/
 
 
@@ -54,7 +55,7 @@ int IsStdFunc (const char* Name);
  * called in a special way.
  */
 
-void HandleStdFunc (ExprDesc* lval);
+void HandleStdFunc (struct FuncDesc* F, ExprDesc* lval);
 /* Generate code for a known standard function. */