1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-24 11:31:31 +00:00

Inline parameter frame building

git-svn-id: svn://svn.cc65.org/cc65/trunk@661 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-03-24 13:00:16 +00:00
parent 59bcc726b6
commit c18453ebcb
8 changed files with 279 additions and 158 deletions

View File

@ -652,63 +652,63 @@ void g_getimmed (unsigned flags, unsigned long val, unsigned offs)
{ {
if ((flags & CF_CONST) != 0) { if ((flags & CF_CONST) != 0) {
/* Numeric constant */ /* Numeric constant */
switch (flags & CF_TYPE) { switch (flags & CF_TYPE) {
case CF_CHAR: case CF_CHAR:
if ((flags & CF_FORCECHAR) != 0) { if ((flags & CF_FORCECHAR) != 0) {
ldaconst (val); ldaconst (val);
break; break;
} }
/* FALL THROUGH */ /* FALL THROUGH */
case CF_INT: case CF_INT:
ldxconst ((val >> 8) & 0xFF); ldxconst ((val >> 8) & 0xFF);
ldaconst (val & 0xFF); ldaconst (val & 0xFF);
break; break;
case CF_LONG: case CF_LONG:
if (val < 0x100) { if (val < 0x100) {
AddCodeLine ("\tldx\t#$00"); AddCodeLine ("\tldx\t#$00");
AddCodeLine ("\tstx\tsreg+1"); AddCodeLine ("\tstx\tsreg+1");
AddCodeLine ("\tstx\tsreg"); AddCodeLine ("\tstx\tsreg");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val); AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
} else if ((val & 0xFFFF00FF) == 0) { } else if ((val & 0xFFFF00FF) == 0) {
AddCodeLine ("\tlda\t#$00"); AddCodeLine ("\tlda\t#$00");
AddCodeLine ("\tsta\tsreg+1"); AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg"); AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8)); AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else if ((val & 0xFFFF0000) == 0 && FavourSize == 0) { } else if ((val & 0xFFFF0000) == 0 && FavourSize == 0) {
AddCodeLine ("\tlda\t#$00"); AddCodeLine ("\tlda\t#$00");
AddCodeLine ("\tsta\tsreg+1"); AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg"); AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val); AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8)); AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else if ((val & 0xFFFFFF00) == 0xFFFFFF00) { } else if ((val & 0xFFFFFF00) == 0xFFFFFF00) {
AddCodeLine ("\tldx\t#$FF"); AddCodeLine ("\tldx\t#$FF");
AddCodeLine ("\tstx\tsreg+1"); AddCodeLine ("\tstx\tsreg+1");
AddCodeLine ("\tstx\tsreg"); AddCodeLine ("\tstx\tsreg");
if ((val & 0xFF) == 0xFF) { if ((val & 0xFF) == 0xFF) {
AddCodeLine ("\ttxa"); AddCodeLine ("\ttxa");
} else { } else {
AddCodeLine ("\tlda\t#$%02X", (unsigned char) val); AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
} }
} else if ((val & 0xFFFF00FF) == 0xFFFF00FF) { } else if ((val & 0xFFFF00FF) == 0xFFFF00FF) {
AddCodeLine ("\tlda\t#$FF"); AddCodeLine ("\tlda\t#$FF");
AddCodeLine ("\tsta\tsreg+1"); AddCodeLine ("\tsta\tsreg+1");
AddCodeLine ("\tsta\tsreg"); AddCodeLine ("\tsta\tsreg");
AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8)); AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
} else { } else {
/* Call a subroutine that will load following value */ /* Call a subroutine that will load following value */
AddCodeLine ("\tjsr\tldeax"); AddCodeLine ("\tjsr\tldeax");
AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF); AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF);
} }
break; break;
default: default:
typeerror (flags); typeerror (flags);
break; break;
} }
} else { } else {
@ -1084,34 +1084,79 @@ void g_putstatic (unsigned flags, unsigned long label, unsigned offs)
void g_putlocal (unsigned flags, int offs) void g_putlocal (unsigned Flags, int Offs, long Val)
/* Put data into local object. */ /* Put data into local object. */
{ {
offs -= oursp; Offs -= oursp;
CheckLocalOffs (offs); CheckLocalOffs (Offs);
switch (flags & CF_TYPE) { switch (Flags & CF_TYPE) {
case CF_CHAR: case CF_CHAR:
if (CPU == CPU_65C02 && offs == 0) { if (Flags & CF_CONST) {
AddCodeLine ("\tsta\t(sp)"); AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val);
} else {
ldyconst (offs);
AddCodeLine ("\tsta\t(sp),y");
} }
break; if (CPU == CPU_65C02 && Offs == 0) {
AddCodeLine ("\tsta\t(sp)");
case CF_INT:
if (offs) {
ldyconst (offs);
AddCodeLine ("\tjsr\tstaxysp");
} else { } else {
AddCodeLine ("\tjsr\tstax0sp"); ldyconst (Offs);
AddCodeLine ("\tsta\t(sp),y");
} }
break; break;
case CF_INT:
if (Flags & CF_CONST) {
ldyconst (Offs+1);
AddCodeLine ("\tlda\t#$%02X", (unsigned char) (Val >> 8));
AddCodeLine ("\tsta\t(sp),y");
if ((Flags & CF_NOKEEP) == 0) {
/* Place high byte into X */
AddCodeLine ("\ttax");
}
if (CPU == CPU_65C02 && Offs == 0) {
AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val);
AddCodeLine ("\tsta\t(sp)");
} else {
if ((Val & 0xFF) == Offs+1) {
/* The value we need is already in Y */
AddCodeLine ("\ttya");
AddCodeLine ("\tdey");
} else {
AddCodeLine ("\tdey");
AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val);
}
AddCodeLine ("\tsta\t(sp),y");
}
} else {
if ((Flags & CF_NOKEEP) == 0 || FavourSize) {
if (Offs) {
ldyconst (Offs);
AddCodeLine ("\tjsr\tstaxysp");
} else {
AddCodeLine ("\tjsr\tstax0sp");
}
} else {
if (CPU == CPU_65C02 && Offs == 0) {
AddCodeLine ("\tsta\t(sp)");
ldyconst (1);
AddCodeLine ("\ttxa");
AddCodeLine ("\tsta\t(sp),y");
} else {
ldyconst (Offs);
AddCodeLine ("\tsta\t(sp),y");
AddCodeLine ("\tiny");
AddCodeLine ("\ttxa");
AddCodeLine ("\tsta\t(sp),y");
}
}
}
break;
case CF_LONG: case CF_LONG:
if (offs) { if (Flags & CF_CONST) {
ldyconst (offs); g_getimmed (Flags, Val, 0);
}
if (Offs) {
ldyconst (Offs);
AddCodeLine ("\tjsr\tsteaxysp"); AddCodeLine ("\tjsr\tsteaxysp");
} else { } else {
AddCodeLine ("\tjsr\tsteax0sp"); AddCodeLine ("\tjsr\tsteax0sp");
@ -1119,7 +1164,7 @@ void g_putlocal (unsigned flags, int offs)
break; break;
default: default:
typeerror (flags); typeerror (Flags);
} }
} }
@ -2461,44 +2506,44 @@ void g_swap (unsigned flags)
void g_call (unsigned flags, char* lbl, unsigned argsize) void g_call (unsigned Flags, const char* Label, unsigned ArgSize)
/* Call the specified subroutine name */ /* Call the specified subroutine name */
{ {
if ((flags & CF_FIXARGC) == 0) { if ((Flags & CF_FIXARGC) == 0) {
/* Pass arg count */ /* Pass the argument count */
ldyconst (argsize); ldyconst (ArgSize);
} }
AddCodeLine ("\tjsr\t_%s", lbl); AddCodeLine ("\tjsr\t_%s", Label);
oursp += argsize; /* callee pops args */ oursp += ArgSize; /* callee pops args */
} }
void g_callind (unsigned flags, unsigned argsize) void g_callind (unsigned Flags, unsigned ArgSize)
/* Call subroutine with address in AX */ /* Call subroutine with address in AX */
{ {
if ((flags & CF_FIXARGC) == 0) { if ((Flags & CF_FIXARGC) == 0) {
/* Pass arg count */ /* Pass arg count */
ldyconst (argsize); ldyconst (ArgSize);
} }
AddCodeLine ("\tjsr\tcallax"); /* do the call */ AddCodeLine ("\tjsr\tcallax"); /* do the call */
oursp += argsize; /* callee pops args */ oursp += ArgSize; /* callee pops args */
} }
void g_jump (unsigned label) void g_jump (unsigned Label)
/* Jump to specified internal label number */ /* Jump to specified internal label number */
{ {
AddCodeLine ("\tjmp\tL%04X", label); AddCodeLine ("\tjmp\tL%04X", Label);
} }
void g_switch (unsigned flags) void g_switch (unsigned Flags)
/* Output switch statement preample */ /* Output switch statement preamble */
{ {
switch (flags & CF_TYPE) { switch (Flags & CF_TYPE) {
case CF_CHAR: case CF_CHAR:
case CF_INT: case CF_INT:
@ -2510,7 +2555,7 @@ void g_switch (unsigned flags)
break; break;
default: default:
typeerror (flags); typeerror (Flags);
} }
} }

