1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 15:29:46 +00:00

Rewrote code generation for the strlen standard function. Added code for

other standard functions in several places.


git-svn-id: svn://svn.cc65.org/cc65/trunk@3069 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2004-06-02 21:33:35 +00:00
parent 2bb2ceec33
commit 6e34e386cb
15 changed files with 282 additions and 188 deletions

View File

@ -464,21 +464,22 @@ void g_leave (void)
/* Function epilogue */
{
/* How many bytes of locals do we have to drop? */
int k = -StackPtr;
unsigned k = (unsigned) -StackPtr;
/* If we didn't have a variable argument list, don't call leave */
if (funcargs >= 0) {
/* Drop stackframe if needed */
/* Drop stackframe if needed. We can only drop 255 bytes at a time. */
k += funcargs;
if (k > 0) {
if (k <= 8) {
AddCodeLine ("jsr incsp%d", k);
while (k > 0) {
unsigned ToDrop = (k > 255)? 255 : k;
if (ToDrop <= 8) {
AddCodeLine ("jsr incsp%d", k);
} else {
CheckLocalOffs (k);
ldyconst (k);
AddCodeLine ("jsr addysp");
ldyconst (ToDrop);
AddCodeLine ("jsr addysp");
}
k -= ToDrop;
}
} else {
@ -488,6 +489,11 @@ void g_leave (void)
AddCodeLine ("jsr leave");
} else {
/* We've a stack frame to drop */
while (k > 255) {
ldyconst (255);
AddCodeLine ("jsr addysp");
k -= 255;
}
ldyconst (k);
AddCodeLine ("jsr leavey");
}
@ -4279,53 +4285,3 @@ void g_asmcode (struct StrBuf* B)
/*****************************************************************************/
/* Inlined known functions */
/*****************************************************************************/
void g_strlen (unsigned flags, unsigned long val, long offs)
/* Inline the strlen() function */
{
/* We need a label in both cases */
unsigned label = GetLocalLabel ();
/* Two different encodings */
if (flags & CF_CONST) {
/* The address of the string is constant. Create the correct label name */
const char* lbuf = GetLabelName (flags, val, offs);
/* Generate the strlen code */
AddCodeLine ("ldy #$FF");
g_defcodelabel (label);
AddCodeLine ("iny");
AddCodeLine ("lda %s,y", lbuf);
AddCodeLine ("bne %s", LocalLabelName (label));
AddCodeLine ("tax");
AddCodeLine ("tya");
} else {
/* Address not constant but in primary */
if (CodeSizeFactor < 400) {
/* This is too much code, so call strlen instead of inlining */
AddCodeLine ("jsr _strlen");
} else {
/* Inline the function */
AddCodeLine ("sta ptr1");
AddCodeLine ("stx ptr1+1");
AddCodeLine ("ldy #$FF");
g_defcodelabel (label);
AddCodeLine ("iny");
AddCodeLine ("lda (ptr1),y");
AddCodeLine ("bne %s", LocalLabelName (label));
AddCodeLine ("tax");
AddCodeLine ("tya");
}
}
}

View File

@ -472,17 +472,6 @@ void g_asmcode (struct StrBuf* B);
/*****************************************************************************/
/* Inlined known functions */
/*****************************************************************************/
void g_strlen (unsigned flags, unsigned long val, long offs);
/* Inline the strlen() function */
/* End of codegen.h */
#endif

View File

@ -455,13 +455,6 @@ void ExprLoad (unsigned Flags, ExprDesc* Expr)
Expr->Test &= ~E_FORCETEST;
}
}
#if 0
/* Regardless of the original contents, Expr is now an rvalue in the
* primary. ### Later...
*/
ED_MakeRValExpr (Expr);
#endif
}
@ -637,6 +630,7 @@ static void FunctionCall (ExprDesc* Expr)
{
FuncDesc* Func; /* Function descriptor */
int IsFuncPtr; /* Flag */
int StdFunc; /* Standard function index */
unsigned ParamSize; /* Number of parameter bytes */
CodeMark Mark = 0; /* Initialize to keep gcc silent */
int PtrOffs = 0; /* Offset of function pointer on stack */
@ -682,11 +676,12 @@ static void FunctionCall (ExprDesc* Expr)
}
/* Check for known standard functions and inline them if requested */
} else if (IS_Get (&InlineStdFuncs) && IsStdFunc ((const char*) Expr->Name)) {
} else if (IS_Get (&InlineStdFuncs) &&
(StdFunc = FindStdFunc ((const char*) Expr->Name)) >= 0) {
/* Inline this function */
HandleStdFunc (Func, Expr);
goto ExitPoint;
HandleStdFunc (StdFunc, Func, Expr);
return;
}
@ -712,7 +707,7 @@ static void FunctionCall (ExprDesc* Expr)
*/
if (ParamSize == 0) {
RemoveCode (Mark);
pop (CF_PTR);
pop (CF_PTR);
PtrOnStack = 0;
} else {
/* Load from the saved copy */
@ -752,7 +747,6 @@ static void FunctionCall (ExprDesc* Expr)
}
ExitPoint:
/* The function result is an rvalue in the primary register */
ED_MakeRValExpr (Expr);
Expr->Type = GetFuncReturn (Expr->Type);
@ -1110,7 +1104,7 @@ static void ArrayRef (ExprDesc* Expr)
* portion of the index (which is in (e)ax, so there's no further
* action required).
*/
g_scale (CF_INT | CF_UNSIGNED, CheckedSizeOf (ElementType));
g_scale (CF_INT, CheckedSizeOf (ElementType));
} else {
@ -1144,7 +1138,7 @@ static void ArrayRef (ExprDesc* Expr)
/* The array base address is on stack and the subscript is in the
* primary. Add both.
*/
g_add (CF_INT | CF_UNSIGNED, 0);
g_add (CF_INT, 0);
} else {
@ -1182,7 +1176,7 @@ static void ArrayRef (ExprDesc* Expr)
} else {
if (ED_IsLocAbs (Expr)) {
/* Constant numeric address. Just add it */
g_inc (CF_INT | CF_UNSIGNED, Expr->Val);
g_inc (CF_INT, Expr->Val);
} else if (ED_IsLocStack (Expr)) {
/* Base address is a local variable address */
if (IsTypeArray (Expr->Type)) {

View File

@ -33,8 +33,13 @@
/* common */
#include "xsprintf.h"
/* cc65 */
#include "asmlabel.h"
#include "datatype.h"
#include "error.h"
#include "symentry.h"
#include "exprdesc.h"
@ -60,6 +65,64 @@ ExprDesc* ED_Init (ExprDesc* Expr)
const char* ED_GetLabelName (const ExprDesc* Expr, long Offs)
/* Return the assembler label name of the given expression. Beware: This
* function may use a static buffer, so the name may get "lost" on the second
* call to the function.
*/
{
static char Buf[256];
/* Expr may have it's own offset, adjust Offs accordingly */
Offs += Expr->Val;
/* Generate a label depending on the location */
switch (ED_GetLoc (Expr)) {
case E_LOC_ABS:
/* Absolute: numeric address or const */
xsprintf (Buf, sizeof (Buf), "$%04X", (int)(Offs & 0xFFFF));
break;
case E_LOC_GLOBAL:
case E_LOC_STATIC:
/* Global or static variable */
if (Offs) {
xsprintf (Buf, sizeof (Buf), "%s%+ld",
SymGetAsmName (Expr->Sym), Offs);
} else {
xsprintf (Buf, sizeof (Buf), "%s",
SymGetAsmName (Expr->Sym));
}
break;
case E_LOC_REGISTER:
/* Register variable */
xsprintf (Buf, sizeof (Buf), "regbank+%u",
(unsigned)(Offs & 0xFFFFU));
break;
case E_LOC_LITERAL:
/* Literal in the literal pool */
if (Offs) {
xsprintf (Buf, sizeof (Buf), "%s%+ld",
LocalLabelName (Expr->Name), Offs);
} else {
xsprintf (Buf, sizeof (Buf), "%s",
LocalLabelName (Expr->Name));
}
break;
default:
Internal ("Invalid location in ED_GetLabelName: 0x%04X", ED_GetLoc (Expr));
}
/* Return a pointer to the static buffer */
return Buf;
}
ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, type* Type)
/* Make Expr an absolute const with the given value and type. */
{

View File

@ -123,6 +123,16 @@ INLINE int ED_IsLocAbs (const ExprDesc* Expr)
# define ED_IsLocAbs(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_ABS)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_IsLocRegister (const ExprDesc* Expr)
/* Return true if the expression is located in a register */
{
return (Expr->Flags & E_MASK_LOC) == E_LOC_REGISTER;
}
#else
# define ED_IsLocRegister(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_REGISTER)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_IsLocStack (const ExprDesc* Expr)
/* Return true if the expression is located on the stack */
@ -133,6 +143,16 @@ INLINE int ED_IsLocStack (const ExprDesc* Expr)
# define ED_IsLocStack(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_STACK)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_IsLocPrimary (const ExprDesc* Expr)
/* Return true if the expression is an expression in the register pseudo variable */
{
return (Expr->Flags & E_MASK_LOC) == E_LOC_PRIMARY;
}
#else
# define ED_IsLocExpr(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_PRIMARY)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_IsLocExpr (const ExprDesc* Expr)
/* Return true if the expression is an expression in the primary */
@ -143,6 +163,16 @@ INLINE int ED_IsLocExpr (const ExprDesc* Expr)
# define ED_IsLocExpr(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_EXPR)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_IsLocLiteral (const ExprDesc* Expr)
/* Return true if the expression is a string from the literal pool */
{
return (Expr->Flags & E_MASK_LOC) == E_LOC_LITERAL;
}
#else
# define ED_IsLocLiteral(Expr) (((Expr)->Flags & E_MASK_LOC) == E_LOC_LITERAL)
#endif
#if defined(HAVE_INLINE)
INLINE int ED_IsLocConst (const ExprDesc* Expr)
/* Return true if the expression is a constant location of some sort */
@ -193,6 +223,12 @@ INLINE void ED_MakeRVal (ExprDesc* Expr)
# define ED_MakeRVal(Expr) do { (Expr)->Flags &= ~E_RTYPE_LVAL; } while (0)
#endif
const char* ED_GetLabelName (const ExprDesc* Expr, long Offs);
/* Return the assembler label name of the given expression. Beware: This
* function may use a static buffer, so the name may get "lost" on the second
* call to the function.
*/
ExprDesc* ED_MakeConstAbs (ExprDesc* Expr, long Value, type* Type);
/* Make Expr an absolute const with the given value and type. */

View File

@ -47,7 +47,6 @@ unsigned char AddSource = 0; /* Add source lines as comments */
unsigned char DebugInfo = 0; /* Add debug info to the obj */
unsigned char CreateDep = 0; /* Create a dependency file */
unsigned char ANSI = 0; /* Strict ANSI flag */
unsigned char WriteableStrings = 0; /* Literal strings are r/w */
unsigned char NoWarn = 0; /* Suppress warnings */
unsigned char Optimize = 0; /* Optimize flag */
unsigned long OptDisable = 0; /* Optimizer passes to disable */
@ -56,6 +55,7 @@ unsigned CodeSizeFactor = 100; /* Size factor for generated code */
unsigned RegisterSpace = 6; /* Space available for register vars */
/* Stackable options */
IntStack WritableStrings = INTSTACK(0); /* Literal strings are r/w */
IntStack InlineStdFuncs = INTSTACK(0); /* Inline some known functions */
IntStack EnableRegVars = INTSTACK(0); /* Enable register variables */
IntStack AllowRegVarAddr = INTSTACK(0); /* Allow taking addresses of register vars */

View File

@ -53,7 +53,6 @@ extern unsigned char AddSource; /* Add source lines as comments */
extern unsigned char DebugInfo; /* Add debug info to the obj */
extern unsigned char CreateDep; /* Create a dependency file */
extern unsigned char ANSI; /* Strict ANSI flag */
extern unsigned char WriteableStrings; /* Literal strings are r/w */
extern unsigned char NoWarn; /* Suppress warnings */
extern unsigned char Optimize; /* Optimize flag */
extern unsigned long OptDisable; /* Optimizer passes to disable */
@ -62,6 +61,7 @@ extern unsigned CodeSizeFactor; /* Size factor for generated code */
extern unsigned RegisterSpace; /* Space available for register vars */
/* Stackable options */
extern IntStack WritableStrings; /* Literal strings are r/w */
extern IntStack InlineStdFuncs; /* Inline some known functions */
extern IntStack EnableRegVars; /* Enable register variables */
extern IntStack AllowRegVarAddr; /* Allow taking addresses of register vars */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstraße 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -93,7 +93,7 @@ void DumpLiteralPool (void)
}
/* Switch to the data segment */
if (WriteableStrings) {
if (IS_Get (&WritableStrings)) {
g_usedata ();
} else {
g_userodata ();
@ -168,7 +168,7 @@ void GetLiteralStrBuf (StrBuf* Target, unsigned Offs)
/* Copy the string starting at Offs and lasting to the end of the buffer
* into Target.
*/
{
{
CHECK (Offs <= SB_GetLen (&LiteralPool));
SB_Slice (Target, &LiteralPool, Offs, SB_GetLen (&LiteralPool) - Offs);
}

View File

@ -127,7 +127,8 @@ static void Usage (void)
" --static-locals\tMake local variables static\n"
" --target sys\t\tSet the target system\n"
" --verbose\t\tIncrease verbosity\n"
" --version\t\tPrint the compiler version number\n",
" --version\t\tPrint the compiler version number\n"
" --writable-strings\tMake string literals writable\n",
ProgName);
}
@ -660,6 +661,15 @@ static void OptVersion (const char* Opt attribute ((unused)),
static void OptWritableStrings (const char* Opt attribute ((unused)),
const char* Arg attribute ((unused)))
/* Make string literals writable */
{
IS_Set (&WritableStrings, 1);
}
int main (int argc, char* argv[])
{
/* Program long options */
@ -691,6 +701,7 @@ int main (int argc, char* argv[])
{ "--target", 1, OptTarget },
{ "--verbose", 0, OptVerbose },
{ "--version", 0, OptVersion },
{ "--writable-strings", 0, OptWritableStrings },
};
unsigned I;

View File

@ -41,6 +41,7 @@
#include "check.h"
/* cc65 */
#include "asmlabel.h"
#include "codegen.h"
#include "error.h"
#include "funcdesc.h"
@ -54,7 +55,7 @@
/*****************************************************************************/
/* Function forwards */
/* Function forwards */
/*****************************************************************************/
@ -65,7 +66,7 @@ static void StdFunc_strlen (FuncDesc*, ExprDesc*);
/*****************************************************************************/
/* Data */
/* Data */
/*****************************************************************************/
@ -75,13 +76,14 @@ static void StdFunc_strlen (FuncDesc*, ExprDesc*);
*/
static struct StdFuncDesc {
const char* Name;
void (*Handler) (FuncDesc*, ExprDesc*);
} StdFuncs [] = {
void (*Handler) (FuncDesc*, ExprDesc*);
} StdFuncs[] = {
{ "memset", StdFunc_memset },
{ "strlen", StdFunc_strlen },
};
#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs [0]))
#define FUNC_COUNT (sizeof (StdFuncs) / sizeof (StdFuncs[0]))
/*****************************************************************************/
@ -98,16 +100,6 @@ static int CmpFunc (const void* Key, const void* Elem)
static struct StdFuncDesc* FindFunc (const char* Name)
/* Find a function with the given name. Return a pointer to the descriptor if
* found, return NULL otherwise.
*/
{
return bsearch (Name, StdFuncs, FUNC_COUNT, sizeof (StdFuncs [0]), CmpFunc);
}
static unsigned ParseArg (type* Type, ExprDesc* Arg)
/* Parse one argument but do not push it onto the stack. Return the code
* generator flags needed to do the actual push.
@ -146,8 +138,7 @@ static unsigned ParseArg (type* Type, ExprDesc* Arg)
static void StdFunc_memset (FuncDesc* F attribute ((unused)),
ExprDesc* lval attribute ((unused)))
static void StdFunc_memset (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
/* Handle the memset function */
{
/* Argument types */
@ -198,91 +189,123 @@ static void StdFunc_memset (FuncDesc* F attribute ((unused)),
/* We expect the closing brace */
ConsumeRParen ();
/* The function result is an rvalue in the primary register */
ED_MakeRValExpr (Expr);
Expr->Type = GetFuncReturn (Expr->Type);
}
static void StdFunc_strlen (FuncDesc* F attribute ((unused)),
ExprDesc* lval attribute ((unused)))
static void StdFunc_strlen (FuncDesc* F attribute ((unused)), ExprDesc* Expr)
/* Handle the strlen function */
{
static type ParamType[] = { T_PTR, T_SCHAR, T_END };
ExprDesc Param;
unsigned CodeFlags;
unsigned long ParamName;
static type ArgType[] = { T_PTR, T_SCHAR, T_END };
ExprDesc Arg;
unsigned L;
/* Setup the argument type string */
ParamType[1] = GetDefaultChar () | T_QUAL_CONST;
ArgType[1] = GetDefaultChar () | T_QUAL_CONST;
/* Fetch the parameter and convert it to the type needed */
hie1 (&Param);
TypeConversion (&Param, ParamType);
/* Evaluate the parameter */
hie1 (&Arg);
/* 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 ((ED_IsLocConst (&Param) && IsTypeArray (Param.Type)) ||
(ED_IsLocAbs (&Param) && IsTypePtr (Param.Type))) {
/* We can generate special code for several locations */
if (ED_IsLocConst (&Arg) && IsTypeArray (Arg.Type)) {
/* Check which type of constant it is */
switch (ED_GetLoc (&Param)) {
/* Do type conversion */
TypeConversion (&Arg, ArgType);
case E_LOC_ABS:
/* Numerical address */
CodeFlags |= CF_CONST | CF_ABSOLUTE;
break;
/* If the expression is a literal, and 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 (ED_IsLocLiteral (&Arg) && IS_Get (&WritableStrings)) {
case E_LOC_GLOBAL:
/* Global label */
CodeFlags |= CF_CONST | CF_EXTERNAL;
break;
/* Constant string literal */
ED_MakeConstAbs (Expr, strlen (GetLiteral (Arg.Val)), type_size_t);
ResetLiteralPoolOffs (Arg.Val);
case E_LOC_STATIC:
/* Local symbol */
CodeFlags |= CF_CONST | CF_STATIC;
break;
} else {
case E_LOC_REGISTER:
/* Register variable */
CodeFlags |= CF_CONST | CF_REGVAR;
break;
/* Generate the strlen code */
L = GetLocalLabel ();
AddCodeLine ("ldy #$FF");
g_defcodelabel (L);
AddCodeLine ("iny");
AddCodeLine ("lda %s,y", ED_GetLabelName (&Arg, 0));
AddCodeLine ("bne %s", LocalLabelName (L));
AddCodeLine ("tax");
AddCodeLine ("tya");
case E_LOC_LITERAL:
/* 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;
ED_MakeConstAbsInt (&Length, strlen (GetLiteral (Param.Val)));
ResetLiteralPoolOffs (Param.Val);
ExprLoad (CF_NONE, &Length);
goto ExitPoint;
} else {
CodeFlags |= CF_CONST | CF_STATIC;
ParamName = LiteralPoolLabel;
}
break;
/* The function result is an rvalue in the primary register */
ED_MakeRValExpr (Expr);
Expr->Type = type_size_t;
default:
Internal ("Unknown constant type: %04X", Param.Flags);
}
} else if (ED_IsLocStack (&Arg) && StackPtr >= -255 && IsTypeArray (Arg.Type)) {
/* Calculate the true stack offset */
unsigned Offs = (unsigned) (Arg.Val - StackPtr);
/* Do type conversion */
TypeConversion (&Arg, ArgType);
/* Generate the strlen code */
L = GetLocalLabel ();
AddCodeLine ("ldx #$FF");
AddCodeLine ("ldy #$%02X", (unsigned char) (Offs-1));
g_defcodelabel (L);
AddCodeLine ("inx");
AddCodeLine ("iny");
AddCodeLine ("lda (sp),y");
AddCodeLine ("bne %s", LocalLabelName (L));
AddCodeLine ("txa");
AddCodeLine ("ldx #$00");
/* The function result is an rvalue in the primary register */
ED_MakeRValExpr (Expr);
Expr->Type = type_size_t;
} else if (ED_IsLocRegister (&Arg) && ED_IsLVal (&Arg) && IsTypePtr (Arg.Type)) {
/* Do type conversion */
TypeConversion (&Arg, ArgType);
/* Generate the strlen code */
L = GetLocalLabel ();
AddCodeLine ("ldy #$FF");
g_defcodelabel (L);
AddCodeLine ("iny");
AddCodeLine ("lda (%s),y", ED_GetLabelName (&Arg, 0));
AddCodeLine ("bne %s", LocalLabelName (L));
AddCodeLine ("tax");
AddCodeLine ("tya");
/* The function result is an rvalue in the primary register */
ED_MakeRValExpr (Expr);
Expr->Type = type_size_t;
} else {
/* Not an array with a constant address. Load parameter into primary */
ExprLoad (CF_NONE, &Param);
/* Do type conversion */
TypeConversion (&Arg, ArgType);
/* Load the expression into the primary */
ExprLoad (CF_NONE, &Arg);
/* Call the strlen function */
AddCodeLine ("jsr _%s", Func_strlen);
/* The function result is an rvalue in the primary register */
ED_MakeRValExpr (Expr);
Expr->Type = type_size_t;
}
/* Generate the strlen code */
g_strlen (CodeFlags, ParamName, Param.Val);
ExitPoint:
/* We expect the closing brace */
ConsumeRParen ();
}
@ -295,23 +318,33 @@ ExitPoint:
int IsStdFunc (const char* Name)
int FindStdFunc (const char* Name)
/* Determine if the given function is a known standard function that may be
* called in a special way.
* called in a special way. If so, return the index, otherwise return -1.
*/
{
/* Look into the table for known names */
return FindFunc (Name) != 0;
struct StdFuncDesc* D =
bsearch (Name, StdFuncs, FUNC_COUNT, sizeof (StdFuncs[0]), CmpFunc);
/* Return the function index or -1 */
if (D == 0) {
return -1;
} else {
return D - StdFuncs;
}
}
void HandleStdFunc (FuncDesc* F, ExprDesc* lval)
void HandleStdFunc (int Index, FuncDesc* F, ExprDesc* lval)
/* Generate code for a known standard function. */
{
struct StdFuncDesc* D;
/* Get a pointer to the table entry */
struct StdFuncDesc* D = FindFunc ((const char*) lval->Name);
CHECK (D != 0);
CHECK (Index >= 0 && Index < (int)FUNC_COUNT);
D = StdFuncs + Index;
/* Call the handler function */
D->Handler (F, lval);

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998-2002 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2004 Ullrich von Bassewitz */
/* Römerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
@ -50,12 +50,12 @@
int IsStdFunc (const char* Name);
int FindStdFunc (const char* Name);
/* Determine if the given function is a known standard function that may be
* called in a special way.
* called in a special way. If so, return the index, otherwise return -1.
*/
void HandleStdFunc (struct FuncDesc* F, ExprDesc* lval);
void HandleStdFunc (int Index, struct FuncDesc* F, ExprDesc* lval);
/* Generate code for a known standard function. */

View File

@ -43,9 +43,10 @@
const char Func__bzero[] = "_bzero"; /* Asm name of "_bzero" */
const char Func_memcpy[] = "memcpy"; /* Asm name of "memcpy" */
const char Func_memset[] = "memset"; /* Asm name of "memset" */
const char Func__bzero[] = "_bzero"; /* Asm name of "_bzero */
const char Func_strlen[] = "strlen"; /* Asm name of "strlen" */

View File

@ -43,10 +43,11 @@
/*****************************************************************************/
extern const char Func__bzero[]; /* Asm name of "_bzero" */
extern const char Func_memcpy[]; /* Asm name of "memcpy" */
extern const char Func_memset[]; /* Asm name of "memset" */
extern const char Func__bzero[]; /* Asm name of "_bzero */
extern const char Func_strlen[]; /* Asm name of "strlen" */

View File

@ -197,6 +197,16 @@ INLINE int SymIsRegVar (const SymEntry* Sym)
# define SymIsRegVar(Sym) (((Sym)->Flags & (SC_REGISTER|SC_TYPE)) == SC_REGISTER)
#endif
#if defined(HAVE_INLINE)
INLINE const char* SymGetAsmName (const SymEntry* Sym)
/* Return the assembler label name for the symbol (beware: may be NULL!) */
{
return Sym->AsmName;
}
#else
# define SymGetAsmName(Sym) ((Sym)->AsmName)
#endif
void CvtRegVarToAuto (SymEntry* Sym);
/* Convert a register variable to an auto variable */

View File

@ -68,7 +68,7 @@ static void DoPtrConversions (ExprDesc* Expr)
static void DoConversion (ExprDesc* Expr, type* NewType)
static void DoConversion (ExprDesc* Expr, const type* NewType)
/* Emit code to convert the given expression to a new type. */
{
type* OldType;