Made local static data use a separated label pool from the code label pool.

This commit is contained in:
acqn
2020-08-23 01:35:11 +08:00
committed by Oliver Schmidt
parent 9398e1cd33
commit 6b64b43395
10 changed files with 110 additions and 30 deletions

View File

@@ -101,6 +101,35 @@ 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;
/* Check for an overflow */
if (NextLabel >= 0xFFFF) {
Internal ("Local data label overflow");
}
/* Return the next label */
return ++NextLabel;
}
const char* LocalDataLabelName (unsigned L)
/* Make a label name from the given data label number. The label name will be
** created in static storage and overwritten when calling the function again.
*/
{
static char Buf[64];
sprintf (Buf, "M%04X", L);
return Buf;
}
unsigned GetPooledLiteralLabel (void) unsigned GetPooledLiteralLabel (void)
/* Get an unused literal label. Will never return zero. */ /* Get an unused literal label. Will never return zero. */
{ {

View File

@@ -56,6 +56,14 @@ const char* LocalLabelName (unsigned L);
int IsLocalLabelName (const char* Name); int IsLocalLabelName (const char* Name);
/* Return true if Name is the name of a local label */ /* Return true if Name is the name of a local label */
unsigned GetLocalDataLabel (void);
/* Get an unused local data label. Will never return zero. */
const char* LocalDataLabelName (unsigned L);
/* Make a label name from the given data label number. The label name will be
** created in static storage and overwritten when calling the function again.
*/
unsigned GetPooledLiteralLabel (void); unsigned GetPooledLiteralLabel (void);
/* Get an unused literal label. Will never return zero. */ /* Get an unused literal label. Will never return zero. */

View File

@@ -286,7 +286,7 @@ static void ParseLabelArg (StrBuf* T, unsigned Arg attribute ((unused)))
} else { } else {
/* Add a new label symbol if we don't have one until now */ /* Add a new C label symbol if we don't have one until now */
SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF); SymEntry* Entry = AddLabelSym (CurTok.Ident, SC_REF);
/* Append the label name to the buffer */ /* Append the label name to the buffer */

View File

@@ -107,11 +107,11 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs)
break; break;
case CF_STATIC: case CF_STATIC:
/* Static memory cell */ /* Local static memory cell */
if (Offs) { if (Offs) {
xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalLabelName (Label), Offs); xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalDataLabelName (Label), Offs);
} else { } else {
xsprintf (Buf, sizeof (Buf), "%s", LocalLabelName (Label)); xsprintf (Buf, sizeof (Buf), "%s", LocalDataLabelName (Label));
} }
break; break;
@@ -144,6 +144,15 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs)
xsprintf (Buf, sizeof (Buf), "regbank+%u", (unsigned)((Label+Offs) & 0xFFFF)); xsprintf (Buf, sizeof (Buf), "regbank+%u", (unsigned)((Label+Offs) & 0xFFFF));
break; break;
case CF_CODE:
/* Code label location */
if (Offs) {
xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalLabelName (Label), Offs);
} else {
xsprintf (Buf, sizeof (Buf), "%s", LocalLabelName (Label));
}
break;
default: default:
Internal ("Invalid address flags: %04X", Flags); Internal ("Invalid address flags: %04X", Flags);
} }
@@ -360,7 +369,7 @@ void g_defcodelabel (unsigned label)
void g_defdatalabel (unsigned label) void g_defdatalabel (unsigned label)
/* Define a local data label */ /* Define a local data label */
{ {
AddDataLine ("%s:", LocalLabelName (label)); AddDataLine ("%s:", LocalDataLabelName (label));
} }
@@ -2453,11 +2462,11 @@ void g_lateadjustSP (unsigned label)
/* Adjust stack based on non-immediate data */ /* Adjust stack based on non-immediate data */
{ {
AddCodeLine ("pha"); AddCodeLine ("pha");
AddCodeLine ("lda %s", LocalLabelName (label)); AddCodeLine ("lda %s", LocalDataLabelName (label));
AddCodeLine ("clc"); AddCodeLine ("clc");
AddCodeLine ("adc sp"); AddCodeLine ("adc sp");
AddCodeLine ("sta sp"); AddCodeLine ("sta sp");
AddCodeLine ("lda %s+1", LocalLabelName (label)); AddCodeLine ("lda %s+1", LocalDataLabelName (label));
AddCodeLine ("adc sp+1"); AddCodeLine ("adc sp+1");
AddCodeLine ("sta sp+1"); AddCodeLine ("sta sp+1");
AddCodeLine ("pla"); AddCodeLine ("pla");

View File

@@ -2204,6 +2204,11 @@ static void DefineData (ExprDesc* Expr)
g_defdata (CF_REGVAR, Expr->Name, Expr->IVal); g_defdata (CF_REGVAR, Expr->Name, Expr->IVal);
break; break;
case E_LOC_CODE:
/* Code label location */
g_defdata (CF_CODE, Expr->Name, Expr->IVal);
break;
case E_LOC_STACK: case E_LOC_STACK:
case E_LOC_PRIMARY: case E_LOC_PRIMARY:
case E_LOC_EXPR: case E_LOC_EXPR:

View File

@@ -92,6 +92,7 @@ static unsigned GlobalModeFlags (const ExprDesc* Expr)
case E_LOC_PRIMARY: return CF_PRIMARY; case E_LOC_PRIMARY: return CF_PRIMARY;
case E_LOC_EXPR: return CF_EXPR; case E_LOC_EXPR: return CF_EXPR;
case E_LOC_LITERAL: return CF_LITERAL; case E_LOC_LITERAL: return CF_LITERAL;
case E_LOC_CODE: return CF_CODE;
default: default:
Internal ("GlobalModeFlags: Invalid location flags value: 0x%04X", Expr->Flags); Internal ("GlobalModeFlags: Invalid location flags value: 0x%04X", Expr->Flags);
/* NOTREACHED */ /* NOTREACHED */
@@ -794,7 +795,7 @@ static void Primary (ExprDesc* E)
NextToken (); NextToken ();
Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND); Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND);
/* output its label */ /* output its label */
E->Flags = E_RTYPE_RVAL | E_LOC_STATIC | E_ADDRESS_OF; E->Flags = E_RTYPE_RVAL | E_LOC_CODE | E_ADDRESS_OF;
E->Name = Entry->V.L.Label; E->Name = Entry->V.L.Label;
E->Type = PointerTo (type_void); E->Type = PointerTo (type_void);
NextToken (); NextToken ();
@@ -1545,7 +1546,8 @@ void Store (ExprDesc* Expr, const Type* StoreType)
case E_LOC_STATIC: case E_LOC_STATIC:
case E_LOC_LITERAL: case E_LOC_LITERAL:
/* Static variable or literal in the literal pool */ case E_LOC_CODE:
/* Static variable, pooled literal or code label location */
g_putstatic (Flags, Expr->Name, Expr->IVal); g_putstatic (Flags, Expr->Name, Expr->IVal);
break; break;
@@ -1624,7 +1626,8 @@ static void PreInc (ExprDesc* Expr)
case E_LOC_STATIC: case E_LOC_STATIC:
case E_LOC_LITERAL: case E_LOC_LITERAL:
/* Static variable or literal in the literal pool */ case E_LOC_CODE:
/* Static variable, pooled literal or code label location */
g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val); g_addeqstatic (Flags, Expr->Name, Expr->IVal, Val);
break; break;
@@ -1700,7 +1703,8 @@ static void PreDec (ExprDesc* Expr)
case E_LOC_STATIC: case E_LOC_STATIC:
case E_LOC_LITERAL: case E_LOC_LITERAL:
/* Static variable or literal in the literal pool */ case E_LOC_CODE:
/* Static variable, pooled literal or code label location */
g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val); g_subeqstatic (Flags, Expr->Name, Expr->IVal, Val);
break; break;
@@ -3878,7 +3882,8 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op)
case E_LOC_STATIC: case E_LOC_STATIC:
case E_LOC_LITERAL: case E_LOC_LITERAL:
/* Static variable or literal in the literal pool */ case E_LOC_CODE:
/* Static variable, pooled literal or code label location */
if (Gen->Tok == TOK_PLUS_ASSIGN) { if (Gen->Tok == TOK_PLUS_ASSIGN) {
g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal);
} else { } else {

View File

@@ -196,6 +196,15 @@ const char* ED_GetLabelName (const ExprDesc* Expr, long Offs)
} }
break; break;
case E_LOC_CODE:
/* Code label location */
if (Offs) {
SB_Printf (&Buf, "%s%+ld", LocalLabelName (Expr->Name), Offs);
} else {
SB_Printf (&Buf, "%s", LocalLabelName (Expr->Name));
}
break;
default: default:
Internal ("Invalid location in ED_GetLabelName: 0x%04X", ED_GetLoc (Expr)); Internal ("Invalid location in ED_GetLabelName: 0x%04X", ED_GetLoc (Expr));
} }
@@ -503,9 +512,9 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
Flags &= ~E_LOC_LITERAL; Flags &= ~E_LOC_LITERAL;
Sep = ','; Sep = ',';
} }
if (Flags & E_RTYPE_LVAL) { if (Flags & E_LOC_CODE) {
fprintf (F, "%cE_RTYPE_LVAL", Sep); fprintf (F, "%cE_LOC_CODE", Sep);
Flags &= ~E_RTYPE_LVAL; Flags &= ~E_LOC_CODE;
Sep = ','; Sep = ',';
} }
if (Flags & E_BITFIELD) { if (Flags & E_BITFIELD) {
@@ -523,6 +532,11 @@ void PrintExprDesc (FILE* F, ExprDesc* E)
Flags &= ~E_CC_SET; Flags &= ~E_CC_SET;
Sep = ','; Sep = ',';
} }
if (Flags & E_RTYPE_LVAL) {
fprintf (F, "%cE_RTYPE_LVAL", Sep);
Flags &= ~E_RTYPE_LVAL;
Sep = ',';
}
if (Flags & E_ADDRESS_OF) { if (Flags & E_ADDRESS_OF) {
fprintf (F, "%cE_ADDRESS_OF", Sep); fprintf (F, "%cE_ADDRESS_OF", Sep);
Flags &= ~E_ADDRESS_OF; Flags &= ~E_ADDRESS_OF;

View File

@@ -83,6 +83,11 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr)
g_getimmed ((Flags | CF_REGVAR) & ~CF_CONST, Expr->Name, Expr->IVal); g_getimmed ((Flags | CF_REGVAR) & ~CF_CONST, Expr->Name, Expr->IVal);
break; break;
case E_LOC_CODE:
/* Code label, load address */
g_getimmed ((Flags | CF_CODE) & ~CF_CONST, Expr->Name, Expr->IVal);
break;
case E_LOC_STACK: case E_LOC_STACK:
g_leasp (Expr->IVal); g_leasp (Expr->IVal);
break; break;
@@ -201,6 +206,11 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr)
g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal); g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal);
break; break;
case E_LOC_CODE:
/* Code label location */
g_getstatic (Flags | CF_CODE, Expr->Name, Expr->IVal);
break;
case E_LOC_STACK: case E_LOC_STACK:
/* Value on the stack */ /* Value on the stack */
g_getlocal (Flags, Expr->IVal); g_getlocal (Flags, Expr->IVal);

