diff --git a/src/cc65/asmlabel.c b/src/cc65/asmlabel.c index f561036ce..7d5db75e6 100644 --- a/src/cc65/asmlabel.c +++ b/src/cc65/asmlabel.c @@ -42,6 +42,17 @@ /* cc65 */ #include "asmlabel.h" #include "error.h" +#include "segments.h" + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + + + +static struct Segments* CurrentFunctionSegment; @@ -51,19 +62,26 @@ -unsigned GetLocalLabel (void) -/* Get an unused label. Will never return zero. */ +void UseLabelPoolFromSegments (struct Segments* Seg) +/* Use the info in segments for generating new label numbers */ { - /* Number to generate unique labels */ - static unsigned NextLabel = 0; + CurrentFunctionSegment = Seg; +} + + + +unsigned GetLocalLabel (void) +/* Get an unused assembler label for the function. Will never return zero. */ +{ + PRECONDITION (CurrentFunctionSegment != 0); /* Check for an overflow */ - if (NextLabel >= 0xFFFF) { + if (CurrentFunctionSegment->NextLabel >= 0xFFFF) { Internal ("Local label overflow"); } /* Return the next label */ - return ++NextLabel; + return ++CurrentFunctionSegment->NextLabel; } @@ -104,16 +122,15 @@ int IsLocalLabelName (const char* Name) unsigned GetLocalDataLabel (void) /* Get an unused local data label. Will never return zero. */ { - /* Number to generate unique labels */ - static unsigned NextLabel = 0; + PRECONDITION (CurrentFunctionSegment != 0); /* Check for an overflow */ - if (NextLabel >= 0xFFFF) { + if (CurrentFunctionSegment->NextDataLabel >= 0xFFFF) { Internal ("Local data label overflow"); } /* Return the next label */ - return ++NextLabel; + return ++CurrentFunctionSegment->NextDataLabel; } diff --git a/src/cc65/asmlabel.h b/src/cc65/asmlabel.h index a79071400..dbfe2f443 100644 --- a/src/cc65/asmlabel.h +++ b/src/cc65/asmlabel.h @@ -38,14 +38,27 @@ +/*****************************************************************************/ +/* Forwards */ +/*****************************************************************************/ + + + +struct Segments; + + + /*****************************************************************************/ /* Code */ /*****************************************************************************/ +void UseLabelPoolFromSegments (struct Segments* Seg); +/* Use the info in segments for generating new label numbers */ + unsigned GetLocalLabel (void); -/* Get an unused assembler label. Will never return zero. */ +/* Get an unused assembler label for the function. Will never return zero. */ const char* LocalLabelName (unsigned L); /* Make a label name from the given label number. The label name will be diff --git a/src/cc65/compile.c b/src/cc65/compile.c index 3296968f6..00e78c2bd 100644 --- a/src/cc65/compile.c +++ b/src/cc65/compile.c @@ -389,6 +389,12 @@ void Compile (const char* FileName) /* Create the global code and data segments */ CreateGlobalSegments (); + /* There shouldn't be needs for local labels outside a function, but the + ** current code generator still tries to get some at times even though the + ** code were ill-formed. So just set it up with the global segment list. + */ + UseLabelPoolFromSegments (GS); + /* Initialize the literal pool */ InitLiteralPool (); @@ -488,6 +494,9 @@ void FinishCompile (void) */ for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { if (SymIsOutputFunc (Entry)) { + /* Continue with previous label numbers */ + UseLabelPoolFromSegments (Entry->V.F.Seg); + /* Function which is defined and referenced or extern */ MoveLiteralPool (Entry->V.F.LitPool); CS_MergeLabels (Entry->V.F.Seg->Code); diff --git a/src/cc65/function.c b/src/cc65/function.c index 9d4f8c2f9..00755ae65 100644 --- a/src/cc65/function.c +++ b/src/cc65/function.c @@ -83,7 +83,7 @@ static Function* NewFunction (struct SymEntry* Sym, FuncDesc* D) F->ReturnType = GetFuncReturn (Sym->Type); F->Desc = D; F->Reserved = 0; - F->RetLab = GetLocalLabel (); + F->RetLab = 0; F->TopLevelSP = 0; F->RegOffs = RegisterSpace; F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; @@ -255,6 +255,14 @@ int F_HasOldStyleIntRet (const Function* F) +void F_SetRetLab (Function* F, unsigned NewRetLab) +/* Change the return jump label */ +{ + F->RetLab = NewRetLab; +} + + + unsigned F_GetRetLab (const Function* F) /* Return the return jump label */ { @@ -540,6 +548,12 @@ void NewFunc (SymEntry* Func, FuncDesc* D) /* Allocate code and data segments for this function */ Func->V.F.Seg = PushSegments (Func); + /* Use the info in the segments for generating new local labels */ + UseLabelPoolFromSegments (Func->V.F.Seg); + + /* Set return label. This has to be done after the segments are pushed */ + F_SetRetLab (CurrentFunc, GetLocalLabel ()); + /* Allocate a new literal pool */ PushLiteralPool (Func); diff --git a/src/cc65/function.h b/src/cc65/function.h index e0b7ef0a2..825257a60 100644 --- a/src/cc65/function.h +++ b/src/cc65/function.h @@ -120,6 +120,9 @@ int F_IsOldStyle (const Function* F); int F_HasOldStyleIntRet (const Function* F); /* Return true if this is an old style (K&R) function with an implicit int return */ +void F_SetRetLab (Function* F, unsigned NewRetLab); +/* Change the return jump label */ + unsigned F_GetRetLab (const Function* F); /* Return the return jump label */ diff --git a/src/cc65/segments.c b/src/cc65/segments.c index 6efbf68b7..7a9e32eb8 100644 --- a/src/cc65/segments.c +++ b/src/cc65/segments.c @@ -143,12 +143,14 @@ static Segments* NewSegments (SymEntry* Func) Segments* S = xmalloc (sizeof (Segments)); /* Initialize the fields */ - S->Text = NewTextSeg (Func); - S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func); - S->Data = NewDataSeg (GetSegName (SEG_DATA), Func); - S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func); - S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func); - S->CurDSeg = SEG_DATA; + S->Text = NewTextSeg (Func); + S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func); + S->Data = NewDataSeg (GetSegName (SEG_DATA), Func); + S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func); + S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func); + S->CurDSeg = SEG_DATA; + S->NextLabel = 0; + S->NextDataLabel = 0; /* Return the new struct */ return S; diff --git a/src/cc65/segments.h b/src/cc65/segments.h index f55be688b..777073559 100644 --- a/src/cc65/segments.h +++ b/src/cc65/segments.h @@ -86,6 +86,8 @@ struct Segments { struct DataSeg* ROData; /* Readonly data segment */ struct DataSeg* BSS; /* Segment for uninitialized data */ segment_t CurDSeg; /* Current data segment */ + unsigned NextLabel; /* Number to generate unique code labels */ + unsigned NextDataLabel; /* Number to generate unique data labels */ }; /* Pointer to the current segment list. Output goes here. */