+#include "../common/xmalloc.h"
+
#include "asmcode.h"
#include "asmlabel.h"
#include "codegen.h"
#include "funcdesc.h"
#include "litpool.h"
#include "locals.h"
-#include "mem.h"
#include "scanner.h"
#include "stmt.h"
#include "symtab.h"
type* ReturnType; /* Function return type */
struct FuncDesc* Desc; /* Function descriptor */
CodeMark EntryCode; /* Backpatch addr for entry code */
- unsigned LocalMax; /* Total space for locals */
- unsigned LocalSize; /* Current space for locals */
- unsigned RetLab; /* Return code label */
+ int Reserved; /* Reserved local space */
+ unsigned RetLab; /* Return code label */
};
/* Pointer to current function */
/*****************************************************************************/
-/* code */
+/* Subroutines working with struct Function */
/*****************************************************************************/
F->FuncEntry = Sym;
F->ReturnType = Sym->Type + 1 + DECODE_SIZE;
F->Desc = DecodePtr (Sym->Type + 1);
- F->EntryCode = GetCodePos ();
- F->LocalMax = 0;
- F->LocalSize = 0;
+ F->EntryCode = 0;
+ F->Reserved = 0;
F->RetLab = GetLabel ();
/* Return the new structure */
+void RememberEntry (Function* F)
+/* Remember the current output position for local space creation later */
+{
+ F->EntryCode = GetCodePos ();
+}
+
+
+
unsigned GetRetLab (const Function* F)
/* Return the return jump label */
{
-unsigned AllocLocalSpace (Function* F, unsigned Size)
-/* Allocate space for the function locals, return stack offset */
+int ReserveLocalSpace (Function* F, unsigned Size)
+/* Reserve (but don't allocate) the given local space and return the stack
+ * offset.
+ */
{
- /* Remember the current offset */
- unsigned Offs = F->LocalSize;
-
- /* Add the size */
- F->LocalSize += Size;
- if (F->LocalSize > F->LocalMax) {
- F->LocalMax = F->LocalSize;
- }
-
- /* Return the offset */
- return Offs;
+ F->Reserved += Size;
+ return oursp - F->Reserved;
}
-void FreeLocalSpace (Function* F, unsigned Size)
-/* Free space allocated for function locals */
+void AllocLocalSpace (Function* F)
+/* Allocate any local space previously reserved. The function will do
+ * nothing if there is no reserved local space.
+ */
{
- F->LocalSize -= Size;
+ if (F->Reserved > 0) {
+
+ /* Switch to the code segment */
+ g_usecode ();
+
+ /* Create space on the stack */
+ g_space (F->Reserved);
+
+ /* Correct the stack pointer */
+ oursp -= F->Reserved;
+
+ /* Nothing more reserved */
+ F->Reserved = 0;
+ }
}
+/*****************************************************************************/
+/* code */
+/*****************************************************************************/
+
+
+
void NewFunc (SymEntry* Func)
/* Parse argument declarations and function body. */
{
/* C functions cannot currently have __fastcall__ calling conventions */
if (IsFastCallFunc (Func->Type)) {
- Error (ERR_FASTCALL);
+ Error (ERR_FASTCALL);
}
/* Need a starting curly brace */
- if (curtok != LCURLY) {
+ if (curtok != TOK_LCURLY) {
Error (ERR_LCURLY_EXPECTED);
}
/* Setup register variables */
InitRegVars ();
- /* Switch to the code segment and generate function entry code */
+ /* Switch to the code segment and define the function name label */
g_usecode ();
- g_enter (TypeOf (Func->Type), Func->Name, GetParamSize (CurrentFunc));
+ g_defgloblabel (Func->Name);
+
+ /* Generate function entry code if needed */
+ g_enter (TypeOf (Func->Type), GetParamSize (CurrentFunc));
+
+ /* Remember the current code position. This may be used later to create
+ * local variable space once we have created the function body itself.
+ * Currently this is not possible because the stack offsets of all locals
+ * have to be known in advance.
+ */
+ RememberEntry (CurrentFunc);
/* Parse the function body */
oursp = 0;
+