Don't use SF_TRAMPOLINE, change symbol references instead.

In smart mode, use RTL instead of RTS if the enclosing .PROC is far.
More address size changes.


git-svn-id: svn://svn.cc65.org/cc65/trunk@2696 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2003-11-29 07:53:26 +00:00
parent 05f3f154a9
commit c5cc4e1536
12 changed files with 365 additions and 390 deletions

View File

@@ -64,9 +64,7 @@
/* Combined symbol entry flags used within this module */
#define SF_UNDEFMASK (SF_REFERENCED | SF_DEFINED | SF_IMPORT)
#define SF_UNDEFVAL (SF_REFERENCED)
#define SF_EXPMASK (SF_TRAMPOLINE | SF_EXPORT)
#define SF_EXPVAL (SF_EXPORT)
#define SF_DBGINFOMASK (SF_TRAMPOLINE | SF_DEFINED | SF_EXPORT | SF_IMPORT)
#define SF_DBGINFOMASK (SF_UNUSED | SF_DEFINED | SF_EXPORT | SF_IMPORT)
#define SF_DBGINFOVAL (SF_DEFINED)
/* Symbol tables */
@@ -74,8 +72,8 @@ SymTable* CurrentScope = 0; /* Pointer to current symbol table */
SymTable* RootScope = 0; /* Root symbol table */
/* Symbol table variables */
static unsigned ImportCount = 0;/* Counter for import symbols */
static unsigned ExportCount = 0;/* Counter for export symbols */
static unsigned ImportCount = 0; /* Counter for import symbols */
static unsigned ExportCount = 0; /* Counter for export symbols */
@@ -257,6 +255,54 @@ SymTable* SymFindAnyScope (SymTable* Parent, const char* Name)
SymEntry* SymFindLocal (const char* Name, int AllocNew)
/* Find a cheap local symbol. If AllocNew is given and the entry is not
* found, create a new one. Return the entry found, or the new entry created,
* or - in case AllocNew is zero - return 0.
*/
{
SymEntry* S;
int Cmp;
/* Local symbol, get the table */
if (!SymLast) {
/* No last global, so there's no local table */
Error ("No preceeding global symbol");
if (AllocNew) {
return NewSymEntry (Name);
} else {
return 0;
}
}
/* Search for the symbol if we have a table */
Cmp = SymSearchTree (SymLast->Locals, Name, &S);
/* If we found an entry, return it */
if (Cmp == 0) {
return S;
}
if (AllocNew) {
/* Otherwise create a new entry, insert and return it */
SymEntry* N = NewSymEntry (Name);
if (S == 0) {
SymLast->Locals = N;
} else if (Cmp < 0) {
S->Left = N;
} else {
S->Right = N;
}
return N;
}
/* We did not find the entry and AllocNew is false. */
return 0;
}
SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
/* Find a new symbol table entry in the given table. If AllocNew is given and
* the entry is not found, create a new one. Return the entry found, or the
@@ -264,78 +310,33 @@ SymEntry* SymFind (SymTable* Scope, const char* Name, int AllocNew)
*/
{
SymEntry* S;
int Cmp;
if (IsLocalName (Name)) {
/* Global symbol: Get the hash value for the name */
unsigned Hash = HashStr (Name) % Scope->TableSlots;
/* Local symbol, get the table */
if (!SymLast) {
/* No last global, so there's no local table */
Error ("No preceeding global symbol");
if (AllocNew) {
return NewSymEntry (Name);
} else {
return 0;
}
}
/* Search for the entry */
int Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);
/* Search for the symbol if we have a table */
Cmp = SymSearchTree (SymLast->Locals, Name, &S);
/* If we found an entry, return it */
if (Cmp == 0) {
return S;
}
/* If we found an entry, return it */
if (Cmp == 0) {
return S;
}
if (AllocNew) {
if (AllocNew) {
/* Otherwise create a new entry, insert and return it */
SymEntry* N = NewSymEntry (Name);
if (S == 0) {
Scope->Table[Hash] = N;
} else if (Cmp < 0) {
S->Left = N;
} else {
S->Right = N;
}
N->SymTab = Scope;
++Scope->TableEntries;
return N;
/* Otherwise create a new entry, insert and return it */
SymEntry* N = NewSymEntry (Name);
if (S == 0) {
SymLast->Locals = N;
} else if (Cmp < 0) {
S->Left = N;
} else {
S->Right = N;
}
return N;
}
} else {
/* Global symbol: Get the hash value for the name */
unsigned Hash = HashStr (Name) % Scope->TableSlots;
/* Search for the entry */
Cmp = SymSearchTree (Scope->Table[Hash], Name, &S);
/* If we found an entry, return it */
if (Cmp == 0) {
/* Check for a trampoline entry, in this case return the real
* symbol.
*/
while (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
return S;
}
if (AllocNew) {
/* Otherwise create a new entry, insert and return it */
SymEntry* N = NewSymEntry (Name);
if (S == 0) {
Scope->Table[Hash] = N;
} else if (Cmp < 0) {
S->Left = N;
} else {
S->Right = N;
}
N->SymTab = Scope;
++Scope->TableEntries;
return N;
}
}
/* We did not find the entry and AllocNew is false. */
@@ -372,11 +373,6 @@ static SymEntry* SymFindAny (SymTable* Scope, const char* Name)
int SymIsZP (SymEntry* S)
/* Return true if the symbol is explicitly marked as zeropage symbol */
{
/* Resolve trampoline entries */
if (S->Flags & SF_TRAMPOLINE) {
S = S->V.Sym;
}
/* If the symbol is not a global symbol, was not defined before, check the
* enclosing scope for a symbol with the same name, and return the ZP
* attribute of this symbol if we find one.
@@ -443,28 +439,50 @@ static void SymCheckUndefined (SymEntry* S)
}
}
}
if (Sym) {
/* We found the symbol in a higher level. Make S a trampoline
* symbol. Beware: We have to transfer the symbol attributes to
* the real symbol and check for any conflicts.
*/
S->Flags |= SF_TRAMPOLINE;
S->V.Sym = Sym;
/* Transfer the flags. Note: S may not be imported, since in that
* case it wouldn't be undefined.
*/
if (S->Flags & SF_EXPORT) {
/* We found the symbol in a higher level. Transfer the flags and
* address size from the local symbol to that in the higher level
* and check for problems.
*/
if (S->Flags & SF_EXPORT) {
if (Sym->Flags & SF_IMPORT) {
/* The symbol is already marked as imported external symbol */
PError (&S->Pos, "Symbol `%s' is already an import", GetString (S->Name));
/* The symbol is already marked as import */
PError (&S->Pos, "Symbol `%s' is already an import",
GetString (Sym->Name));
}
Sym->Flags |= (S->Flags & SF_EXPORT);
Sym->ExportSize = S->ExportSize;
}
if (Sym->Flags & SF_EXPORT) {
/* The symbol is already marked as an export. */
if (Sym->AddrSize > S->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
AddrSizeToStr (S->ExportSize));
}
} else {
/* Mark the symbol as an export */
Sym->Flags |= SF_EXPORT;
Sym->ExportSize = S->ExportSize;
if (Sym->ExportSize == ADDR_SIZE_DEFAULT) {
/* Use the actual size of the symbol */
Sym->ExportSize = Sym->AddrSize;
}
if (Sym->AddrSize > Sym->ExportSize) {
/* We're exporting a symbol smaller than it actually is */
PWarning (&S->Pos, 1, "Symbol `%s' is %s but exported %s",
GetSymName (Sym), AddrSizeToStr (Sym->AddrSize),
AddrSizeToStr (Sym->ExportSize));
}
}
}
Sym->Flags |= (S->Flags & SF_REFERENCED);
/* Transfer the referenced flag */
Sym->Flags |= (S->Flags & SF_REFERENCED);
/* Transfer all expression references */
SymTransferExprRefs (S, Sym);
/* Mark the symbol as unused removing all other flags */
S->Flags = SF_UNUSED;
} else {
/* The symbol is definitely undefined */
@@ -474,12 +492,12 @@ static void SymCheckUndefined (SymEntry* S)
GetString (S->Name));
} else {
if (AutoImport) {
/* Mark as import, will be indexed later */
S->Flags |= SF_IMPORT;
/* Mark as import, will be indexed later */
S->Flags |= SF_IMPORT;
/* Use the address size for code */
S->AddrSize = CodeAddrSize;
} else {
/* Error */
/* Error */
PError (&S->Pos, "Symbol `%s' is undefined", GetString (S->Name));
}
}
@@ -509,9 +527,9 @@ void SymCheck (void)
if (S->Flags & SF_GLOBAL) {
S->Flags &= ~SF_GLOBAL;
if (S->Flags & SF_DEFINED) {
S->Flags |= SF_EXPORT;
S->Flags |= SF_EXPORT;
} else {
S->Flags |= SF_IMPORT;
S->Flags |= SF_IMPORT;
}
}
@@ -526,35 +544,35 @@ void SymCheck (void)
}
/* Second pass: Walk again through the symbols. Ignore undefined's, since
* we handled them in the last pass, and ignore trampoline symbols, since
* we handled them in the last pass, and ignore unused symbols, since
* we handled them in the last pass, too.
*/
S = SymList;
while (S) {
if ((S->Flags & SF_TRAMPOLINE) == 0 &&
if ((S->Flags & SF_UNUSED) == 0 &&
(S->Flags & SF_UNDEFMASK) != SF_UNDEFVAL) {
if ((S->Flags & SF_DEFINED) != 0 && (S->Flags & SF_REFERENCED) == 0) {
/* Symbol was defined but never referenced */
PWarning (&S->Pos, 2,
/* Symbol was defined but never referenced */
PWarning (&S->Pos, 2,
"Symbol `%s' is defined but never used",
GetString (S->Name));
}
if (S->Flags & SF_IMPORT) {
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
/* Imported symbol is not referenced */
PWarning (&S->Pos, 2,
if ((S->Flags & (SF_REFERENCED | SF_FORCED)) == SF_NONE) {
/* Imported symbol is not referenced */
PWarning (&S->Pos, 2,
"Symbol `%s' is imported but never used",
GetString (S->Name));
} else {
/* Give the import an index, count imports */
S->Index = ImportCount++;
S->Flags |= SF_INDEXED;
}
} else {
/* Give the import an index, count imports */
S->Index = ImportCount++;
S->Flags |= SF_INDEXED;
}
}
if (S->Flags & SF_EXPORT) {
/* Give the export an index, count exports */
S->Index = ExportCount++;
S->Flags |= SF_INDEXED;
/* Give the export an index, count exports */
S->Index = ExportCount++;
S->Flags |= SF_INDEXED;
}
}
@@ -571,8 +589,8 @@ void SymDump (FILE* F)
SymEntry* S = SymList;
while (S) {
/* Ignore trampoline symbols */
if ((S->Flags & SF_TRAMPOLINE) != 0) {
/* Ignore unused symbols */
if ((S->Flags & SF_UNUSED) != 0) {
fprintf (F,
"%-24s %s %s %s %s %s\n",
GetString (S->Name),
@@ -607,7 +625,7 @@ void WriteImports (void)
*/
S = SymList;
while (S) {
if ((S->Flags & (SF_TRAMPOLINE | SF_IMPORT)) == SF_IMPORT &&
if ((S->Flags & (SF_UNUSED | SF_IMPORT)) == SF_IMPORT &&
(S->Flags & (SF_REFERENCED | SF_FORCED)) != 0) {
ObjWrite8 (S->AddrSize);
@@ -638,7 +656,7 @@ void WriteExports (void)
/* Walk throught list and write all exports to the file */
S = SymList;
while (S) {
if ((S->Flags & SF_EXPMASK) == SF_EXPVAL) {
if ((S->Flags & (SF_UNUSED | SF_EXPORT)) == SF_EXPORT) {
long ConstVal;