View File

@ -50,12 +50,14 @@
*/ */
#define CF_NONE 0x0000 /* No special flags */ #define CF_NONE 0x0000 /* No special flags */
#define CF_TYPE 0x000F /* Mask for operand type */ #define CF_TYPE 0x0007 /* Mask for operand type */
#define CF_CHAR 0x0003 /* Operation on characters */ #define CF_CHAR 0x0003 /* Operation on characters */
#define CF_INT 0x0001 /* Operation on ints */ #define CF_INT 0x0001 /* Operation on ints */
#define CF_PTR CF_INT /* Alias for readability */ #define CF_PTR CF_INT /* Alias for readability */
#define CF_LONG 0x0000 /* Operation on longs */ #define CF_LONG 0x0000 /* Operation on longs */
#define CF_NOKEEP 0x0008 /* Value may get destroyed when storing */
#define CF_UNSIGNED 0x0010 /* Value is unsigned */ #define CF_UNSIGNED 0x0010 /* Value is unsigned */
#define CF_CONST 0x0020 /* Constant value available */ #define CF_CONST 0x0020 /* Constant value available */
#define CF_CONSTADDR 0x0040 /* Constant address value available */ #define CF_CONSTADDR 0x0040 /* Constant address value available */
@ -273,7 +275,7 @@ void g_leavariadic (int Offs);
void g_putstatic (unsigned flags, unsigned long label, unsigned offs); void g_putstatic (unsigned flags, unsigned long label, unsigned offs);
/* Store the primary register into the specified static memory cell */ /* Store the primary register into the specified static memory cell */
void g_putlocal (unsigned flags, int offs); void g_putlocal (unsigned Flags, int Offs, long Val);
/* Put data into local object. */ /* Put data into local object. */
void g_putind (unsigned flags, unsigned offs); void g_putind (unsigned flags, unsigned offs);
@ -370,10 +372,18 @@ void g_cmp (unsigned flags, unsigned long val);
void g_test (unsigned flags); void g_test (unsigned flags);
void g_push (unsigned flags, unsigned long val); void g_push (unsigned flags, unsigned long val);
void g_swap (unsigned flags); void g_swap (unsigned flags);
void g_call (unsigned flags, char *lbl, unsigned argsize);
void g_callind (unsigned flags, unsigned argsize); void g_call (unsigned Flags, const char* Label, unsigned ArgSize);
void g_jump (unsigned label); /* Call the specified subroutine name */
void g_switch (unsigned flags);
void g_callind (unsigned Flags, unsigned ArgSize);
/* Call subroutine with address in AX */
void g_jump (unsigned Label);
/* Jump to specified internal label number */
void g_switch (unsigned Flags);
/* Output switch statement preamble */
void g_case (unsigned flags, unsigned label, unsigned long val); void g_case (unsigned flags, unsigned label, unsigned long val);
/* Create table code for one case selector */ /* Create table code for one case selector */

