1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 06:25:17 +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 */ /* cc65 */
#include "asmlabel.h" #include "asmlabel.h"
#include "error.h" #include "error.h"
#include "segments.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
static struct Segments* CurrentFunctionSegment;
@@ -51,19 +62,26 @@
unsigned GetLocalLabel (void) void UseLabelPoolFromSegments (struct Segments* Seg)
/* Get an unused label. Will never return zero. */ /* Use the info in segments for generating new label numbers */
{ {
/* Number to generate unique labels */ CurrentFunctionSegment = Seg;
static unsigned NextLabel = 0; }
unsigned GetLocalLabel (void)
/* Get an unused assembler label for the function. Will never return zero. */
{
PRECONDITION (CurrentFunctionSegment != 0);
/* Check for an overflow */ /* Check for an overflow */
if (NextLabel >= 0xFFFF) { if (CurrentFunctionSegment->NextLabel >= 0xFFFF) {
Internal ("Local label overflow"); Internal ("Local label overflow");
} }
/* Return the next label */ /* Return the next label */
return ++NextLabel; return ++CurrentFunctionSegment->NextLabel;
} }
@@ -104,16 +122,15 @@ int IsLocalLabelName (const char* Name)
unsigned GetLocalDataLabel (void) unsigned GetLocalDataLabel (void)
/* Get an unused local data label. Will never return zero. */ /* Get an unused local data label. Will never return zero. */
{ {
/* Number to generate unique labels */ PRECONDITION (CurrentFunctionSegment != 0);
static unsigned NextLabel = 0;
/* Check for an overflow */ /* Check for an overflow */
if (NextLabel >= 0xFFFF) { if (CurrentFunctionSegment->NextDataLabel >= 0xFFFF) {
Internal ("Local data label overflow"); Internal ("Local data label overflow");
} }
/* Return the next label */ /* Return the next label */
return ++NextLabel; return ++CurrentFunctionSegment->NextDataLabel;
} }

View File

@@ -38,14 +38,27 @@
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
struct Segments;
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
void UseLabelPoolFromSegments (struct Segments* Seg);
/* Use the info in segments for generating new label numbers */
unsigned GetLocalLabel (void); 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); const char* LocalLabelName (unsigned L);
/* Make a label name from the given label number. The label name will be /* 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 */ /* Create the global code and data segments */
CreateGlobalSegments (); 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 */ /* Initialize the literal pool */
InitLiteralPool (); InitLiteralPool ();
@@ -488,6 +494,9 @@ void FinishCompile (void)
*/ */
for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) { for (Entry = GetGlobalSymTab ()->SymHead; Entry; Entry = Entry->NextSym) {
if (SymIsOutputFunc (Entry)) { if (SymIsOutputFunc (Entry)) {
/* Continue with previous label numbers */
UseLabelPoolFromSegments (Entry->V.F.Seg);
/* Function which is defined and referenced or extern */ /* Function which is defined and referenced or extern */
MoveLiteralPool (Entry->V.F.LitPool); MoveLiteralPool (Entry->V.F.LitPool);
CS_MergeLabels (Entry->V.F.Seg->Code); 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->ReturnType = GetFuncReturn (Sym->Type);
F->Desc = D; F->Desc = D;
F->Reserved = 0; F->Reserved = 0;
F->RetLab = GetLocalLabel (); F->RetLab = 0;
F->TopLevelSP = 0; F->TopLevelSP = 0;
F->RegOffs = RegisterSpace; F->RegOffs = RegisterSpace;
F->Flags = IsTypeVoid (F->ReturnType) ? FF_VOID_RETURN : FF_NONE; 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) unsigned F_GetRetLab (const Function* F)
/* Return the return jump label */ /* Return the return jump label */
{ {
@@ -540,6 +548,12 @@ void NewFunc (SymEntry* Func, FuncDesc* D)
/* Allocate code and data segments for this function */ /* Allocate code and data segments for this function */
Func->V.F.Seg = PushSegments (Func); 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 */ /* Allocate a new literal pool */
PushLiteralPool (Func); PushLiteralPool (Func);

View File

@@ -120,6 +120,9 @@ int F_IsOldStyle (const Function* F);
int F_HasOldStyleIntRet (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 */ /* 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); unsigned F_GetRetLab (const Function* F);
/* Return the return jump label */ /* Return the return jump label */

View File

@@ -143,12 +143,14 @@ static Segments* NewSegments (SymEntry* Func)
Segments* S = xmalloc (sizeof (Segments)); Segments* S = xmalloc (sizeof (Segments));
/* Initialize the fields */ /* Initialize the fields */
S->Text = NewTextSeg (Func); S->Text = NewTextSeg (Func);
S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func); S->Code = NewCodeSeg (GetSegName (SEG_CODE), Func);
S->Data = NewDataSeg (GetSegName (SEG_DATA), Func); S->Data = NewDataSeg (GetSegName (SEG_DATA), Func);
S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func); S->ROData = NewDataSeg (GetSegName (SEG_RODATA), Func);
S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func); S->BSS = NewDataSeg (GetSegName (SEG_BSS), Func);
S->CurDSeg = SEG_DATA; S->CurDSeg = SEG_DATA;
S->NextLabel = 0;
S->NextDataLabel = 0;
/* Return the new struct */ /* Return the new struct */
return S; return S;

View File

@@ -86,6 +86,8 @@ struct Segments {
struct DataSeg* ROData; /* Readonly data segment */ struct DataSeg* ROData; /* Readonly data segment */
struct DataSeg* BSS; /* Segment for uninitialized data */ struct DataSeg* BSS; /* Segment for uninitialized data */
segment_t CurDSeg; /* Current data segment */ 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. */ /* Pointer to the current segment list. Output goes here. */