diff --git a/src/cc65/asmlabel.c b/src/cc65/asmlabel.c index 09aee3b92..1dda96fb0 100644 --- a/src/cc65/asmlabel.c +++ b/src/cc65/asmlabel.c @@ -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; +} diff --git a/src/cc65/asmlabel.h b/src/cc65/asmlabel.h index 4a76643a5..31b1f311a 100644 --- a/src/cc65/asmlabel.h +++ b/src/cc65/asmlabel.h @@ -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 */ diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index 48cf02319..b48d815d8 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -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 */ diff --git a/src/cc65/codegen.h b/src/cc65/codegen.h index d946a9a10..3054a39b3 100644 --- a/src/cc65/codegen.h +++ b/src/cc65/codegen.h @@ -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 */ diff --git a/src/cc65/declare.c b/src/cc65/declare.c index 6953afa3c..e81c761ed 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -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. diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index ac19873e7..b9b5ba5fb 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -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; diff --git a/src/cc65/litpool.c b/src/cc65/litpool.c index eb31c7ecc..95228179d 100644 --- a/src/cc65/litpool.c +++ b/src/cc65/litpool.c @@ -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)); diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 17b0dd0fe..07acb3cbc 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -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);