1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-07 07:29:33 +00:00

Made local code/data labels really local to the functions where they live in.

This commit is contained in:
acqn 2020-08-23 01:35:18 +08:00 committed by Oliver Schmidt
parent 86ced2bd4c
commit d02b12fa6c
7 changed files with 78 additions and 18 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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. */