/* */
/* */
/* */
-/* (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 */
/* */
/* */
-/* 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 */
F->Reserved = 0;
F->RetLab = GetLocalLabel ();
F->TopLevelSP = 0;
- F->RegOffs = MAX_REG_SPACE;
+ F->RegOffs = RegisterSpace;
/* Return the new structure */
return 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;
}
/* Parse argument declarations and function body. */
{
int HadReturn;
- SymEntry* LastParam;
SymEntry* Param;
/* Get the function descriptor from the function entry */
/* 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).
/* 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) {
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);
}
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.
Param = Param->NextSym;
}
- /* Setup the stack */
- oursp = 0;
-
/* Need a starting curly brace */
ConsumeLCurly ();
/* 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 ();