]> git.sur5r.net Git - cc65/blobdiff - src/cc65/function.c
Improved optimizations
[cc65] / src / cc65 / function.c
index edf795b8d6bb514bf314b995d8fdee5859f02597..c30e682a63eb17dd51ce5ade0a459844e5ed207b 100644 (file)
@@ -6,9 +6,9 @@
 /*                                                                           */
 /*                                                                           */
 /*                                                                           */
-/* (C) 2000-2002 Ullrich von Bassewitz                                       */
-/*               Wacholderweg 14                                             */
-/*               D-70597 Stuttgart                                           */
+/* (C) 2000-2003 Ullrich von Bassewitz                                       */
+/*               Römerstrasse 52                                             */
+/*               D-70794 Filderstadt                                         */
 /* EMail:        uz@cc65.org                                                 */
 /*                                                                           */
 /*                                                                           */
@@ -60,9 +60,6 @@
 
 
 
-/* Maximum register variable size */
-#define MAX_REG_SPACE   6
-
 /* Structure that holds all data needed for function activation */
 struct Function {
     struct SymEntry*           FuncEntry;      /* Symbol table entry */
@@ -98,7 +95,7 @@ static Function* NewFunction (struct SymEntry* Sym)
     F->Reserved          = 0;
     F->RetLab    = GetLocalLabel ();
     F->TopLevelSP = 0;
-    F->RegOffs    = MAX_REG_SPACE;
+    F->RegOffs    = RegisterSpace;
 
     /* Return the new structure */
     return F;
@@ -260,7 +257,7 @@ static void F_RestoreRegVars (Function* F)
     const SymEntry* Sym;
 
     /* If we don't have register variables in this function, bail out early */
-    if (F->RegOffs == MAX_REG_SPACE) {
+    if (F->RegOffs == RegisterSpace) {
                return;
     }
 
@@ -337,7 +334,6 @@ void NewFunc (SymEntry* Func)
 /* Parse argument declarations and function body. */
 {
     int HadReturn;
-    SymEntry* LastParam;
     SymEntry* Param;
 
     /* Get the function descriptor from the function entry */
@@ -349,9 +345,6 @@ void NewFunc (SymEntry* Func)
     /* Reenter the lexical level */
     ReenterFunctionLevel (D);
 
-    /* Before adding more symbols, remember the last parameter for later */
-    LastParam = D->SymTab->SymTail;
-
     /* Declare two special functions symbols: __fixargs__ and __argsize__.
      * The latter is different depending on the type of the function (variadic
      * or not).
@@ -372,6 +365,22 @@ void NewFunc (SymEntry* Func)
     /* Allocate code and data segments for this function */
     Func->V.F.Seg = PushSegments (Func);
 
+    /* Special handling for main() */
+    if (strcmp (Func->Name, "main") == 0) {
+        /* Main cannot be a fastcall function */
+        if (IsFastCallFunc (Func->Type)) {
+            Error ("`main' cannot be declared as __fastcall__");
+        }
+
+        /* If main() takes parameters, generate a forced import to a function
+         * that will setup these parameters. This way, programs that do not
+         * need the additional code will not get it.
+         */
+        if (D->ParamCount > 0 || (D->Flags & FD_VARIADIC) != 0) {
+            g_importmainargs ();
+        }
+    }
+
     /* If this is a fastcall function, push the last parameter onto the stack */
     if (IsFastCallFunc (Func->Type) && D->ParamCount > 0) {
 
@@ -381,11 +390,11 @@ void NewFunc (SymEntry* Func)
        CHECK ((D->Flags & FD_VARIADIC) == 0);
 
        /* Generate the push */
-       if (IsTypeFunc (LastParam->Type)) {
+       if (IsTypeFunc (D->LastParam->Type)) {
            /* Pointer to function */
            Flags = CF_PTR;
        } else {
-           Flags = TypeOf (LastParam->Type) | CF_FORCECHAR;
+           Flags = TypeOf (D->LastParam->Type) | CF_FORCECHAR;
        }
        g_push (Flags, 0);
     }
@@ -398,6 +407,9 @@ void NewFunc (SymEntry* Func)
        g_stackcheck ();
     }
 
+    /* Setup the stack */
+    oursp = 0;
+
     /* Walk through the parameter list and allocate register variable space
      * for parameters declared as register. Generate code to swap the contents
      * of the register bank with the save area on the stack.
@@ -429,9 +441,6 @@ void NewFunc (SymEntry* Func)
         Param = Param->NextSym;
     }
 
-    /* Setup the stack */
-    oursp = 0;
-
     /* Need a starting curly brace */
     ConsumeLCurly ();
 
@@ -462,15 +471,15 @@ void NewFunc (SymEntry* Func)
     /* Generate the exit code */
     g_leave ();
 
-    /* Eat the closing brace */
-    ConsumeRCurly ();
-
     /* Emit references to imports/exports */
     EmitExternals ();
 
     /* Leave the lexical level */
     LeaveFunctionLevel ();
 
+    /* Eat the closing brace */
+    ConsumeRCurly ();
+
     /* Switch back to the old segments */
     PopSegments ();