View File

@ -173,7 +173,7 @@ type* GetImplicitFuncType (void)
type* T = TypeAlloc (1 + DECODE_SIZE + 2); type* T = TypeAlloc (1 + DECODE_SIZE + 2);
/* Prepare the function descriptor */ /* Prepare the function descriptor */
F->Flags = FD_IMPLICIT | FD_EMPTY | FD_ELLIPSIS; F->Flags = FD_IMPLICIT | FD_EMPTY | FD_VARIADIC;
F->SymTab = &EmptySymTab; F->SymTab = &EmptySymTab;
F->TagTab = &EmptySymTab; F->TagTab = &EmptySymTab;
@ -476,7 +476,7 @@ unsigned TypeOf (const type* T)
case T_FUNC: case T_FUNC:
F = (FuncDesc*) DecodePtr (T+1); F = (FuncDesc*) DecodePtr (T+1);
return (F->Flags & FD_ELLIPSIS)? 0 : CF_FIXARGC; return (F->Flags & FD_VARIADIC)? 0 : CF_FIXARGC;
case T_STRUCT: case T_STRUCT:
case T_UNION: case T_UNION:
@ -654,7 +654,7 @@ int IsVariadicFunc (const type* T)
FuncDesc* F; FuncDesc* F;
CHECK (IsTypeFunc (T)); CHECK (IsTypeFunc (T));
F = (FuncDesc*) DecodePtr (T+1); F = (FuncDesc*) DecodePtr (T+1);
return (F->Flags & FD_ELLIPSIS) != 0; return (F->Flags & FD_VARIADIC) != 0;
} }

