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

Use a dedicated label pool for literals.

This commit is contained in:
acqn 2020-08-23 01:35:06 +08:00 committed by Oliver Schmidt
parent bee559d5f4
commit 9398e1cd33
8 changed files with 105 additions and 34 deletions

View File

@ -98,3 +98,32 @@ int IsLocalLabelName (const char* Name)
/* Local label name */
return 1;
}
unsigned GetPooledLiteralLabel (void)
/* Get an unused literal label. Will never return zero. */
{
/* Number to generate unique labels */
static unsigned NextLabel = 0;
/* Check for an overflow */
if (NextLabel >= 0xFFFF) {
Internal ("Literal label overflow");
}
/* Return the next label */
return ++NextLabel;
}
const char* PooledLiteralLabelName (unsigned L)
/* Make a litral label name from the given label number. The label name will be
** created in static storage and overwritten when calling the function again.
*/
{
static char Buf[64];
sprintf (Buf, "S%04X", L);
return Buf;
}

View File

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

View File

@ -124,6 +124,16 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs)
}
break;
case CF_LITERAL:
/* Literal */
/* Static memory cell */
if (Offs) {
xsprintf (Buf, sizeof (Buf), "%s%+ld", PooledLiteralLabelName (Label), Offs);
} else {
xsprintf (Buf, sizeof (Buf), "%s", PooledLiteralLabelName (Label));
}
break;
case CF_ABSOLUTE:
/* Absolute address */
xsprintf (Buf, sizeof (Buf), "$%04X", (unsigned)((Label+Offs) & 0xFFFF));
@ -355,24 +365,6 @@ void g_defdatalabel (unsigned label)
void g_aliasdatalabel (unsigned label, unsigned baselabel, long offs)
/* Define label as a local alias for baselabel+offs */
{
/* We need an intermediate buffer here since LocalLabelName uses a
** static buffer which changes with each call.
*/
StrBuf L = AUTO_STRBUF_INITIALIZER;
SB_AppendStr (&L, LocalLabelName (label));
SB_Terminate (&L);
AddDataLine ("%s\t:=\t%s+%ld",
SB_GetConstBuf (&L),
LocalLabelName (baselabel),
offs);
SB_Done (&L);
}
/*****************************************************************************/
/* Functions handling global labels */
/*****************************************************************************/
@ -388,6 +380,33 @@ void g_defgloblabel (const char* Name)
void g_defliterallabel (unsigned label)
/* Define a literal data label */
{
/* Literal labels are always data labels */
AddDataLine ("%s:", PooledLiteralLabelName (label));
}
void g_aliasliterallabel (unsigned label, unsigned baselabel, long offs)
/* Define label as an alias for baselabel+offs */
{
/* We need an intermediate buffer here since LocalLabelName uses a
** static buffer which changes with each call.
*/
StrBuf L = AUTO_STRBUF_INITIALIZER;
SB_AppendStr (&L, PooledLiteralLabelName (label));
SB_Terminate (&L);
AddDataLine ("%s\t:=\t%s+%ld",
SB_GetConstBuf (&L),
PooledLiteralLabelName (baselabel),
offs);
SB_Done (&L);
}
void g_defexport (const char* Name, int ZP)
/* Export the given label */
{
@ -2364,7 +2383,7 @@ void g_call (unsigned Flags, const char* Label, unsigned ArgSize)
void g_callind (unsigned Flags, unsigned ArgSize, int Offs)
/* Call subroutine indirect */
{
if ((Flags & CF_STACK) == 0) {
if ((Flags & CF_ADDRMASK) != CF_STACK) {
/* Address is in a/x */
if ((Flags & CF_FIXARGC) == 0) {
/* Pass arg count */

View File

@ -148,9 +148,6 @@ void g_defcodelabel (unsigned label);
void g_defdatalabel (unsigned label);
/* Define a local data label */
void g_aliasdatalabel (unsigned label, unsigned baselabel, long offs);
/* Define label as a local alias for baselabel+offs */
/*****************************************************************************/
@ -162,6 +159,12 @@ void g_aliasdatalabel (unsigned label, unsigned baselabel, long offs);
void g_defgloblabel (const char* Name);
/* Define a global label with the given name */
void g_defliterallabel (unsigned label);
/* Define a literal data label */
void g_aliasliterallabel (unsigned label, unsigned baselabel, long offs);
/* Define label as an alias for baselabel+offs */
void g_defexport (const char* Name, int ZP);
/* Export the given label */

View File

@ -2185,11 +2185,15 @@ static void DefineData (ExprDesc* Expr)
break;
case E_LOC_STATIC:
case E_LOC_LITERAL:
/* Static variable or literal in the literal pool */
/* Static variable */
g_defdata (CF_STATIC, Expr->Name, Expr->IVal);
break;
case E_LOC_LITERAL:
/* Literal in the literal pool */
g_defdata (CF_LITERAL, Expr->Name, Expr->IVal);
break;
case E_LOC_REGISTER:
/* Register variable. Taking the address is usually not
** allowed.

View File

@ -190,9 +190,9 @@ const char* ED_GetLabelName (const ExprDesc* Expr, long Offs)
case E_LOC_LITERAL:
/* Literal in the literal pool */
if (Offs) {
SB_Printf (&Buf, "%s%+ld", LocalLabelName (Expr->Name), Offs);
SB_Printf (&Buf, "%s%+ld", PooledLiteralLabelName (Expr->Name), Offs);
} else {
SB_Printf (&Buf, "%s", LocalLabelName (Expr->Name));
SB_Printf (&Buf, "%s", PooledLiteralLabelName (Expr->Name));
}
break;

View File

@ -99,7 +99,7 @@ static Literal* NewLiteral (const void* Buf, unsigned Len)
Literal* L = xmalloc (sizeof (*L));
/* Initialize the fields */
L->Label = GetLocalLabel ();
L->Label = GetPooledLiteralLabel ();
L->RefCount = 0;
L->Output = 0;
SB_Init (&L->Data);
@ -130,7 +130,7 @@ static void OutputLiteral (Literal* L)
TranslateLiteral (L);
/* Define the label for the literal */
g_defdatalabel (L->Label);
g_defliterallabel (L->Label);
/* Output the literal data */
g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data));
@ -423,12 +423,12 @@ static void OutputReadOnlyLiterals (Collection* Literals)
if (C != 0) {
/* This literal is part of a longer literal, merge them */
g_aliasdatalabel (L->Label, C->Label, GetLiteralSize (C) - GetLiteralSize (L));
g_aliasliterallabel (L->Label, C->Label, GetLiteralSize (C) - GetLiteralSize (L));
} else {
/* Define the label for the literal */
g_defdatalabel (L->Label);
g_defliterallabel (L->Label);
/* Output the literal data */
g_defbytes (SB_GetConstBuf (&L->Data), SB_GetLen (&L->Data));

View File

@ -64,11 +64,15 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr)
break;
case E_LOC_STATIC:
case E_LOC_LITERAL:
/* Static symbol or literal, load address */
/* Static symbol, load address */
g_getimmed ((Flags | CF_STATIC) & ~CF_CONST, Expr->Name, Expr->IVal);
break;
case E_LOC_LITERAL:
/* Literal, load address */
g_getimmed ((Flags | CF_LITERAL) & ~CF_CONST, Expr->Name, Expr->IVal);
break;
case E_LOC_REGISTER:
/* Register variable. Taking the address is usually not
** allowed.
@ -183,11 +187,15 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr)
break;
case E_LOC_STATIC:
case E_LOC_LITERAL:
/* Static variable or literal in the literal pool */
/* Static variable */
g_getstatic (Flags | CF_STATIC, Expr->Name, Expr->IVal);
break;
case E_LOC_LITERAL:
/* Literal in the literal pool */
g_getstatic (Flags | CF_LITERAL, Expr->Name, Expr->IVal);
break;
case E_LOC_REGISTER:
/* Register variable */
g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal);