mirror of
https://github.com/cc65/cc65.git
synced 2025-02-03 22:32:24 +00:00
Made local code/data labels really local to the functions where they live in.
This commit is contained in:
parent
86ced2bd4c
commit
d02b12fa6c
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user