X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fcc65%2Fstdfunc.c;h=1730ee08ac08647502a14ae0dc0b31d71262db75;hb=db42af3f20b49e5c63d66a6c8630e5bcc1f0b094;hp=74b9b8c2a2d91459ff041e786991bcbc2259e9c1;hpb=d8279302a947f26f248929eac552c7ed0c465cee;p=cc65 diff --git a/src/cc65/stdfunc.c b/src/cc65/stdfunc.c index 74b9b8c2a..1730ee08a 100644 --- a/src/cc65/stdfunc.c +++ b/src/cc65/stdfunc.c @@ -1,13 +1,13 @@ /*****************************************************************************/ /* */ -/* stdfunc.c */ +/* stdfunc.c */ /* */ -/* Handle inlining of known functions for the cc65 compiler */ +/* Handle inlining of known functions for the cc65 compiler */ /* */ /* */ /* */ -/* (C) 1998-2004 Ullrich von Bassewitz */ -/* Römerstrasse 52 */ +/* (C) 1998-2010 Ullrich von Bassewitz */ +/* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ /* */ @@ -58,20 +58,21 @@ /*****************************************************************************/ -/* Function forwards */ +/* Function forwards */ /*****************************************************************************/ static void StdFunc_memcpy (FuncDesc*, ExprDesc*); static void StdFunc_memset (FuncDesc*, ExprDesc*); +static void StdFunc_strcmp (FuncDesc*, ExprDesc*); static void StdFunc_strcpy (FuncDesc*, ExprDesc*); static void StdFunc_strlen (FuncDesc*, ExprDesc*); /*****************************************************************************/ -/* Data */ +/* Data */ /*****************************************************************************/ @@ -80,23 +81,24 @@ static void StdFunc_strlen (FuncDesc*, ExprDesc*); * alphabetically! */ static struct StdFuncDesc { - const char* Name; - void (*Handler) (FuncDesc*, ExprDesc*); + const char* Name; + void (*Handler) (FuncDesc*, ExprDesc*); } StdFuncs[] = { - { "memcpy", StdFunc_memcpy }, - { "memset", StdFunc_memset }, - { "strcpy", StdFunc_strcpy }, - { "strlen", StdFunc_strlen }, + { "memcpy", StdFunc_memcpy }, + { "memset", StdFunc_memset }, + { "strcmp", StdFunc_strcmp }, + { "strcpy", StdFunc_strcpy }, + { "strlen", StdFunc_strlen }, }; -#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0])) +#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0])) typedef struct ArgDesc ArgDesc; struct ArgDesc { - const type* ArgType; /* Required argument type */ + const Type* ArgType; /* Required argument type */ ExprDesc Expr; /* Argument expression */ - const type* Type; /* The original type before conversion */ - CodeMark Start; /* Start of the code for calculation */ + const Type* Type; /* The original type before conversion */ + CodeMark Load; /* Start of argument load code */ CodeMark Push; /* Start of argument push code */ CodeMark End; /* End of the code for calculation+push */ unsigned Flags; /* Code generation flags */ @@ -105,7 +107,7 @@ struct ArgDesc { /*****************************************************************************/ -/* Helper functions */ +/* Helper functions */ /*****************************************************************************/ @@ -139,7 +141,7 @@ static long ArrayElementCount (const ArgDesc* Arg) -static void ParseArg (ArgDesc* Arg, type* Type) +static void ParseArg (ArgDesc* Arg, Type* Type) /* Parse one argument but do not push it onto the stack. Make all fields in * Arg valid. */ @@ -150,11 +152,8 @@ static void ParseArg (ArgDesc* Arg, type* Type) /* Remember the required argument type */ Arg->ArgType = Type; - /* Remember the current code position */ - Arg->Start = GetCodePos (); - /* Read the expression we're going to pass to the function */ - ExprWithCheck (hie1, &Arg->Expr); + MarkedExprWithCheck (hie1, &Arg->Expr); /* Remember the actual argument type */ Arg->Type = Arg->Expr.Type; @@ -162,10 +161,13 @@ static void ParseArg (ArgDesc* Arg, type* Type) /* Convert this expression to the expected type */ TypeConversion (&Arg->Expr, Type); + /* Remember the following code position */ + GetCodePos (&Arg->Load); + /* If the value is a constant, set the flag, otherwise load it into the * primary register. */ - if (ED_IsConstAbsInt (&Arg->Expr)) { + if (ED_IsConstAbsInt (&Arg->Expr) && ED_CodeRangeIsEmpty (&Arg->Expr)) { /* Remember that we have a constant value */ Arg->Flags |= CF_CONST; } else { @@ -174,7 +176,8 @@ static void ParseArg (ArgDesc* Arg, type* Type) } /* Remember the following code position */ - Arg->End = Arg->Push = GetCodePos (); + GetCodePos (&Arg->Push); + GetCodePos (&Arg->End); /* Use the type of the argument for the push */ Arg->Flags |= TypeOf (Arg->Expr.Type); @@ -191,30 +194,27 @@ static void ParseArg (ArgDesc* Arg, type* Type) static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the memcpy function */ { - /* Argument types */ - static type Arg1Type[] = { T_PTR, T_VOID, T_END }; /* void* */ - static type Arg2Type[] = { T_PTR, T_VOID|T_QUAL_CONST, T_END }; /* const void* */ - static type Arg3Type[] = { T_SIZE_T, T_END }; /* size_t */ + /* Argument types: (void*, const void*, size_t) */ + static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; + static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_VOID|T_QUAL_CONST), TYPE(T_END) }; + static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; - CodeMark Start; ArgDesc Arg1, Arg2, Arg3; unsigned ParamSize = 0; unsigned Label; - - /* Remember where we are now */ - Start = GetCodePos (); + int Offs; /* Argument #1 */ ParseArg (&Arg1, Arg1Type); g_push (Arg1.Flags, Arg1.Expr.IVal); - Arg1.End = GetCodePos (); + GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); ConsumeComma (); /* Argument #2 */ ParseArg (&Arg2, Arg2Type); g_push (Arg2.Flags, Arg2.Expr.IVal); - Arg2.End = GetCodePos (); + GetCodePos (&Arg2.End); ParamSize += SizeOf (Arg2Type); ConsumeComma (); @@ -239,7 +239,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Remove all of the generated code but the load of the first * argument, which is what memcpy returns. */ - RemoveCode (Arg1.Push); + RemoveCode (&Arg1.Push); /* Set the function result to the first argument */ *Expr = Arg1.Expr; @@ -263,7 +263,7 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Reg2 = ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr); /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need a label */ Label = GetLocalLabel (); @@ -329,18 +329,18 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) !(ED_IsLocAbs (&Arg2.Expr) && Arg2.Expr.IVal < 256); /* Calculate the real stack offset */ - int Offs = ED_GetStackOffs (&Arg1.Expr, 0); + Offs = ED_GetStackOffs (&Arg1.Expr, 0); /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need a label */ Label = GetLocalLabel (); /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127) { + if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { - if (Offs == 0 || AllowOneIndex) { + if (Offs == 0) { AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg2.Expr, -Offs)); @@ -403,22 +403,22 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) !(ED_IsLocAbs (&Arg1.Expr) && Arg1.Expr.IVal < 256); /* Calculate the real stack offset */ - int Offs = ED_GetStackOffs (&Arg2.Expr, 0); + Offs = ED_GetStackOffs (&Arg2.Expr, 0); /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need a label */ Label = GetLocalLabel (); /* Generate memcpy code */ - if (Arg3.Expr.IVal <= 127) { + if (Arg3.Expr.IVal <= 127 && !AllowOneIndex) { - if (Offs == 0 || AllowOneIndex) { - AddCodeLine ("ldy #$%02X", (unsigned char) (Offs + Arg3.Expr.IVal - 1)); + if (Offs == 0) { + AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); g_defcodelabel (Label); AddCodeLine ("lda (sp),y"); - AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, -Offs)); + AddCodeLine ("sta %s,y", ED_GetLabelName (&Arg1.Expr, 0)); AddCodeLine ("dey"); AddCodeLine ("bpl %s", LocalLabelName (Label)); } else { @@ -461,6 +461,43 @@ static void StdFunc_memcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) */ *Expr = Arg1.Expr; + } else if (ED_IsConstAbsInt (&Arg3.Expr) && Arg3.Expr.IVal <= 256 && + ED_IsRVal (&Arg2.Expr) && ED_IsLocStack (&Arg2.Expr) && + (Offs = ED_GetStackOffs (&Arg2.Expr, 0)) == 0) { + + /* Drop the generated code but leave the load of the first argument*/ + RemoveCode (&Arg1.Push); + + /* We need a label */ + Label = GetLocalLabel (); + + /* Generate memcpy code */ + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + if (Arg3.Expr.IVal <= 127) { + AddCodeLine ("ldy #$%02X", (unsigned char) (Arg3.Expr.IVal - 1)); + g_defcodelabel (Label); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("dey"); + AddCodeLine ("bpl %s", LocalLabelName (Label)); + } else { + AddCodeLine ("ldy #$00"); + g_defcodelabel (Label); + AddCodeLine ("lda (sp),y"); + AddCodeLine ("sta (ptr1),y"); + AddCodeLine ("iny"); + AddCodeLine ("cpy #$%02X", (unsigned char) Arg3.Expr.IVal); + AddCodeLine ("bne %s", LocalLabelName (Label)); + } + + /* Reload result - X hasn't changed by the code above */ + AddCodeLine ("lda ptr1"); + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = GetFuncReturn (Expr->Type); + } else { /* The function result is an rvalue in the primary register */ @@ -485,24 +522,20 @@ ExitPoint: static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* 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_SIZE_T, T_END }; /* size_t */ + /* Argument types: (void*, int, size_t) */ + static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_VOID), TYPE(T_END) }; + static Type Arg2Type[] = { TYPE(T_INT), TYPE(T_END) }; + static Type Arg3Type[] = { TYPE(T_SIZE_T), TYPE(T_END) }; - CodeMark Start; ArgDesc Arg1, Arg2, Arg3; int MemSet = 1; /* Use real memset if true */ unsigned ParamSize = 0; unsigned Label; - /* Remember where we are now */ - Start = GetCodePos (); - /* Argument #1 */ ParseArg (&Arg1, Arg1Type); g_push (Arg1.Flags, Arg1.Expr.IVal); - Arg1.End = GetCodePos (); + GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); ConsumeComma (); @@ -516,7 +549,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } else { /* Push the argument */ g_push (Arg2.Flags, Arg2.Expr.IVal); - Arg2.End = GetCodePos (); + GetCodePos (&Arg2.End); ParamSize += SizeOf (Arg2Type); } ConsumeComma (); @@ -542,7 +575,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Remove all of the generated code but the load of the first * argument, which is what memset returns. */ - RemoveCode (Arg1.Push); + RemoveCode (&Arg1.Push); /* Set the function result to the first argument */ *Expr = Arg1.Expr; @@ -568,7 +601,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Reg = ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr); /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need a label */ Label = GetLocalLabel (); @@ -617,7 +650,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Offs = ED_GetStackOffs (&Arg1.Expr, 0); /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need a label */ Label = GetLocalLabel (); @@ -643,7 +676,7 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Remove all of the generated code but the load of the first * argument. */ - RemoveCode (Arg1.Push); + RemoveCode (&Arg1.Push); /* We need a label */ Label = GetLocalLabel (); @@ -692,6 +725,208 @@ ExitPoint: +/*****************************************************************************/ +/* strcmp */ +/*****************************************************************************/ + + + +static void StdFunc_strcmp (FuncDesc* F attribute ((unused)), ExprDesc* Expr) +/* Handle the strcmp function */ +{ + /* Argument types: (const char*, const char*) */ + static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; + + ArgDesc Arg1, Arg2; + unsigned ParamSize = 0; + long ECount1; + long ECount2; + int IsArray; + int Offs; + + /* Setup the argument type string */ + Arg1Type[1].C = GetDefaultChar () | T_QUAL_CONST; + Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST; + + /* Argument #1 */ + ParseArg (&Arg1, Arg1Type); + g_push (Arg1.Flags, Arg1.Expr.IVal); + ParamSize += SizeOf (Arg1Type); + ConsumeComma (); + + /* Argument #2. */ + ParseArg (&Arg2, Arg2Type); + + /* Since strcmp 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. + */ + if (Arg2.Flags & CF_CONST) { + LoadExpr (CF_NONE, &Arg2.Expr); + } + + /* Emit the actual function call. This will also cleanup the stack. */ + g_call (CF_FIXARGC, Func_strcmp, ParamSize); + + /* Get the element counts of the arguments. Then get the larger of the + * two into ECount1. This removes FLEXIBLE and UNSPECIFIED automatically + */ + ECount1 = ArrayElementCount (&Arg1); + ECount2 = ArrayElementCount (&Arg2); + if (ECount2 > ECount1) { + ECount1 = ECount2; + } + + /* If the second argument is the empty string literal, we can generate + * more efficient code. + */ + if (ED_IsLocLiteral (&Arg2.Expr) && + IS_Get (&WritableStrings) == 0 && + GetLiteralSize (Arg2.Expr.LVal) == 1 && + GetLiteralStr (Arg2.Expr.LVal)[0] == '\0') { + + /* Drop the generated code so we have the first argument in the + * primary + */ + RemoveCode (&Arg1.Push); + + /* We don't need the literal any longer */ + ReleaseLiteral (Arg2.Expr.LVal); + + /* We do now have Arg1 in the primary. Load the first character from + * this string and cast to int. This is the function result. + */ + IsArray = IsTypeArray (Arg1.Type) && ED_IsRVal (&Arg1.Expr); + if (IsArray && ED_IsLocStack (&Arg1.Expr) && + (Offs = ED_GetStackOffs (&Arg1.Expr, 0) < 256)) { + /* Drop the generated code */ + RemoveCode (&Arg1.Load); + + /* Generate code */ + AddCodeLine ("ldy #$%02X", Offs); + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda (sp),y"); + } else if (IsArray && ED_IsLocConst (&Arg1.Expr)) { + /* Drop the generated code */ + RemoveCode (&Arg1.Load); + + /* Generate code */ + AddCodeLine ("ldx #$00"); + AddCodeLine ("lda %s", ED_GetLabelName (&Arg1.Expr, 0)); + } else { + /* Drop part of the generated code so we have the first argument + * in the primary + */ + RemoveCode (&Arg1.Push); + + /* Fetch the first char */ + g_getind (CF_CHAR | CF_UNSIGNED, 0); + } + + } else if ((IS_Get (&CodeSizeFactor) >= 165) && + ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || + (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && + ((ED_IsRVal (&Arg1.Expr) && ED_IsLocConst (&Arg1.Expr)) || + (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr))) && + (IS_Get (&InlineStdFuncs) || (ECount1 > 0 && ECount1 < 256))) { + + + unsigned Entry, Loop, Fin; /* Labels */ + const char* Load; + const char* Compare; + + if (ED_IsLVal (&Arg1.Expr) && ED_IsLocRegister (&Arg1.Expr)) { + Load = "lda (%s),y"; + } else { + Load = "lda %s,y"; + } + if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { + Compare = "cmp (%s),y"; + } else { + Compare = "cmp %s,y"; + } + + /* Drop the generated code */ + RemoveCode (&Arg1.Expr.Start); + + /* We need labels */ + Entry = GetLocalLabel (); + Loop = GetLocalLabel (); + Fin = GetLocalLabel (); + + /* Generate strcmp code */ + AddCodeLine ("ldy #$00"); + AddCodeLine ("beq %s", LocalLabelName (Entry)); + g_defcodelabel (Loop); + AddCodeLine ("tax"); + AddCodeLine ("beq %s", LocalLabelName (Fin)); + AddCodeLine ("iny"); + g_defcodelabel (Entry); + AddCodeLine (Load, ED_GetLabelName (&Arg1.Expr, 0)); + AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0)); + AddCodeLine ("beq %s", LocalLabelName (Loop)); + AddCodeLine ("ldx #$01"); + AddCodeLine ("bcs %s", LocalLabelName (Fin)); + AddCodeLine ("ldx #$FF"); + g_defcodelabel (Fin); + + } else if ((IS_Get (&CodeSizeFactor) > 190) && + ((ED_IsRVal (&Arg2.Expr) && ED_IsLocConst (&Arg2.Expr)) || + (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr))) && + (IS_Get (&InlineStdFuncs) || (ECount1 > 0 && ECount1 < 256))) { + + + unsigned Entry, Loop, Fin; /* Labels */ + const char* Compare; + + if (ED_IsLVal (&Arg2.Expr) && ED_IsLocRegister (&Arg2.Expr)) { + Compare = "cmp (%s),y"; + } else { + Compare = "cmp %s,y"; + } + + /* Drop the generated code */ + RemoveCode (&Arg1.Push); + + /* We need labels */ + Entry = GetLocalLabel (); + Loop = GetLocalLabel (); + Fin = GetLocalLabel (); + + /* Store Arg1 into ptr1 */ + AddCodeLine ("sta ptr1"); + AddCodeLine ("stx ptr1+1"); + + /* Generate strcmp code */ + AddCodeLine ("ldy #$00"); + AddCodeLine ("beq %s", LocalLabelName (Entry)); + g_defcodelabel (Loop); + AddCodeLine ("tax"); + AddCodeLine ("beq %s", LocalLabelName (Fin)); + AddCodeLine ("iny"); + g_defcodelabel (Entry); + AddCodeLine ("lda (ptr1),y"); + AddCodeLine (Compare, ED_GetLabelName (&Arg2.Expr, 0)); + AddCodeLine ("beq %s", LocalLabelName (Loop)); + AddCodeLine ("ldx #$01"); + AddCodeLine ("bcs %s", LocalLabelName (Fin)); + AddCodeLine ("ldx #$FF"); + g_defcodelabel (Fin); + + } + + /* The function result is an rvalue in the primary register */ + ED_MakeRValExpr (Expr); + Expr->Type = GetFuncReturn (Expr->Type); + + /* We expect the closing brace */ + ConsumeRParen (); +} + + + /*****************************************************************************/ /* strcpy */ /*****************************************************************************/ @@ -701,27 +936,23 @@ ExitPoint: static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strcpy function */ { - /* Argument types */ - static type Arg1Type[] = { T_PTR, T_CHAR, T_END }; /* char* */ - static type Arg2Type[] = { T_PTR, T_CHAR|T_QUAL_CONST, T_END }; /* const char* */ + /* Argument types: (char*, const char*) */ + static Type Arg1Type[] = { TYPE(T_PTR), TYPE(T_CHAR), TYPE(T_END) }; + static Type Arg2Type[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; - CodeMark Start; ArgDesc Arg1, Arg2; unsigned ParamSize = 0; long ECount; unsigned L1; /* Setup the argument type string */ - Arg1Type[1] = GetDefaultChar (); - Arg2Type[1] = GetDefaultChar () | T_QUAL_CONST; - - /* Remember where we are now */ - Start = GetCodePos (); + Arg1Type[1].C = GetDefaultChar (); + Arg2Type[1].C = GetDefaultChar () | T_QUAL_CONST; /* Argument #1 */ ParseArg (&Arg1, Arg1Type); g_push (Arg1.Flags, Arg1.Expr.IVal); - Arg1.End = GetCodePos (); + GetCodePos (&Arg1.End); ParamSize += SizeOf (Arg1Type); ConsumeComma (); @@ -738,7 +969,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Emit the actual function call. This will also cleanup the stack. */ g_call (CF_FIXARGC, Func_strcpy, ParamSize); - /* Get the element count of argument 2 if it is an array */ + /* Get the element count of argument 1 if it is an array */ ECount = ArrayElementCount (&Arg1); /* We've generated the complete code for the function now and know the @@ -767,7 +998,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) } /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need labels */ L1 = GetLocalLabel (); @@ -801,7 +1032,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Offs = ED_GetStackOffs (&Arg2.Expr, 0); /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need labels */ L1 = GetLocalLabel (); @@ -844,7 +1075,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) int Offs = ED_GetStackOffs (&Arg1.Expr, 0); /* Drop the generated code */ - RemoveCode (Start); + RemoveCode (&Arg1.Expr.Start); /* We need labels */ L1 = GetLocalLabel (); @@ -892,7 +1123,7 @@ static void StdFunc_strcpy (FuncDesc* F attribute ((unused)), ExprDesc* Expr) static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Handle the strlen function */ { - static type ArgType[] = { T_PTR, T_SCHAR, T_END }; + static Type ArgType[] = { TYPE(T_PTR), TYPE(T_CHAR|T_QUAL_CONST), TYPE(T_END) }; ExprDesc Arg; int IsArray; int IsPtr; @@ -903,7 +1134,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /* Setup the argument type string */ - ArgType[1] = GetDefaultChar () | T_QUAL_CONST; + ArgType[1].C = GetDefaultChar () | T_QUAL_CONST; /* Evaluate the parameter */ hie1 (&Arg); @@ -941,8 +1172,10 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) if (ED_IsLocLiteral (&Arg) && IS_Get (&WritableStrings) == 0) { /* Constant string literal */ - ED_MakeConstAbs (Expr, strlen (GetLiteral (Arg.IVal)), type_size_t); - ResetLiteralPoolOffs (Arg.IVal); + ED_MakeConstAbs (Expr, GetLiteralSize (Arg.LVal) - 1, type_size_t); + + /* We don't need the literal any longer */ + ReleaseLiteral (Arg.LVal); /* We will inline strlen for arrays with constant addresses, if either the * inlining was forced on the command line, or the array is smaller than @@ -1057,7 +1290,7 @@ static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr) /*****************************************************************************/ -/* Code */ +/* Code */ /*****************************************************************************/ @@ -1093,6 +1326,3 @@ void HandleStdFunc (int Index, FuncDesc* F, ExprDesc* lval) /* Call the handler function */ D->Handler (F, lval); } - - -