View File

@@ -64,31 +64,31 @@
static unsigned AllocLabel (void (*UseSeg) ()) static unsigned AllocLabel (void (*UseSeg) ())
/* Switch to a segment, define a local label and return it */ /* Switch to a segment, define a local data label and return it */
{ {
unsigned Label; unsigned DataLabel;
/* Switch to the segment */ /* Switch to the segment */
UseSeg (); UseSeg ();
/* Define the variable label */ /* Define the variable label */
Label = GetLocalLabel (); DataLabel = GetLocalDataLabel ();
g_defdatalabel (Label); g_defdatalabel (DataLabel);
/* Return the label */ /* Return the label */
return Label; return DataLabel;
} }
static void AllocStorage (unsigned Label, void (*UseSeg) (), unsigned Size) static void AllocStorage (unsigned DataLabel, void (*UseSeg) (), unsigned Size)
/* Reserve Size bytes of BSS storage prefixed by a local label. */ /* Reserve Size bytes of BSS storage prefixed by a local data label. */
{ {
/* Switch to the segment */ /* Switch to the segment */
UseSeg (); UseSeg ();
/* Define the variable label */ /* Define the variable label */
g_defdatalabel (Label); g_defdatalabel (DataLabel);
/* Reserve space for the data */ /* Reserve space for the data */
g_res (Size); g_res (Size);
@@ -301,7 +301,7 @@ static void ParseAutoDecl (Declaration* Decl)
Decl->StorageClass = (Decl->StorageClass & ~SC_AUTO) | SC_STATIC; Decl->StorageClass = (Decl->StorageClass & ~SC_AUTO) | SC_STATIC;
/* Generate a label, but don't define it */ /* Generate a label, but don't define it */
DataLabel = GetLocalLabel (); DataLabel = GetLocalDataLabel ();
/* Add the symbol to the symbol table. */ /* Add the symbol to the symbol table. */
Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, DataLabel); Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, DataLabel);
@@ -380,7 +380,7 @@ static void ParseStaticDecl (Declaration* Decl)
unsigned Size; unsigned Size;
/* Generate a label, but don't define it */ /* Generate a label, but don't define it */
unsigned DataLabel = GetLocalLabel (); unsigned DataLabel = GetLocalDataLabel ();
/* Add the symbol to the symbol table. */ /* Add the symbol to the symbol table. */
SymEntry* Sym = AddLocalSym (Decl->Ident, Decl->Type, SymEntry* Sym = AddLocalSym (Decl->Ident, Decl->Type,

View File

@@ -931,7 +931,7 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags)
DOR->Flags = Flags; DOR->Flags = Flags;
DOR->StackPtr = StackPtr; DOR->StackPtr = StackPtr;
DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack);
DOR->LateSP_Label = GetLocalLabel (); DOR->LateSP_Label = GetLocalDataLabel ();
return DOR; return DOR;
} }
@@ -953,7 +953,7 @@ unsigned short FindSPAdjustment (const char* Name)
SymEntry* AddLabelSym (const char* Name, unsigned Flags) SymEntry* AddLabelSym (const char* Name, unsigned Flags)
/* Add a goto label to the label table */ /* Add a C goto label to the label table */
{ {
unsigned i; unsigned i;
DefOrRef *DOR, *NewDOR; DefOrRef *DOR, *NewDOR;
@@ -1012,7 +1012,7 @@ SymEntry* AddLabelSym (const char* Name, unsigned Flags)
/* Optimizer will need the information about the value of SP adjustment /* Optimizer will need the information about the value of SP adjustment
** later, so let's preserve it. ** later, so let's preserve it.
*/ */
E = NewSymEntry (LocalLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT); E = NewSymEntry (LocalDataLabelName (DOR->LateSP_Label), SC_SPADJUSTMENT);
E->V.SPAdjustment = StackPtr - DOR->StackPtr; E->V.SPAdjustment = StackPtr - DOR->StackPtr;
AddSymEntry (SPAdjustTab, E); AddSymEntry (SPAdjustTab, E);
} }
@@ -1134,9 +1134,9 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs
Entry->V.L.Label = Offs; Entry->V.L.Label = Offs;
SymSetAsmName (Entry); SymSetAsmName (Entry);
} else if ((Flags & SC_STATIC) == SC_STATIC) { } else if ((Flags & SC_STATIC) == SC_STATIC) {
/* Generate the assembler name from the label number */ /* Generate the assembler name from the data label number */
Entry->V.L.Label = Offs; Entry->V.L.Label = Offs;
Entry->AsmName = xstrdup (LocalLabelName (Entry->V.L.Label)); Entry->AsmName = xstrdup (LocalDataLabelName (Entry->V.L.Label));
} else { } else {
Internal ("Invalid flags in AddLocalSym: %04X", Flags); Internal ("Invalid flags in AddLocalSym: %04X", Flags);
} }