]> git.sur5r.net Git - cc65/commitdiff
Inline parameter frame building
authorcuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 24 Mar 2001 13:00:16 +0000 (13:00 +0000)
committercuz <cuz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 24 Mar 2001 13:00:16 +0000 (13:00 +0000)
git-svn-id: svn://svn.cc65.org/cc65/trunk@661 b7a2c559-68d2-44c3-8de9-860c34a00d81

src/cc65/codegen.c
src/cc65/codegen.h
src/cc65/datatype.c
src/cc65/declare.c
src/cc65/expr.c
src/cc65/funcdesc.h
src/cc65/function.c
src/cc65/parser.c

index 416be40da7fc1d02901d229e2e0e1999ac39333a..97c5c1fce483fc6bc3788a50eeaf7ff8f5ec5d8c 100644 (file)
@@ -652,63 +652,63 @@ void g_getimmed (unsigned flags, unsigned long val, unsigned offs)
 {
     if ((flags & CF_CONST) != 0) {
 
-       /* Numeric constant */
-       switch (flags & CF_TYPE) {
+       /* Numeric constant */
+       switch (flags & CF_TYPE) {
 
-           case CF_CHAR:
-               if ((flags & CF_FORCECHAR) != 0) {
-                   ldaconst (val);
-                   break;
-               }
-               /* FALL THROUGH */
-           case CF_INT:
-               ldxconst ((val >> 8) & 0xFF);
-               ldaconst (val & 0xFF);
-               break;
+           case CF_CHAR:
+               if ((flags & CF_FORCECHAR) != 0) {
+                   ldaconst (val);
+                   break;
+               }
+               /* FALL THROUGH */
+           case CF_INT:
+               ldxconst ((val >> 8) & 0xFF);
+               ldaconst (val & 0xFF);
+               break;
 
-           case CF_LONG:
-               if (val < 0x100) {
-                   AddCodeLine ("\tldx\t#$00");
-                   AddCodeLine ("\tstx\tsreg+1");
-                   AddCodeLine ("\tstx\tsreg");
-                   AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
-               } else if ((val & 0xFFFF00FF) == 0) {
-                   AddCodeLine ("\tlda\t#$00");
-                   AddCodeLine ("\tsta\tsreg+1");
-                   AddCodeLine ("\tsta\tsreg");
-                   AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
-               } else if ((val & 0xFFFF0000) == 0 && FavourSize == 0) {
-                   AddCodeLine ("\tlda\t#$00");
-                   AddCodeLine ("\tsta\tsreg+1");
-                   AddCodeLine ("\tsta\tsreg");
-                   AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
-                   AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
-               } else if ((val & 0xFFFFFF00) == 0xFFFFFF00) {
-                   AddCodeLine ("\tldx\t#$FF");
-                   AddCodeLine ("\tstx\tsreg+1");
-                   AddCodeLine ("\tstx\tsreg");
-                   if ((val & 0xFF) == 0xFF) {
-                       AddCodeLine ("\ttxa");
-                   } else {
-                       AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
-                   }
-               } else if ((val & 0xFFFF00FF) == 0xFFFF00FF) {
-                   AddCodeLine ("\tlda\t#$FF");
-                   AddCodeLine ("\tsta\tsreg+1");
-                   AddCodeLine ("\tsta\tsreg");
-                   AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
-               } else {
-                   /* Call a subroutine that will load following value */
-                   AddCodeLine ("\tjsr\tldeax");
-                   AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF);
-               }
-               break;
+           case CF_LONG:
+               if (val < 0x100) {
+                   AddCodeLine ("\tldx\t#$00");
+                   AddCodeLine ("\tstx\tsreg+1");
+                   AddCodeLine ("\tstx\tsreg");
+                   AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
+               } else if ((val & 0xFFFF00FF) == 0) {
+                   AddCodeLine ("\tlda\t#$00");
+                   AddCodeLine ("\tsta\tsreg+1");
+                   AddCodeLine ("\tsta\tsreg");
+                   AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
+               } else if ((val & 0xFFFF0000) == 0 && FavourSize == 0) {
+                   AddCodeLine ("\tlda\t#$00");
+                   AddCodeLine ("\tsta\tsreg+1");
+                   AddCodeLine ("\tsta\tsreg");
+                   AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
+                   AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
+               } else if ((val & 0xFFFFFF00) == 0xFFFFFF00) {
+                   AddCodeLine ("\tldx\t#$FF");
+                   AddCodeLine ("\tstx\tsreg+1");
+                   AddCodeLine ("\tstx\tsreg");
+                   if ((val & 0xFF) == 0xFF) {
+                       AddCodeLine ("\ttxa");
+                   } else {
+                       AddCodeLine ("\tlda\t#$%02X", (unsigned char) val);
+                   }
+               } else if ((val & 0xFFFF00FF) == 0xFFFF00FF) {
+                   AddCodeLine ("\tlda\t#$FF");
+                   AddCodeLine ("\tsta\tsreg+1");
+                   AddCodeLine ("\tsta\tsreg");
+                   AddCodeLine ("\tldx\t#$%02X", (unsigned char) (val >> 8));
+               } else {
+                   /* Call a subroutine that will load following value */
+                   AddCodeLine ("\tjsr\tldeax");
+                   AddCodeLine ("\t.dword\t$%08lX", val & 0xFFFFFFFF);
+               }
+               break;
 
-           default:
-               typeerror (flags);
-               break;
+           default:
+               typeerror (flags);
+               break;
 
-       }
+       }
 
     } 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. */
 {
-    offs -= oursp;
-    CheckLocalOffs (offs);
-    switch (flags & CF_TYPE) {
+    Offs -= oursp;
+    CheckLocalOffs (Offs);
+    switch (Flags & CF_TYPE) {
 
        case CF_CHAR:
-           if (CPU == CPU_65C02 && offs == 0) {
-               AddCodeLine ("\tsta\t(sp)");
-           } else {
-               ldyconst (offs);
-               AddCodeLine ("\tsta\t(sp),y");
+           if (Flags & CF_CONST) {
+               AddCodeLine ("\tlda\t#$%02X", (unsigned char) Val);
            }
+           if (CPU == CPU_65C02 && Offs == 0) {
+               AddCodeLine ("\tsta\t(sp)");
+           } else {
+               ldyconst (Offs);
+               AddCodeLine ("\tsta\t(sp),y");
+           }
            break;
 
        case CF_INT:
-           if (offs) {
-               ldyconst (offs);
-               AddCodeLine ("\tjsr\tstaxysp");
-           } else {
-               AddCodeLine ("\tjsr\tstax0sp");
-           }
+           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:
-           if (offs) {
-               ldyconst (offs);
+           if (Flags & CF_CONST) {
+               g_getimmed (Flags, Val, 0);
+           }
+           if (Offs) {
+               ldyconst (Offs);
                AddCodeLine ("\tjsr\tsteaxysp");
            } else {
                AddCodeLine ("\tjsr\tsteax0sp");
@@ -1119,7 +1164,7 @@ void g_putlocal (unsigned flags, int offs)
            break;
 
                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 */
 {
-    if ((flags & CF_FIXARGC) == 0) {
-       /* Pass arg count */
-       ldyconst (argsize);
+    if ((Flags & CF_FIXARGC) == 0) {
+       /* Pass the argument count */
+       ldyconst (ArgSize);
     }
-    AddCodeLine ("\tjsr\t_%s", lbl);
-    oursp += argsize;                  /* callee pops args */
+    AddCodeLine ("\tjsr\t_%s", Label);
+    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 */
 {
-    if ((flags & CF_FIXARGC) == 0) {
+    if ((Flags & CF_FIXARGC) == 0) {
        /* Pass arg count */
-       ldyconst (argsize);
+       ldyconst (ArgSize);
     }
     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 */
 {
-    AddCodeLine ("\tjmp\tL%04X", label);
+    AddCodeLine ("\tjmp\tL%04X", Label);
 }
 
 
 
-void g_switch (unsigned flags)
-/* Output switch statement preample */
+void g_switch (unsigned Flags)
+/* Output switch statement preamble */
 {
-    switch (flags & CF_TYPE) {
+    switch (Flags & CF_TYPE) {
 
        case CF_CHAR:
        case CF_INT:
@@ -2510,7 +2555,7 @@ void g_switch (unsigned flags)
            break;
 
        default:
-           typeerror (flags);
+           typeerror (Flags);
 
     }
 }
index 94b19c1c921635f5ffef1e2c3f526b6641d6b5c6..be2a5742fa00ae5dcfd4d3aec7dbacd93f136218 100644 (file)
  */
 #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_INT         0x0001  /* Operation on ints */
 #define CF_PTR         CF_INT  /* Alias for readability */
 #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_CONST       0x0020  /* Constant 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);
 /* 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. */
 
 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_push (unsigned flags, unsigned long val);
 void g_swap (unsigned flags);
-void g_call (unsigned flags, char *lbl, unsigned argsize);
-void g_callind (unsigned flags, unsigned argsize);
-void g_jump (unsigned label);
-void g_switch (unsigned flags);
+
+void g_call (unsigned Flags, const char* Label, unsigned ArgSize);
+/* Call the specified subroutine name */
+
+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);
 /* Create table code for one case selector */
index 6e0ac1d8549c007d25222777dce7b94f416a6088..e50f56ffbd32837f30d33732a9938fa4137d4620 100644 (file)
@@ -173,7 +173,7 @@ type* GetImplicitFuncType (void)
     type* T = TypeAlloc (1 + DECODE_SIZE + 2);
 
     /* Prepare the function descriptor */
-    F->Flags  = FD_IMPLICIT | FD_EMPTY | FD_ELLIPSIS;
+    F->Flags  = FD_IMPLICIT | FD_EMPTY | FD_VARIADIC;
     F->SymTab = &EmptySymTab;
     F->TagTab = &EmptySymTab;
 
@@ -476,7 +476,7 @@ unsigned TypeOf (const type* T)
 
         case T_FUNC:
            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_UNION:
@@ -654,7 +654,7 @@ int IsVariadicFunc (const type* T)
     FuncDesc* F;
     CHECK (IsTypeFunc (T));
     F = (FuncDesc*) DecodePtr (T+1);
-    return (F->Flags & FD_ELLIPSIS) != 0;
+    return (F->Flags & FD_VARIADIC) != 0;
 }
 
 
index c5bf0977712985af4f57d4d11517c17f919a0545..b37d9088b9dea9fc9db4551c9fc88530fe025089 100644 (file)
@@ -626,7 +626,7 @@ static void ParseAnsiParamList (FuncDesc* F)
        /* Allow an ellipsis as last parameter */
        if (curtok == TOK_ELLIPSIS) {
            NextToken ();
-           F->Flags |= FD_ELLIPSIS;
+           F->Flags |= FD_VARIADIC;
            break;
        }
 
@@ -708,14 +708,14 @@ static FuncDesc* ParseFuncDecl (void)
     /* Check for several special parameter lists */
     if (curtok == TOK_RPAREN) {
        /* Parameter list is empty */
-       F->Flags |= (FD_EMPTY | FD_ELLIPSIS);
+       F->Flags |= (FD_EMPTY | FD_VARIADIC);
     } else if (curtok == TOK_VOID && nxttok == TOK_RPAREN) {
        /* Parameter list declared as void */
        NextToken ();
        F->Flags |= FD_VOID_PARAM;
     } else if (curtok == TOK_IDENT && (nxttok == TOK_COMMA || nxttok == TOK_RPAREN)) {
        /* Old style (K&R) function. Assume variable param list. */
-               F->Flags |= (FD_OLDSTYLE | FD_ELLIPSIS);
+               F->Flags |= (FD_OLDSTYLE | FD_VARIADIC);
     }
 
     /* Parse params */
@@ -730,7 +730,7 @@ static FuncDesc* ParseFuncDecl (void)
     /* Assign offsets. If the function has a variable parameter list,
      * 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;
     while (Sym) {
        unsigned Size = SizeOf (Sym->Type);
index 11c43b9730a2f0095febc67d4a02de3282305243..0cd605efce7732ec2e49ff78d7d0410eff42114a 100644 (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
- * either call the named function, or if the supplied ptr is zero,
- * will call the contents of P.
+
+static unsigned FunctionParamList (FuncDesc* Func)
+/* Parse a function parameter list and pass the parameters to the called
+ * 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;
-    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;
-
-
-    /* Get a pointer to the function descriptor from the type string */
-    Func = GetFuncDesc (lval->e_tptr);
-
-    /* Initialize vars to keep gcc silent */
-    Param = 0;
-    Mark  = 0;
+    struct expent lval;
 
-    /* Check if this is a function pointer. If so, save it. If not, check for
-     * special known library functions that may be inlined.
+    /* 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 */
+
+    /* As an optimization, we may allocate the complete parameter frame at
+     * once instead of pushing each parameter as it comes. We may do that,
+     * if...
+     *
+     *  - optimizations that increase code size are enabled (allocating the
+     *    stack frame at once gives usually larger code).
+     *  - we have more than one parameter to push (don't count the last param
+     *    for __fastcall__ functions).
      */
-    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;
+    if (Optimize && !FavourSize) {
+
+       /* Calculate the number and size of the parameters */
+       FrameParams = Func->ParamCount;
+       FrameSize   = Func->ParamSize;
+       if (FrameParams > 0 && (Func->Flags & FD_FASTCALL) != 0) {
+           /* Last parameter is not pushed */
+           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 */
-    ParamSize  = 0;
-    ParamCount = 0;
-    Ellipsis   = 0;
     while (curtok != TOK_RPAREN) {
 
+       unsigned CFlags;
+       unsigned Flags;
+
        /* Add a hint for the optimizer */
        AddCodeHint ("param:start");
 
-       /* Count arguments */
-       ++ParamCount;
+       /* Count arguments */
+       ++ParamCount;
 
        /* Fetch the pointer to the next argument, check for too many args */
        if (ParamCount <= Func->ParamCount) {
@@ -579,7 +595,7 @@ static void callfunction (struct expent* lval)
            }
        } else if (!Ellipsis) {
            /* 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 */
                Error ("Too many arguments in function call");
            }
@@ -596,8 +612,8 @@ static void callfunction (struct expent* lval)
                if (!Ellipsis && SizeOf (Param->Type) == 1) {
            CFlags = CF_FORCECHAR;
        }
-       Flags = 0;
-               if (evalexpr (CFlags, hie1, &lval2) == 0) {
+       Flags = CF_NONE;
+               if (evalexpr (CFlags, hie1, &lval) == 0) {
                    /* A constant value */
            Flags |= CF_CONST;
        }
@@ -607,14 +623,14 @@ static void callfunction (struct expent* lval)
         */
                if (!Ellipsis) {
            /* Promote the argument if needed */
-                   assignadjust (Param->Type, &lval2);
+                   assignadjust (Param->Type, &lval);
 
            /* If we have a prototype, chars may be pushed as chars */
            Flags |= CF_FORCECHAR;
                }
 
        /* 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 (ParamCount == Func->ParamCount && (Func->Flags & FD_FASTCALL) != 0) {
@@ -623,12 +639,24 @@ static void callfunction (struct expent* lval)
             * the primary.
             */
            if (Flags & CF_CONST) {
-               exprhs (CF_FORCECHAR, 0, &lval2);
+               exprhs (CF_FORCECHAR, 0, &lval);
            }
        } else {
-           /* Push the argument, count the argument size */
-           g_push (Flags, lval2.e_const);
-           ParamSize += sizeofarg (Flags);
+           unsigned ArgSize = sizeofarg (Flags);
+           if (FrameSize > 0) {
+               /* 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 */
@@ -641,14 +669,52 @@ static void callfunction (struct expent* lval)
        NextToken ();
     }
 
-    /* We need the closing bracket here */
-    ConsumeRParen ();
-
     /* Check if we had enough parameters */
     if (ParamCount < Func->ParamCount) {
        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) {
        /* 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);
     } 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_flags |= E_MEXPR;
                }
-               callfunction (lval);
+               CallFunction (lval);
                lval->e_flags = E_MEXPR;
                lval->e_tptr += DECODE_SIZE + 1;        /* Set to result */
            } else {
@@ -1255,7 +1321,7 @@ static void store (struct expent* lval)
                g_putstatic (flags, lval->e_name, lval->e_const);
 
     } else if (f & E_MLOCAL) {
-               g_putlocal (flags, lval->e_const);
+               g_putlocal (flags, lval->e_const, 0);
     } else if (f == E_MEOFFS) {
        g_putind (flags, lval->e_const);
     } else if (f != E_MREG) {
index c18eb546c60215d8521a1ab74fb909aa802866b2..eb62d3d48e788fe16bb18028ced90d5be8a7f7e9 100644 (file)
@@ -48,7 +48,7 @@
 #define FD_IMPLICIT            0x0001U /* Implicitly declared function      */
 #define FD_EMPTY               0x0002U /* Function with empty 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_OLDSTYLE            0x0020U /* Old style (K&R) function          */
 #define FD_UNNAMED_PARAMS      0x0040U /* Function has unnamed params       */
index 8b4e92c741d4a0568d1a74ddc8233d8abb2abc4c..d9efc9a7700ab3dbd932d3ac53c0eddb7e40c48b 100644 (file)
@@ -151,7 +151,7 @@ int HasVoidReturn (const Function* F)
 int IsVariadic (const Function* F)
 /* Return true if this is a variadic function */
 {
-    return (F->Desc->Flags & FD_ELLIPSIS) != 0;
+    return (F->Desc->Flags & FD_VARIADIC) != 0;
 }
 
 
@@ -231,8 +231,8 @@ void NewFunc (SymEntry* Func)
      * The latter is different depending on the type of the function (variadic
      * or not).
      */
-    AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);    
-    if (D->Flags & FD_ELLIPSIS) {
+    AddConstSym ("__fixargs__", type_uint, SC_DEF | SC_CONST, D->ParamSize);
+    if (D->Flags & FD_VARIADIC) {
        /* Variadic function. The variable must be const. */
        static const type T [] = { T_UCHAR | T_QUAL_CONST, T_END };
        AddLocalSym ("__argsize__", T, SC_DEF | SC_REF | SC_AUTO, 0);
@@ -263,8 +263,8 @@ void NewFunc (SymEntry* Func)
        unsigned Flags;
 
        /* 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 */
        LastParam = D->SymTab->SymTail;
 
index b86cafd9ca0f2ee2cc11fe52b3912c3d7acf4312..42f7324772bd3a4b6032cc0676d9659f66e100c7 100644 (file)
@@ -589,7 +589,7 @@ static ExprNode* DoFunctionCall (ExprNode* Left)
            }
        } else if (!Ellipsis) {
            /* 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 */
                Error ("Too many function arguments");
            }