Replace calls to memset with _bzero if the fill value is zero and -Oi in

effect.


git-svn-id: svn://svn.cc65.org/cc65/trunk@1359 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2002-07-16 11:01:51 +00:00
parent 87fa3fbdaa
commit 02c26efdd3
3 changed files with 116 additions and 18 deletions

View File

@@ -756,7 +756,7 @@ static void FunctionCall (int k, ExprDesc* lval)
} else if (InlineStdFuncs && IsStdFunc ((const char*) lval->Name)) { } else if (InlineStdFuncs && IsStdFunc ((const char*) lval->Name)) {
/* Inline this function */ /* Inline this function */
HandleStdFunc (lval); HandleStdFunc (Func, lval);
return; return;
} }

View File

@@ -37,11 +37,13 @@
#include <string.h> #include <string.h>
/* common */ /* common */
#include "attrib.h"
#include "check.h" #include "check.h"
/* cc65 */ /* cc65 */
#include "codegen.h" #include "codegen.h"
#include "error.h" #include "error.h"
#include "funcdesc.h"
#include "global.h" #include "global.h"
#include "scanner.h" #include "scanner.h"
#include "stdfunc.h" #include "stdfunc.h"
@@ -54,7 +56,8 @@
static void StdFunc_strlen (ExprDesc*); static void StdFunc_memset (FuncDesc*, ExprDesc*);
static void StdFunc_strlen (FuncDesc*, ExprDesc*);
@@ -69,8 +72,9 @@ static void StdFunc_strlen (ExprDesc*);
*/ */
static struct StdFuncDesc { static struct StdFuncDesc {
const char* Name; const char* Name;
void (*Handler) (ExprDesc*); void (*Handler) (FuncDesc*, ExprDesc*);
} StdFuncs [] = { } StdFuncs [] = {
{ "memset", StdFunc_memset },
{ "strlen", StdFunc_strlen }, { "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 */ /* 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 */ /* Handle the strlen function */
{ {
ExprDesc pval; 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. */ /* Generate code for a known standard function. */
{ {
/* Get a pointer to the table entry */ /* Get a pointer to the table entry */
struct StdFuncDesc* F = FindFunc ((const char*) lval->Name); struct StdFuncDesc* D = FindFunc ((const char*) lval->Name);
CHECK (F != 0); CHECK (D != 0);
/* Call the handler function */ /* Call the handler function */
F->Handler (lval); D->Handler (F, lval);
} }

View File

@@ -6,7 +6,7 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@musoftware.de */
@@ -38,8 +38,9 @@
#include "symtab.h" /* cc65 */
#include "expr.h" #include "expr.h"
#include "symtab.h"
@@ -54,7 +55,7 @@ int IsStdFunc (const char* Name);
* called in a special way. * called in a special way.
*/ */
void HandleStdFunc (ExprDesc* lval); void HandleStdFunc (struct FuncDesc* F, ExprDesc* lval);
/* Generate code for a known standard function. */ /* Generate code for a known standard function. */