View File

@ -626,7 +626,7 @@ static void ParseAnsiParamList (FuncDesc* F)
/* Allow an ellipsis as last parameter */ /* Allow an ellipsis as last parameter */
if (curtok == TOK_ELLIPSIS) { if (curtok == TOK_ELLIPSIS) {
NextToken (); NextToken ();
F->Flags |= FD_ELLIPSIS; F->Flags |= FD_VARIADIC;
break; break;
} }
@ -708,14 +708,14 @@ static FuncDesc* ParseFuncDecl (void)
/* Check for several special parameter lists */ /* Check for several special parameter lists */
if (curtok == TOK_RPAREN) { if (curtok == TOK_RPAREN) {
/* Parameter list is empty */ /* Parameter list is empty */
F->Flags |= (FD_EMPTY | FD_ELLIPSIS); F->Flags |= (FD_EMPTY | FD_VARIADIC);
} else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) { } else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) {
/* Parameter list declared as void */ /* Parameter list declared as void */
NextToken (); NextToken ();
F->Flags |= FD_VOID_PARAM; F->Flags |= FD_VOID_PARAM;
} else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) { } else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) {
/* Old style (K&R) function. Assume variable param list. */ /* Old style (K&R) function. Assume variable param list. */
F->Flags |= (FD_OLDSTYLE | FD_ELLIPSIS); F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
} }
/* Parse params */ /* Parse params */
@ -730,7 +730,7 @@ static FuncDesc* ParseFuncDecl (void)
/* Assign offsets. If the function has a variable parameter list, /* Assign offsets. If the function has a variable parameter list,
* there's one additional byte (the arg size). * there's one additional byte (the arg size).
*/ */
Offs = (F->Flags & FD_ELLIPSIS)? 1 : 0; Offs = (F->Flags & FD_VARIADIC)? 1 : 0;
Sym = GetSymTab()->SymTail; Sym = GetSymTab()->SymTail;
while (Sym) { while (Sym) {
unsigned Size = SizeOf (Sym->Type); unsigned Size = SizeOf (Sym->Type);

View File

@ -510,54 +510,70 @@ void exprhs (unsigned flags, int k, struct expent *lval)
} }
static void callfunction (struct expent* lval)
/* Perform a function call. Called from hie11, this routine will static unsigned FunctionParamList (FuncDesc* Func)
* either call the named function, or if the supplied ptr is zero, /* Parse a function parameter list and pass the parameters to the called
* will call the contents of P. * function. Depending on several criteria this may be done by just pushing
* each parameter separately, or creating the parameter frame once and then
* storing into this frame.
* The function returns the size of the parameters pushed.
*/ */
{ {
struct expent lval2; struct expent lval;
FuncDesc* Func; /* Function descriptor */
int Ellipsis; /* True if we have an open param list */
SymEntry* Param; /* Current formal parameter */
unsigned ParamCount; /* Actual parameter count */
unsigned ParamSize; /* Number of parameter bytes */
unsigned Flags;
unsigned CFlags;
CodeMark Mark;
/* Initialize variables */
SymEntry* Param = 0; /* Keep gcc silent */
unsigned ParamSize = 0; /* Size of parameters pushed */
unsigned ParamCount = 0; /* Number of parameters pushed */
unsigned FrameSize = 0; /* Size of parameter frame */
unsigned FrameParams = 0; /* Number of params in frame */
int FrameOffs = 0; /* Offset into parameter frame */
int Ellipsis = 0; /* Function is variadic */
/* Get a pointer to the function descriptor from the type string */ /* As an optimization, we may allocate the complete parameter frame at
Func = GetFuncDesc (lval->e_tptr); * once instead of pushing each parameter as it comes. We may do that,
* if...
/* Initialize vars to keep gcc silent */ *
Param = 0; * - optimizations that increase code size are enabled (allocating the
Mark = 0; * stack frame at once gives usually larger code).
* - we have more than one parameter to push (don't count the last param
/* Check if this is a function pointer. If so, save it. If not, check for * for __fastcall__ functions).
* special known library functions that may be inlined.
*/ */
if (lval->e_flags & E_MEXPR) { if (Optimize && !FavourSize) {
/* Function pointer is in primary register, save it */
Mark = GetCodePos (); /* Calculate the number and size of the parameters */
g_save (CF_PTR); FrameParams = Func->ParamCount;
} else if (InlineStdFuncs && IsStdFunc ((const char*) lval->e_name)) { FrameSize = Func->ParamSize;
/* Inline this function */ if (FrameParams > 0 && (Func->Flags & FD_FASTCALL) != 0) {
HandleStdFunc (lval); /* Last parameter is not pushed */
return; const SymEntry* LastParam = Func->SymTab->SymTail;
FrameSize -= SizeOf (LastParam->Type);
--FrameParams;
}
/* Do we have more than one parameter in the frame? */
if (FrameParams > 1) {
/* Okeydokey, setup the frame */
FrameOffs = oursp;
g_space (FrameSize);
oursp -= FrameSize;
} else {
/* Don't use a preallocated frame */
FrameSize = 0;
}
} }
/* Parse the actual parameter list */ /* Parse the actual parameter list */
ParamSize = 0;
ParamCount = 0;
Ellipsis = 0;
while (curtok != TOK_RPAREN) { while (curtok != TOK_RPAREN) {
unsigned CFlags;
unsigned Flags;
/* Add a hint for the optimizer */ /* Add a hint for the optimizer */
AddCodeHint ("param:start"); AddCodeHint ("param:start");
/* Count arguments */ /* Count arguments */
++ParamCount; ++ParamCount;
/* Fetch the pointer to the next argument, check for too many args */ /* Fetch the pointer to the next argument, check for too many args */
if (ParamCount <= Func->ParamCount) { if (ParamCount <= Func->ParamCount) {
@ -579,7 +595,7 @@ static void callfunction (struct expent* lval)
} }
} else if (!Ellipsis) { } else if (!Ellipsis) {
/* Too many arguments. Do we have an open param list? */ /* Too many arguments. Do we have an open param list? */
if ((Func->Flags & FD_ELLIPSIS) == 0) { if ((Func->Flags & FD_VARIADIC) == 0) {
/* End of param list reached, no ellipsis */ /* End of param list reached, no ellipsis */
Error ("Too many arguments in function call"); Error ("Too many arguments in function call");
} }
@ -596,8 +612,8 @@ static void callfunction (struct expent* lval)
if (!Ellipsis && SizeOf (Param->Type) == 1) { if (!Ellipsis && SizeOf (Param->Type) == 1) {
CFlags = CF_FORCECHAR; CFlags = CF_FORCECHAR;
} }
Flags = 0; Flags = CF_NONE;
if (evalexpr (CFlags, hie1, &lval2) == 0) { if (evalexpr (CFlags, hie1, &lval) == 0) {
/* A constant value */ /* A constant value */
Flags |= CF_CONST; Flags |= CF_CONST;
} }
@ -607,14 +623,14 @@ static void callfunction (struct expent* lval)
*/ */
if (!Ellipsis) { if (!Ellipsis) {
/* Promote the argument if needed */ /* Promote the argument if needed */
assignadjust (Param->Type, &lval2); assignadjust (Param->Type, &lval);
/* If we have a prototype, chars may be pushed as chars */ /* If we have a prototype, chars may be pushed as chars */
Flags |= CF_FORCECHAR; Flags |= CF_FORCECHAR;
} }
/* Use the type of the argument for the push */ /* Use the type of the argument for the push */
Flags |= TypeOf (lval2.e_tptr); Flags |= TypeOf (lval.e_tptr);
/* If this is a fastcall function, don't push the last argument */ /* If this is a fastcall function, don't push the last argument */
if (ParamCount == Func->ParamCount && (Func->Flags & FD_FASTCALL) != 0) { if (ParamCount == Func->ParamCount && (Func->Flags & FD_FASTCALL) != 0) {
@ -623,12 +639,24 @@ static void callfunction (struct expent* lval)
* the primary. * the primary.
*/ */
if (Flags & CF_CONST) { if (Flags & CF_CONST) {
exprhs (CF_FORCECHAR, 0, &lval2); exprhs (CF_FORCECHAR, 0, &lval);
} }
} else { } else {
/* Push the argument, count the argument size */ unsigned ArgSize = sizeofarg (Flags);
g_push (Flags, lval2.e_const); if (FrameSize > 0) {
ParamSize += sizeofarg (Flags); /* We have the space already allocated, store in the frame */
CHECK (FrameSize >= ArgSize);
FrameSize -= ArgSize;
FrameOffs -= ArgSize;
/* Store */
g_putlocal (Flags | CF_NOKEEP, FrameOffs, lval.e_const);
} else {
/* Push the argument */
g_push (Flags, lval.e_const);
}
/* Calculate total parameter size */
ParamSize += ArgSize;
} }
/* Add an optimizer hint */ /* Add an optimizer hint */
@ -641,14 +669,52 @@ static void callfunction (struct expent* lval)
NextToken (); NextToken ();
} }
/* We need the closing bracket here */
ConsumeRParen ();
/* Check if we had enough parameters */ /* Check if we had enough parameters */
if (ParamCount < Func->ParamCount) { if (ParamCount < Func->ParamCount) {
Error ("Too few arguments in function call"); Error ("Too few arguments in function call");
} }
/* Return the size of all parameters pushed onto the stack */
return ParamSize;
}
static void CallFunction (struct expent* lval)
/* Perform a function call. Called from hie11, this routine will
* either call the named function, or the function pointer in a/x.
*/
{
FuncDesc* Func; /* Function descriptor */
unsigned ParamSize; /* Number of parameter bytes */
CodeMark Mark;
/* Get a pointer to the function descriptor from the type string */
Func = GetFuncDesc (lval->e_tptr);
/* Initialize vars to keep gcc silent */
Mark = 0;
/* Check if this is a function pointer. If so, save it. If not, check for
* special known library functions that may be inlined.
*/
if (lval->e_flags & E_MEXPR) {
/* Function pointer is in primary register, save it */
Mark = GetCodePos ();
g_save (CF_PTR);
} else if (InlineStdFuncs && IsStdFunc ((const char*) lval->e_name)) {
/* Inline this function */
HandleStdFunc (lval);
return;
}
/* Parse the parameter list */
ParamSize = FunctionParamList (Func);
/* We need the closing bracket here */
ConsumeRParen ();
/* */ /* */
if (lval->e_flags & E_MEXPR) { if (lval->e_flags & E_MEXPR) {
/* Function called via pointer: Restore it and call function */ /* Function called via pointer: Restore it and call function */
@ -660,7 +726,7 @@ static void callfunction (struct expent* lval)
} }
g_callind (TypeOf (lval->e_tptr), ParamSize); g_callind (TypeOf (lval->e_tptr), ParamSize);
} else { } else {
g_call (TypeOf (lval->e_tptr), (char*) lval->e_name, ParamSize); g_call (TypeOf (lval->e_tptr), (const char*) lval->e_name, ParamSize);
} }
} }
@ -1205,7 +1271,7 @@ static int hie11 (struct expent *lval)
++lval->e_tptr; /* Skip T_PTR */ ++lval->e_tptr; /* Skip T_PTR */
lval->e_flags |= E_MEXPR; lval->e_flags |= E_MEXPR;
} }
callfunction (lval); CallFunction (lval);
lval->e_flags = E_MEXPR; lval->e_flags = E_MEXPR;
lval->e_tptr += DECODE_SIZE + 1; /* Set to result */ lval->e_tptr += DECODE_SIZE + 1; /* Set to result */
} else { } else {
@ -1255,7 +1321,7 @@ static void store (struct expent* lval)
g_putstatic (flags, lval->e_name, lval->e_const); g_putstatic (flags, lval->e_name, lval->e_const);
} else if (f & E_MLOCAL) { } else if (f & E_MLOCAL) {
g_putlocal (flags, lval->e_const); g_putlocal (flags, lval->e_const, 0);
} else if (f == E_MEOFFS) { } else if (f == E_MEOFFS) {
g_putind (flags, lval->e_const); g_putind (flags, lval->e_const);
} else if (f != E_MREG) { } else if (f != E_MREG) {

View File

@ -48,7 +48,7 @@
#define FD_IMPLICIT 0x0001U /* Implicitly declared function */ #define FD_IMPLICIT 0x0001U /* Implicitly declared function */
#define FD_EMPTY 0x0002U /* Function with empty param list */ #define FD_EMPTY 0x0002U /* Function with empty param list */
#define FD_VOID_PARAM 0x0004U /* Function with a void param list */ #define FD_VOID_PARAM 0x0004U /* Function with a void param list */
#define FD_ELLIPSIS 0x0008U /* Function with variable param list */ #define FD_VARIADIC 0x0008U /* Function with variable param list */
#define FD_FASTCALL 0x0010U /* __fastcall__ function */ #define FD_FASTCALL 0x0010U /* __fastcall__ function */
#define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */ #define FD_OLDSTYLE 0x0020U /* Old style (K&R) function */
#define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ #define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */

View File

@ -151,7 +151,7 @@ int HasVoidReturn (const Function* F)
int IsVariadic (const Function* F) int IsVariadic (const Function* F)
/* Return true if this is a variadic function */ /* Return true if this is a variadic function */
{ {
return (F->Desc->Flags & FD_ELLIPSIS) != 0; return (F->Desc->Flags & FD_VARIADIC) != 0;
} }
@ -232,7 +232,7 @@ void NewFunc (SymEntry* Func)
* or not). * or not).
*/ */
AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize); AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
if (D->Flags & FD_ELLIPSIS) { if (D->Flags & FD_VARIADIC) {
/* Variadic function. The variable must be const. */ /* Variadic function. The variable must be const. */
static const type T [] = { T_UCHAR | T_QUAL_CONST, T_END }; static const type T [] = { T_UCHAR | T_QUAL_CONST, T_END };
AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0); AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
@ -263,7 +263,7 @@ void NewFunc (SymEntry* Func)
unsigned Flags; unsigned Flags;
/* Fastcall functions may never have an ellipsis or the compiler is buggy */ /* Fastcall functions may never have an ellipsis or the compiler is buggy */
CHECK ((D->Flags & FD_ELLIPSIS) == 0); CHECK ((D->Flags & FD_VARIADIC) == 0);
/* Get a pointer to the last parameter entry */ /* Get a pointer to the last parameter entry */
LastParam = D->SymTab->SymTail; LastParam = D->SymTab->SymTail;

View File

@ -589,7 +589,7 @@ static ExprNode* DoFunctionCall (ExprNode* Left)
} }
} else if (!Ellipsis) { } else if (!Ellipsis) {
/* Too many arguments. Do we have an open param list? */ /* Too many arguments. Do we have an open param list? */
if ((Func->Flags & FD_ELLIPSIS) == 0) { if ((Func->Flags & FD_VARIADIC) == 0) {
/* End of param list reached, no ellipsis */ /* End of param list reached, no ellipsis */
Error ("Too many function arguments"); Error ("Too many function arguments");
} }