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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -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
|
||||||
|
@@ -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);
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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 */
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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. */
|
||||||
|
Reference in New Issue
Block a user