diff --git a/src/cc65/asmlabel.c b/src/cc65/asmlabel.c index 1dda96fb0..f561036ce 100644 --- a/src/cc65/asmlabel.c +++ b/src/cc65/asmlabel.c @@ -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) /* Get an unused literal label. Will never return zero. */ { diff --git a/src/cc65/asmlabel.h b/src/cc65/asmlabel.h index 31b1f311a..a79071400 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 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); /* Get an unused literal label. Will never return zero. */ diff --git a/src/cc65/asmstmt.c b/src/cc65/asmstmt.c index 9dd1f906a..bf5a0815b 100644 --- a/src/cc65/asmstmt.c +++ b/src/cc65/asmstmt.c @@ -286,7 +286,7 @@ static void ParseLabelArg (StrBuf* T, unsigned Arg attribute ((unused))) } 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); /* Append the label name to the buffer */ diff --git a/src/cc65/codegen.c b/src/cc65/codegen.c index b48d815d8..031e4e81a 100644 --- a/src/cc65/codegen.c +++ b/src/cc65/codegen.c @@ -107,11 +107,11 @@ static const char* GetLabelName (unsigned Flags, uintptr_t Label, long Offs) break; case CF_STATIC: - /* Static memory cell */ + /* Local static memory cell */ if (Offs) { - xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalLabelName (Label), Offs); + xsprintf (Buf, sizeof (Buf), "%s%+ld", LocalDataLabelName (Label), Offs); } else { - xsprintf (Buf, sizeof (Buf), "%s", LocalLabelName (Label)); + xsprintf (Buf, sizeof (Buf), "%s", LocalDataLabelName (Label)); } 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)); 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: Internal ("Invalid address flags: %04X", Flags); } @@ -360,7 +369,7 @@ void g_defcodelabel (unsigned label) void g_defdatalabel (unsigned 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 */ { AddCodeLine ("pha"); - AddCodeLine ("lda %s", LocalLabelName (label)); + AddCodeLine ("lda %s", LocalDataLabelName (label)); AddCodeLine ("clc"); AddCodeLine ("adc sp"); AddCodeLine ("sta sp"); - AddCodeLine ("lda %s+1", LocalLabelName (label)); + AddCodeLine ("lda %s+1", LocalDataLabelName (label)); AddCodeLine ("adc sp+1"); AddCodeLine ("sta sp+1"); AddCodeLine ("pla"); diff --git a/src/cc65/declare.c b/src/cc65/declare.c index e81c761ed..d6286e62d 100644 --- a/src/cc65/declare.c +++ b/src/cc65/declare.c @@ -2204,6 +2204,11 @@ static void DefineData (ExprDesc* Expr) g_defdata (CF_REGVAR, Expr->Name, Expr->IVal); break; + case E_LOC_CODE: + /* Code label location */ + g_defdata (CF_CODE, Expr->Name, Expr->IVal); + break; + case E_LOC_STACK: case E_LOC_PRIMARY: case E_LOC_EXPR: diff --git a/src/cc65/expr.c b/src/cc65/expr.c index d1dfa62ec..44b0f49be 100644 --- a/src/cc65/expr.c +++ b/src/cc65/expr.c @@ -92,6 +92,7 @@ static unsigned GlobalModeFlags (const ExprDesc* Expr) case E_LOC_PRIMARY: return CF_PRIMARY; case E_LOC_EXPR: return CF_EXPR; case E_LOC_LITERAL: return CF_LITERAL; + case E_LOC_CODE: return CF_CODE; default: Internal ("GlobalModeFlags: Invalid location flags value: 0x%04X", Expr->Flags); /* NOTREACHED */ @@ -794,7 +795,7 @@ static void Primary (ExprDesc* E) NextToken (); Entry = AddLabelSym (CurTok.Ident, SC_REF | SC_GOTO_IND); /* 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->Type = PointerTo (type_void); NextToken (); @@ -1545,7 +1546,8 @@ void Store (ExprDesc* Expr, const Type* StoreType) case E_LOC_STATIC: 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); break; @@ -1624,7 +1626,8 @@ static void PreInc (ExprDesc* Expr) case E_LOC_STATIC: 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); break; @@ -1700,7 +1703,8 @@ static void PreDec (ExprDesc* Expr) case E_LOC_STATIC: 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); break; @@ -3878,7 +3882,8 @@ static void addsubeq (const GenDesc* Gen, ExprDesc *Expr, const char* Op) case E_LOC_STATIC: 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) { g_addeqstatic (lflags, Expr->Name, Expr->IVal, Expr2.IVal); } else { diff --git a/src/cc65/exprdesc.c b/src/cc65/exprdesc.c index b9b5ba5fb..62738bed7 100644 --- a/src/cc65/exprdesc.c +++ b/src/cc65/exprdesc.c @@ -196,6 +196,15 @@ const char* ED_GetLabelName (const ExprDesc* Expr, long Offs) } 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: 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; Sep = ','; } - if (Flags & E_RTYPE_LVAL) { - fprintf (F, "%cE_RTYPE_LVAL", Sep); - Flags &= ~E_RTYPE_LVAL; + if (Flags & E_LOC_CODE) { + fprintf (F, "%cE_LOC_CODE", Sep); + Flags &= ~E_LOC_CODE; Sep = ','; } if (Flags & E_BITFIELD) { @@ -523,6 +532,11 @@ void PrintExprDesc (FILE* F, ExprDesc* E) Flags &= ~E_CC_SET; Sep = ','; } + if (Flags & E_RTYPE_LVAL) { + fprintf (F, "%cE_RTYPE_LVAL", Sep); + Flags &= ~E_RTYPE_LVAL; + Sep = ','; + } if (Flags & E_ADDRESS_OF) { fprintf (F, "%cE_ADDRESS_OF", Sep); Flags &= ~E_ADDRESS_OF; diff --git a/src/cc65/loadexpr.c b/src/cc65/loadexpr.c index 07acb3cbc..95617f596 100644 --- a/src/cc65/loadexpr.c +++ b/src/cc65/loadexpr.c @@ -83,6 +83,11 @@ static void LoadAddress (unsigned Flags, ExprDesc* Expr) g_getimmed ((Flags | CF_REGVAR) & ~CF_CONST, Expr->Name, Expr->IVal); 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: g_leasp (Expr->IVal); break; @@ -201,6 +206,11 @@ void LoadExpr (unsigned Flags, struct ExprDesc* Expr) g_getstatic (Flags | CF_REGVAR, Expr->Name, Expr->IVal); break; + case E_LOC_CODE: + /* Code label location */ + g_getstatic (Flags | CF_CODE, Expr->Name, Expr->IVal); + break; + case E_LOC_STACK: /* Value on the stack */ g_getlocal (Flags, Expr->IVal); diff --git a/src/cc65/locals.c b/src/cc65/locals.c index 255a23b6d..81d0cea09 100644 --- a/src/cc65/locals.c +++ b/src/cc65/locals.c @@ -64,31 +64,31 @@ 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 */ UseSeg (); /* Define the variable label */ - Label = GetLocalLabel (); - g_defdatalabel (Label); + DataLabel = GetLocalDataLabel (); + g_defdatalabel (DataLabel); /* Return the label */ - return Label; + return DataLabel; } -static void AllocStorage (unsigned Label, void (*UseSeg) (), unsigned Size) -/* Reserve Size bytes of BSS storage prefixed by a local label. */ +static void AllocStorage (unsigned DataLabel, void (*UseSeg) (), unsigned Size) +/* Reserve Size bytes of BSS storage prefixed by a local data label. */ { /* Switch to the segment */ UseSeg (); /* Define the variable label */ - g_defdatalabel (Label); + g_defdatalabel (DataLabel); /* Reserve space for the data */ g_res (Size); @@ -301,7 +301,7 @@ static void ParseAutoDecl (Declaration* Decl) Decl->StorageClass = (Decl->StorageClass & ~SC_AUTO) | SC_STATIC; /* Generate a label, but don't define it */ - DataLabel = GetLocalLabel (); + DataLabel = GetLocalDataLabel (); /* Add the symbol to the symbol table. */ Sym = AddLocalSym (Decl->Ident, Decl->Type, Decl->StorageClass, DataLabel); @@ -380,7 +380,7 @@ static void ParseStaticDecl (Declaration* Decl) unsigned Size; /* Generate a label, but don't define it */ - unsigned DataLabel = GetLocalLabel (); + unsigned DataLabel = GetLocalDataLabel (); /* Add the symbol to the symbol table. */ SymEntry* Sym = AddLocalSym (Decl->Ident, Decl->Type, diff --git a/src/cc65/symtab.c b/src/cc65/symtab.c index 6a02fc0ce..10dc0d3ff 100644 --- a/src/cc65/symtab.c +++ b/src/cc65/symtab.c @@ -931,7 +931,7 @@ DefOrRef* AddDefOrRef (SymEntry* E, unsigned Flags) DOR->Flags = Flags; DOR->StackPtr = StackPtr; DOR->Depth = CollCount (&CurrentFunc->LocalsBlockStack); - DOR->LateSP_Label = GetLocalLabel (); + DOR->LateSP_Label = GetLocalDataLabel (); return DOR; } @@ -953,7 +953,7 @@ unsigned short FindSPAdjustment (const char* Name) 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; 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 ** 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; AddSymEntry (SPAdjustTab, E); } @@ -1134,9 +1134,9 @@ SymEntry* AddLocalSym (const char* Name, const Type* T, unsigned Flags, int Offs Entry->V.L.Label = Offs; SymSetAsmName (Entry); } 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->AsmName = xstrdup (LocalLabelName (Entry->V.L.Label)); + Entry->AsmName = xstrdup (LocalDataLabelName (Entry->V.L.Label)); } else { Internal ("Invalid flags in AddLocalSym: %04X", Flags); }