1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 06:25:17 +00:00

Working on the new backend

git-svn-id: svn://svn.cc65.org/cc65/trunk@715 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2001-05-05 13:51:42 +00:00
parent e8174aaa25
commit e6484f85c7
21 changed files with 1212 additions and 1055 deletions

View File

@@ -40,6 +40,7 @@
#include "codeopt.h" #include "codeopt.h"
#include "codeseg.h" #include "codeseg.h"
#include "dataseg.h" #include "dataseg.h"
#include "segments.h"
#include "symtab.h" #include "symtab.h"
#include "asmcode.h" #include "asmcode.h"
@@ -62,7 +63,7 @@ void AddCodeHint (const char* Hint)
CodeMark GetCodePos (void) CodeMark GetCodePos (void)
/* Get a marker pointing to the current output position */ /* Get a marker pointing to the current output position */
{ {
return GetCodeSegEntries (CS); return GetCodeSegEntries (CS->Code);
} }
@@ -70,22 +71,7 @@ CodeMark GetCodePos (void)
void RemoveCode (CodeMark M) void RemoveCode (CodeMark M)
/* Remove all code after the given code marker */ /* Remove all code after the given code marker */
{ {
DelCodeSegAfter (CS, M); DelCodeSegAfter (CS->Code, M);
}
static void PrintFunctionHeader (FILE* F, SymEntry* Entry)
{
/* Print a comment with the function signature */
fprintf (F,
"; ---------------------------------------------------------------\n"
"; ");
PrintFuncSig (F, Entry->Name, Entry->Type);
fprintf (F,
"\n"
"; ---------------------------------------------------------------\n"
"\n");
} }
@@ -96,9 +82,9 @@ void WriteOutput (FILE* F)
SymTable* SymTab; SymTable* SymTab;
SymEntry* Entry; SymEntry* Entry;
/* Output the data segment (the global code segment should be empty) */ /* Output the global data segment */
OutputDataSeg (F, DS); CHECK (GetCodeSegEntries (CS->Code) == 0);
CHECK (GetCodeSegEntries (CS) == 0); OutputSegments (CS, F);
/* Output all global or referenced functions */ /* Output all global or referenced functions */
SymTab = GetGlobalSymTab (); SymTab = GetGlobalSymTab ();
@@ -108,13 +94,9 @@ void WriteOutput (FILE* F)
(Entry->Flags & SC_DEF) != 0 && (Entry->Flags & SC_DEF) != 0 &&
(Entry->Flags & (SC_REF | SC_EXTERN)) != 0) { (Entry->Flags & (SC_REF | SC_EXTERN)) != 0) {
/* Function which is defined and referenced or extern */ /* Function which is defined and referenced or extern */
PrintFunctionHeader (F, Entry); MergeCodeLabels (Entry->V.F.Seg->Code);
MergeCodeLabels (Entry->V.F.CS); RunOpt (Entry->V.F.Seg->Code);
RunOpt (Entry->V.F.CS); OutputSegments (Entry->V.F.Seg, F);
fprintf (F, "; Data segment for function %s:\n", Entry->Name);
OutputDataSeg (F, Entry->V.F.DS);
fprintf (F, "; Code segment for function %s:\n", Entry->Name);
OutputCodeSeg (F, Entry->V.F.CS);
} }
Entry = Entry->NextSym; Entry = Entry->NextSym;
} }

View File

@@ -119,7 +119,7 @@ int CodeEntryHasLabel (const CodeEntry* E)
void OutputCodeEntry (FILE* F, const CodeEntry* E) void OutputCodeEntry (const CodeEntry* E, FILE* F)
/* Output the code entry to a file */ /* Output the code entry to a file */
{ {
const OPCDesc* D; const OPCDesc* D;
@@ -129,7 +129,7 @@ void OutputCodeEntry (FILE* F, const CodeEntry* E)
unsigned LabelCount = CollCount (&E->Labels); unsigned LabelCount = CollCount (&E->Labels);
unsigned I; unsigned I;
for (I = 0; I < LabelCount; ++I) { for (I = 0; I < LabelCount; ++I) {
OutputCodeLabel (F, CollConstAt (&E->Labels, I)); OutputCodeLabel (CollConstAt (&E->Labels, I), F);
} }
/* Get the opcode description */ /* Get the opcode description */

View File

@@ -91,7 +91,7 @@ void FreeCodeEntry (CodeEntry* E);
int CodeEntryHasLabel (const CodeEntry* E); int CodeEntryHasLabel (const CodeEntry* E);
/* Check if the given code entry has labels attached */ /* Check if the given code entry has labels attached */
void OutputCodeEntry (FILE* F, const CodeEntry* E); void OutputCodeEntry (const CodeEntry* E, FILE* F);
/* Output the code entry to a file */ /* Output the code entry to a file */

File diff suppressed because it is too large Load Diff

View File

@@ -38,14 +38,8 @@
/*****************************************************************************/ /* cc65 */
/* Forwards */ #include "segments.h"
/*****************************************************************************/
struct CodeSeg;
struct DataSeg;
@@ -109,12 +103,6 @@ void g_preamble (void);
void g_pushseg (struct CodeSeg** CS, struct DataSeg** DS, const char* FuncName);
/* Push the current segments and generate new ones for the given function */
void g_popseg (void);
/* Restore the old segments */
void g_userodata (void); void g_userodata (void);
/* Switch to the read only data segment */ /* Switch to the read only data segment */
@@ -124,18 +112,6 @@ void g_usedata (void);
void g_usebss (void); void g_usebss (void);
/* Switch to the bss segment */ /* Switch to the bss segment */
void g_codename (const char* Name);
/* Set the name of the CODE segment */
void g_rodataname (const char* Name);
/* Set the name of the RODATA segment */
void g_dataname (const char* Name);
/* Set the name of the DATA segment */
void g_bssname (const char* Name);
/* Set the name of the BSS segment */
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -36,7 +36,7 @@
/* common */ /* common */
#include "xmalloc.h" #include "xmalloc.h"
/* cc65 */ /* cc65 */
#include "codeent.h" #include "codeent.h"
#include "codelab.h" #include "codelab.h"
@@ -107,7 +107,7 @@ unsigned RemoveLabelRef (CodeLabel* L, const struct CodeEntry* E)
void OutputCodeLabel (FILE* F, const CodeLabel* L) void OutputCodeLabel (const CodeLabel* L, FILE* F)
/* Output the code label to a file */ /* Output the code label to a file */
{ {
fprintf (F, "%s:", L->Name); fprintf (F, "%s:", L->Name);

View File

@@ -95,7 +95,7 @@ void AddLabelRef (CodeLabel* L, struct CodeEntry* E);
unsigned RemoveLabelRef (CodeLabel* L, const struct CodeEntry* E); unsigned RemoveLabelRef (CodeLabel* L, const struct CodeEntry* E);
/* Remove a reference to this label, return the number of remaining references */ /* Remove a reference to this label, return the number of remaining references */
void OutputCodeLabel (FILE* F, const CodeLabel* L); void OutputCodeLabel (const CodeLabel* L, FILE* F);
/* Output the code label to a file */ /* Output the code label to a file */

View File

@@ -88,7 +88,7 @@ static void OptDeadJumps (CodeSeg* S)
if (E->AM == AM_BRA && E->JumpTo && E->JumpTo->Owner == CollAt (&S->Entries, I+1)) { if (E->AM == AM_BRA && E->JumpTo && E->JumpTo->Owner == CollAt (&S->Entries, I+1)) {
/* Delete the dead jump */ /* Delete the dead jump */
DelCodeSegLine (S, I); DelCodeEntry (S, I);
/* Keep the number of entries updated */ /* Keep the number of entries updated */
--Count; --Count;
@@ -140,7 +140,7 @@ static void OptDeadCode (CodeSeg* S)
!CodeEntryHasLabel (CollAt (&S->Entries, I+1))) { !CodeEntryHasLabel (CollAt (&S->Entries, I+1))) {
/* Delete the next entry */ /* Delete the next entry */
DelCodeSegLine (S, I+1); DelCodeEntry (S, I+1);
/* Keep the number of entries updated */ /* Keep the number of entries updated */
--Count; --Count;

View File

@@ -52,17 +52,6 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Pointer to current code segment */
CodeSeg* CS = 0;
/*****************************************************************************/ /*****************************************************************************/
/* Functions for parsing instructions */ /* Functions for parsing instructions */
/*****************************************************************************/ /*****************************************************************************/
@@ -309,7 +298,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L)
CodeSeg* NewCodeSeg (const char* SegName, const char* FuncName) CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func)
/* Create a new code segment, initialize and return it */ /* Create a new code segment, initialize and return it */
{ {
unsigned I; unsigned I;
@@ -318,9 +307,8 @@ CodeSeg* NewCodeSeg (const char* SegName, const char* FuncName)
CodeSeg* S = xmalloc (sizeof (CodeSeg)); CodeSeg* S = xmalloc (sizeof (CodeSeg));
/* Initialize the fields */ /* Initialize the fields */
S->Next = 0;
S->SegName = xstrdup (SegName); S->SegName = xstrdup (SegName);
S->FuncName = xstrdup (FuncName); S->Func = Func;
InitCollection (&S->Entries); InitCollection (&S->Entries);
InitCollection (&S->Labels); InitCollection (&S->Labels);
for (I = 0; I < sizeof(S->LabelHash) / sizeof(S->LabelHash[0]); ++I) { for (I = 0; I < sizeof(S->LabelHash) / sizeof(S->LabelHash[0]); ++I) {
@@ -336,39 +324,12 @@ CodeSeg* NewCodeSeg (const char* SegName, const char* FuncName)
void FreeCodeSeg (CodeSeg* S) void FreeCodeSeg (CodeSeg* S)
/* Free a code segment including all code entries */ /* Free a code segment including all code entries */
{ {
FAIL ("Not implemented"); Internal ("Not implemented");
} }
void PushCodeSeg (CodeSeg* S) void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap)
/* Push the given code segment onto the stack */
{
S->Next = CS;
CS = S;
}
CodeSeg* PopCodeSeg (void)
/* Remove the current code segment from the stack and return it */
{
/* Remember the current code segment */
CodeSeg* S = CS;
/* Cannot pop on empty stack */
PRECONDITION (S != 0);
/* Pop */
CS = S->Next;
/* Return the popped code segment */
return S;
}
void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
/* Add a line to the given code segment */ /* Add a line to the given code segment */
{ {
const char* L; const char* L;
@@ -376,11 +337,8 @@ void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
char Token[64]; char Token[64];
/* Format the line */ /* Format the line */
va_list ap;
char Buf [256]; char Buf [256];
va_start (ap, Format);
xvsprintf (Buf, sizeof (Buf), Format, ap); xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
/* Skip whitespace */ /* Skip whitespace */
L = SkipSpace (Buf); L = SkipSpace (Buf);
@@ -436,7 +394,7 @@ void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
void DelCodeSegLine (CodeSeg* S, unsigned Index) void DelCodeEntry (CodeSeg* S, unsigned Index)
/* Delete an entry from the code segment. This includes deleting any associated /* Delete an entry from the code segment. This includes deleting any associated
* labels, removing references to labels and even removing the referenced labels * labels, removing references to labels and even removing the referenced labels
* if the reference count drops to zero. * if the reference count drops to zero.
@@ -592,7 +550,7 @@ void DelCodeSegAfter (CodeSeg* S, unsigned Last)
void OutputCodeSeg (FILE* F, const CodeSeg* S) void OutputCodeSeg (const CodeSeg* S, FILE* F)
/* Output the code segment data to a file */ /* Output the code segment data to a file */
{ {
unsigned I; unsigned I;
@@ -600,31 +558,26 @@ void OutputCodeSeg (FILE* F, const CodeSeg* S)
/* Get the number of entries in this segment */ /* Get the number of entries in this segment */
unsigned Count = CollCount (&S->Entries); unsigned Count = CollCount (&S->Entries);
fprintf (F, "; Labels: "); /* If the code segment is empty, bail out here */
for (I = 0; I < CS_LABEL_HASH_SIZE; ++I) { if (Count == 0) {
const CodeLabel* L = S->LabelHash[I]; return;
while (L) {
fprintf (F, "%s ", L->Name);
L = L->Next;
}
} }
fprintf (F, "\n");
/* Output the segment directive */ /* Output the segment directive */
fprintf (F, ".segment\t\"%s\"\n\n", S->SegName); fprintf (F, ".segment\t\"%s\"\n\n", S->SegName);
/* If this is a segment for a function, enter a function */ /* If this is a segment for a function, enter a function */
if (S->FuncName[0] != '\0') { if (S->Func) {
fprintf (F, ".proc\t_%s\n\n", S->FuncName); fprintf (F, ".proc\t_%s\n\n", S->Func->Name);
} }
/* Output all entries */ /* Output all entries */
for (I = 0; I < Count; ++I) { for (I = 0; I < Count; ++I) {
OutputCodeEntry (F, CollConstAt (&S->Entries, I)); OutputCodeEntry (CollConstAt (&S->Entries, I), F);
} }
/* If this is a segment for a function, leave the function */ /* If this is a segment for a function, leave the function */
if (S->FuncName[0] != '\0') { if (S->Func) {
fprintf (F, "\n.endproc\n\n"); fprintf (F, "\n.endproc\n\n");
} }
} }

View File

@@ -37,7 +37,8 @@
#define CODESEG_H #define CODESEG_H
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
/* common */ /* common */
@@ -46,11 +47,12 @@
/* cc65 */ /* cc65 */
#include "codelab.h" #include "codelab.h"
#include "symentry.h"
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
@@ -61,41 +63,31 @@
/* Code segment structure */ /* Code segment structure */
typedef struct CodeSeg CodeSeg; typedef struct CodeSeg CodeSeg;
struct CodeSeg { struct CodeSeg {
CodeSeg* Next; /* Pointer to next CodeSeg */
char* SegName; /* Segment name */ char* SegName; /* Segment name */
char* FuncName; /* Name of function */ SymEntry* Func; /* Owner function */
Collection Entries; /* List of code entries */ Collection Entries; /* List of code entries */
Collection Labels; /* Labels for next insn */ Collection Labels; /* Labels for next insn */
CodeLabel* LabelHash [CS_LABEL_HASH_SIZE]; /* Label hash table */ CodeLabel* LabelHash [CS_LABEL_HASH_SIZE]; /* Label hash table */
}; };
/* Pointer to current code segment */
extern CodeSeg* CS;
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
CodeSeg* NewCodeSeg (const char* SegName, const char* FuncName); CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func);
/* Create a new code segment, initialize and return it */ /* Create a new code segment, initialize and return it */
void FreeCodeSeg (CodeSeg* S); void FreeCodeSeg (CodeSeg* S);
/* Free a code segment including all code entries */ /* Free a code segment including all code entries */
void PushCodeSeg (CodeSeg* S); void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
/* Push the given code segment onto the stack */
CodeSeg* PopCodeSeg (void);
/* Remove the current code segment from the stack and return it */
void AddCodeSegLine (CodeSeg* S, const char* Format, ...) attribute ((format(printf,2,3)));
/* Add a line to the given code segment */ /* Add a line to the given code segment */
void DelCodeSegLine (CodeSeg* S, unsigned Index); void DelCodeEntry (CodeSeg* S, unsigned Index);
/* Delete an entry from the code segment. This includes deleting any associated /* Delete an entry from the code segment. This includes deleting any associated
* labels, removing references to labels and even removing the referenced labels * labels, removing references to labels and even removing the referenced labels
* if the reference count drops to zero. * if the reference count drops to zero.
@@ -113,7 +105,7 @@ void AddCodeSegHint (CodeSeg* S, unsigned Hint);
void DelCodeSegAfter (CodeSeg* S, unsigned Last); void DelCodeSegAfter (CodeSeg* S, unsigned Last);
/* Delete all entries including the given one */ /* Delete all entries including the given one */
void OutputCodeSeg (FILE* F, const CodeSeg* S); void OutputCodeSeg (const CodeSeg* S, FILE* F);
/* Output the code segment data to a file */ /* Output the code segment data to a file */
CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash); CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash);

View File

@@ -39,36 +39,26 @@
#include "xsprintf.h" #include "xsprintf.h"
/* cc65 */ /* cc65 */
#include "error.h"
#include "dataseg.h" #include "dataseg.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Pointer to current data segment */
DataSeg* DS = 0;
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/
DataSeg* NewDataSeg (const char* Name) DataSeg* NewDataSeg (const char* Name, SymEntry* Func)
/* Create a new data segment, initialize and return it */ /* Create a new data segment, initialize and return it */
{ {
/* Allocate memory */ /* Allocate memory */
DataSeg* S = xmalloc (sizeof (DataSeg)); DataSeg* S = xmalloc (sizeof (DataSeg));
/* Initialize the fields */ /* Initialize the fields */
S->Next = 0; S->SegName = xstrdup (Name);
S->Name = xstrdup (Name); S->Func = Func;
InitCollection (&S->Lines); InitCollection (&S->Lines);
/* Return the new struct */ /* Return the new struct */
@@ -80,50 +70,7 @@ DataSeg* NewDataSeg (const char* Name)
void FreeDataSeg (DataSeg* S) void FreeDataSeg (DataSeg* S)
/* Free a data segment including all line entries */ /* Free a data segment including all line entries */
{ {
unsigned I, Count; Internal ("Not implemented");
/* Free the name */
xfree (S->Name);
/* Free the lines */
Count = CollCount (&S->Lines);
for (I = 0; I < Count; ++I) {
xfree (CollAt (&S->Lines, I));
}
/* Free the collection */
DoneCollection (&S->Lines);
/* Free the struct */
xfree (S);
}
void PushDataSeg (DataSeg* S)
/* Push the given data segment onto the stack */
{
/* Push */
S->Next = DS;
DS = S;
}
DataSeg* PopDataSeg (void)
/* Remove the current data segment from the stack and return it */
{
/* Remember the current data segment */
DataSeg* S = DS;
/* Cannot pop on empty stack */
PRECONDITION (S != 0);
/* Pop */
DS = S->Next;
/* Return the popped data segment */
return S;
} }
@@ -142,16 +89,12 @@ void AppendDataSeg (DataSeg* Target, const DataSeg* Source)
void AddDataSegLine (DataSeg* S, const char* Format, ...) void AddDataEntry (DataSeg* S, const char* Format, va_list ap)
/* Add a line to the given data segment */ /* Add a line to the given data segment */
{ {
va_list ap;
char Buf [256];
/* Format the line */ /* Format the line */
va_start (ap, Format); char Buf [256];
xvsprintf (Buf, sizeof (Buf), Format, ap); xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
/* Add a copy to the data segment */ /* Add a copy to the data segment */
CollAppend (&S->Lines, xstrdup (Buf)); CollAppend (&S->Lines, xstrdup (Buf));
@@ -159,7 +102,7 @@ void AddDataSegLine (DataSeg* S, const char* Format, ...)
void OutputDataSeg (FILE* F, const DataSeg* S) void OutputDataSeg (const DataSeg* S, FILE* F)
/* Output the data segment data to a file */ /* Output the data segment data to a file */
{ {
unsigned I; unsigned I;
@@ -167,10 +110,21 @@ void OutputDataSeg (FILE* F, const DataSeg* S)
/* Get the number of entries in this segment */ /* Get the number of entries in this segment */
unsigned Count = CollCount (&S->Lines); unsigned Count = CollCount (&S->Lines);
/* If the segment is actually empty, bail out */
if (Count == 0) {
return;
}
/* Output the segment directive */
fprintf (F, ".segment\t\"%s\"\n\n", S->SegName);
/* Output all entries */ /* Output all entries */
for (I = 0; I < Count; ++I) { for (I = 0; I < Count; ++I) {
fprintf (F, "%s\n", (const char*) CollConstAt (&S->Lines, I)); fprintf (F, "%s\n", (const char*) CollConstAt (&S->Lines, I));
} }
/* Add an additional newline after the segment output */
fprintf (F, "\n");
} }

View File

@@ -38,30 +38,31 @@
#include <stdarg.h>
#include <stdio.h> #include <stdio.h>
/* common */ /* common */
#include "attrib.h" #include "attrib.h"
#include "coll.h" #include "coll.h"
/* cc65 */
#include "symentry.h"
/*****************************************************************************/ /*****************************************************************************/
/* Data */ /* Data */
/*****************************************************************************/ /*****************************************************************************/
typedef struct DataSeg DataSeg; typedef struct DataSeg DataSeg;
struct DataSeg { struct DataSeg {
DataSeg* Next; /* Pointer to next DataSeg */ char* SegName; /* Segment name */
char* Name; /* Segment name */ SymEntry* Func; /* Owner function */
Collection Lines; /* List of code lines */ Collection Lines; /* List of code lines */
}; };
/* Pointer to current data segment */
extern DataSeg* DS;
/*****************************************************************************/ /*****************************************************************************/
@@ -70,25 +71,19 @@ extern DataSeg* DS;
DataSeg* NewDataSeg (const char* Name); DataSeg* NewDataSeg (const char* SegName, SymEntry* Func);
/* Create a new data segment, initialize and return it */ /* Create a new data segment, initialize and return it */
void FreeDataSeg (DataSeg* S); void FreeDataSeg (DataSeg* S);
/* Free a data segment including all line entries */ /* Free a data segment including all line entries */
void PushDataSeg (DataSeg* S);
/* Push the given data segment onto the stack */
DataSeg* PopDataSeg (void);
/* Remove the current data segment from the stack and return it */
void AppendDataSeg (DataSeg* Target, const DataSeg* Source); void AppendDataSeg (DataSeg* Target, const DataSeg* Source);
/* Append the data from Source to Target. */ /* Append the data from Source to Target. */
void AddDataSegLine (DataSeg* S, const char* Format, ...) attribute ((format(printf,2,3))); void AddDataEntry (DataSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
/* Add a line to the given data segment */ /* Add a line to the given data segment */
void OutputDataSeg (FILE* F, const DataSeg* S); void OutputDataSeg (const DataSeg* S, FILE* F);
/* Output the data segment data to a file */ /* Output the data segment data to a file */

View File

@@ -47,6 +47,7 @@
#include "litpool.h" #include "litpool.h"
#include "locals.h" #include "locals.h"
#include "scanner.h" #include "scanner.h"
#include "segments.h"
#include "stmt.h" #include "stmt.h"
#include "symtab.h" #include "symtab.h"
#include "function.h" #include "function.h"
@@ -246,7 +247,7 @@ void NewFunc (SymEntry* Func)
InitRegVars (); InitRegVars ();
/* Allocate code and data segments for this function */ /* Allocate code and data segments for this function */
g_pushseg (&Func->V.F.CS, &Func->V.F.DS, Func->Name); Func->V.F.Seg = PushSegments (Func);
/* If this is a fastcall function, push the last parameter onto the stack */ /* If this is a fastcall function, push the last parameter onto the stack */
if (IsFastCallFunc (Func->Type) && D->ParamCount > 0) { if (IsFastCallFunc (Func->Type) && D->ParamCount > 0) {
@@ -336,7 +337,7 @@ void NewFunc (SymEntry* Func)
LeaveFunctionLevel (); LeaveFunctionLevel ();
/* Switch back to the old segments */ /* Switch back to the old segments */
g_popseg (); PopSegments ();
/* Reset the current function pointer */ /* Reset the current function pointer */
FreeFunction (CurrentFunc); FreeFunction (CurrentFunc);

View File

@@ -59,7 +59,7 @@
#include "input.h" #include "input.h"
#include "macrotab.h" #include "macrotab.h"
#include "scanner.h" #include "scanner.h"
#include "segname.h" #include "segments.h"

View File

@@ -56,14 +56,14 @@ OBJS = anonname.o \
opcodes.o \ opcodes.o \
preproc.o \ preproc.o \
pragma.o \ pragma.o \
scanner.o \ scanner.o \
segname.o \ segments.o \
stdfunc.o \ stdfunc.o \
stmt.o \ stmt.o \
symentry.o \ symentry.o \
symtab.o \ symtab.o \
typecmp.o \ typecmp.o \
util.o util.o
LIBS = $(COMMON)/common.a LIBS = $(COMMON)/common.a

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998-2000 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */
@@ -37,13 +37,12 @@
#include <string.h> #include <string.h>
/* cc65 */ /* cc65 */
#include "codegen.h"
#include "error.h" #include "error.h"
#include "expr.h" #include "expr.h"
#include "global.h" #include "global.h"
#include "litpool.h" #include "litpool.h"
#include "scanner.h" #include "scanner.h"
#include "segname.h" #include "segments.h"
#include "symtab.h" #include "symtab.h"
#include "pragma.h" #include "pragma.h"
@@ -138,7 +137,7 @@ static void StringPragma (void (*Func) (const char*))
static void SegNamePragma (void (*Func) (const char*)) static void SegNamePragma (segment_t Seg)
/* Handle a pragma that expects a segment name parameter */ /* Handle a pragma that expects a segment name parameter */
{ {
if (curtok != TOK_SCONST) { if (curtok != TOK_SCONST) {
@@ -150,8 +149,8 @@ static void SegNamePragma (void (*Func) (const char*))
/* Check if the name is valid */ /* Check if the name is valid */
if (ValidSegName (Name)) { if (ValidSegName (Name)) {
/* Call the given function to set the name */ /* Set the new name */
Func (Name); NewSegName (Seg, Name);
} else { } else {
@@ -216,7 +215,7 @@ void DoPragma (void)
switch (Pragma) { switch (Pragma) {
case PR_BSSSEG: case PR_BSSSEG:
SegNamePragma (g_bssname); SegNamePragma (SEG_BSS);
break; break;
case PR_CHECKSTACK: case PR_CHECKSTACK:
@@ -224,11 +223,11 @@ void DoPragma (void)
break; break;
case PR_CODESEG: case PR_CODESEG:
SegNamePragma (g_codename); SegNamePragma (SEG_CODE);
break; break;
case PR_DATASEG: case PR_DATASEG:
SegNamePragma (g_dataname); SegNamePragma (SEG_DATA);
break; break;
case PR_REGVARADDR: case PR_REGVARADDR:
@@ -236,7 +235,7 @@ void DoPragma (void)
break; break;
case PR_RODATASEG: case PR_RODATASEG:
SegNamePragma (g_rodataname); SegNamePragma (SEG_RODATA);
break; break;
case PR_SIGNEDCHARS: case PR_SIGNEDCHARS:

View File

@@ -6,10 +6,10 @@
/* */ /* */
/* */ /* */
/* */ /* */
/* (C) 1998 Ullrich von Bassewitz */ /* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */ /* Wacholderweg 14 */
/* D-70597 Stuttgart */ /* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */ /* EMail: uz@cc65.org */
/* */ /* */
/* */ /* */
/* This software is provided 'as-is', without any expressed or implied */ /* This software is provided 'as-is', without any expressed or implied */

250
src/cc65/segments.c Normal file
View File

@@ -0,0 +1,250 @@
/*****************************************************************************/
/* */
/* segments.c */
/* */
/* Lightweight segment management stuff */
/* */
/* */
/* */
/* (C) 2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#include <stdarg.h>
#include <string.h>
/* common */
#include "chartype.h"
#include "check.h"
#include "coll.h"
#include "xmalloc.h"
/* cc65 */
#include "codeseg.h"
#include "dataseg.h"
#include "segments.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Pointer to the current segment list. Output goes here. */
Segments* CS = 0;
/* Actual names for the segments */
static char* SegmentNames[SEG_COUNT];
/* We're using a collection for the stack instead of a linked list. Since
* functions may not be nested (at least in the current implementation), the
* maximum stack depth is 2, so there is not really a need for a better
* implementation.
*/
static Collection SegmentStack = STATIC_COLLECTION_INITIALIZER;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void InitSegNames (void)
/* Initialize the segment names */
{
SegmentNames [SEG_BSS] = xstrdup ("BSS");
SegmentNames [SEG_CODE] = xstrdup ("CODE");
SegmentNames [SEG_DATA] = xstrdup ("DATA");
SegmentNames [SEG_RODATA] = xstrdup ("RODATA");
}
void NewSegName (segment_t Seg, const char* Name)
/* Set a new name for a segment */
{
/* Free the old name and set a new one */
xfree (SegmentNames [Seg]);
SegmentNames [Seg] = xstrdup (Name);
}
int ValidSegName (const char* Name)
/* Return true if the given segment name is valid, return false otherwise */
{
/* Must start with '_' or a letter */
if ((*Name != '_' && !IsAlpha(*Name)) || strlen(Name) > 80) {
return 0;
}
/* Can have letters, digits or the underline */
while (*++Name) {
if (*Name != '_' && !IsAlNum(*Name)) {
return 0;
}
}
/* Name is ok */
return 1;
}
static Segments* NewSegments (SymEntry* Func)
/* Initialize a Segments structure (set all fields to NULL) */
{
/* Allocate memory */
Segments* S = xmalloc (sizeof (Segments));
/* Initialize the fields */
S->Code = NewCodeSeg (SegmentNames[SEG_CODE], Func);
S->Data = NewDataSeg (SegmentNames[SEG_DATA], Func);
S->ROData = NewDataSeg (SegmentNames[SEG_RODATA], Func);
S->BSS = NewDataSeg (SegmentNames[SEG_BSS], Func);
S->CurDSeg = SEG_DATA;
/* Return the new struct */
return S;
}
Segments* PushSegments (SymEntry* Func)
/* Make the new segment list current but remember the old one */
{
/* Push the current pointer onto the stack */
CollAppend (&SegmentStack, CS);
/* Create a new Segments structure */
CS = NewSegments (Func);
/* Return the new struct */
return CS;
}
void PopSegments (void)
/* Pop the old segment list (make it current) */
{
/* Must have something on the stack */
PRECONDITION (CollCount (&SegmentStack) > 0);
/* Pop the last segment and set it as current */
CS = CollPop (&SegmentStack);
}
void UseDataSeg (segment_t DSeg)
/* For the current segment list, use the data segment DSeg */
{
/* Check the input */
PRECONDITION (CS && DSeg != SEG_CODE);
/* Set the new segment to use */
CS->CurDSeg = DSeg;
}
struct DataSeg* GetDataSeg (void)
/* Return the current data segment */
{
PRECONDITION (CS != 0);
switch (CS->CurDSeg) {
case SEG_BSS: return CS->BSS;
case SEG_DATA: return CS->Data;
case SEG_RODATA: return CS->ROData;
default: FAIL ("Invalid data segment");
}
}
void AddCodeLine (const char* Format, ...)
/* Add a line of code to the current code segment */
{
va_list ap;
va_start (ap, Format);
CHECK (CS != 0);
AddCodeEntry (CS->Code, Format, ap);
va_end (ap);
}
void AddDataLine (const char* Format, ...)
/* Add a line of data to the current data segment */
{
va_list ap;
va_start (ap, Format);
CHECK (CS != 0);
AddDataEntry (GetDataSeg(), Format, ap);
va_end (ap);
}
static void PrintFunctionHeader (const SymEntry* Entry, FILE* F)
{
/* Print a comment with the function signature */
fprintf (F,
"; ---------------------------------------------------------------\n"
"; ");
PrintFuncSig (F, Entry->Name, Entry->Type);
fprintf (F,
"\n"
"; ---------------------------------------------------------------\n"
"\n");
}
void OutputSegments (const Segments* S, FILE* F)
/* Output the given segments to the file */
{
/* If the code segment is associated with a function, print a function header */
if (S->Code->Func) {
PrintFunctionHeader (S->Code->Func, F);
}
/* Output the three data segments */
OutputDataSeg (S->Data, F);
OutputDataSeg (S->ROData, F);
OutputDataSeg (S->BSS, F);
/* Output the code segment */
OutputCodeSeg (S->Code, F);
}

132
src/cc65/segments.h Normal file
View File

@@ -0,0 +1,132 @@
/*****************************************************************************/
/* */
/* segments.h */
/* */
/* Segment management */
/* */
/* */
/* */
/* (C) 2000-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/* warranty. In no event will the authors be held liable for any damages */
/* arising from the use of this software. */
/* */
/* Permission is granted to anyone to use this software for any purpose, */
/* including commercial applications, and to alter it and redistribute it */
/* freely, subject to the following restrictions: */
/* */
/* 1. The origin of this software must not be misrepresented; you must not */
/* claim that you wrote the original software. If you use this software */
/* in a product, an acknowledgment in the product documentation would be */
/* appreciated but is not required. */
/* 2. Altered source versions must be plainly marked as such, and must not */
/* be misrepresented as being the original software. */
/* 3. This notice may not be removed or altered from any source */
/* distribution. */
/* */
/*****************************************************************************/
#ifndef SEGMENTS_H
#define SEGMENTS_H
#include <stdio.h>
/* common */
#include "attrib.h"
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
struct CodeSeg;
struct DataSeg;
struct SymEntry;
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Segment types */
typedef enum segment_t {
SEG_CODE,
SEG_RODATA,
SEG_DATA,
SEG_BSS,
SEG_COUNT
} segment_t;
/* A list of all segments used when generating code */
typedef struct Segments Segments;
struct Segments {
struct CodeSeg* Code; /* Code segment */
struct DataSeg* Data; /* Data segment */
struct DataSeg* ROData; /* Readonly data segment */
struct DataSeg* BSS; /* Segment for uninitialized data */
segment_t CurDSeg; /* Current data segment */
};
/* Pointer to the current segment list. Output goes here. */
extern Segments* CS;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
void InitSegNames (void);
/* Initialize the segment names */
void NewSegName (segment_t Seg, const char* Name);
/* Set a new name for a segment */
int ValidSegName (const char* Name);
/* Return true if the given segment name is valid, return false otherwise */
Segments* PushSegments (struct SymEntry* Func);
/* Make the new segment list current but remember the old one */
void PopSegments (void);
/* Pop the old segment list (make it current) */
void UseDataSeg (segment_t DSeg);
/* For the current segment list, use the data segment DSeg */
struct DataSeg* GetDataSeg (void);
/* Return the current data segment */
void AddCodeLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Add a line of code to the current code segment */
void AddDataLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
/* Add a line of data to the current data segment */
void OutputSegments (const Segments* S, FILE* F);
/* Output the given segments to the file */
/* End of segments.h */
#endif

View File

@@ -40,27 +40,38 @@
#include <stdio.h> #include <stdio.h>
/* cc65 */
#include "datatype.h" #include "datatype.h"
/*****************************************************************************/ /*****************************************************************************/
/* struct SymEntry */ /* Forwards */
/*****************************************************************************/
struct Segments;
/*****************************************************************************/
/* struct SymEntry */
/*****************************************************************************/ /*****************************************************************************/
/* Storage classes and flags */ /* Storage classes and flags */
#define SC_AUTO 0x0001U #define SC_AUTO 0x0001U
#define SC_REGISTER 0x0002U /* Register variable, is in static storage */ #define SC_REGISTER 0x0002U /* Register variable, is in static storage */
#define SC_STATIC 0x0004U #define SC_STATIC 0x0004U
#define SC_EXTERN 0x0008U #define SC_EXTERN 0x0008U
#define SC_ENUM 0x0030U /* An enum (numeric constant) */ #define SC_ENUM 0x0030U /* An enum (numeric constant) */
#define SC_CONST 0x0020U /* A numeric constant with a type */ #define SC_CONST 0x0020U /* A numeric constant with a type */
#define SC_LABEL 0x0040U /* A goto label */ #define SC_LABEL 0x0040U /* A goto label */
#define SC_PARAM 0x0080U /* This is a function parameter */ #define SC_PARAM 0x0080U /* This is a function parameter */
#define SC_FUNC 0x0100U /* Function entry */ #define SC_FUNC 0x0100U /* Function entry */
#define SC_STORAGE 0x0400U /* Symbol with associated storage */ #define SC_STORAGE 0x0400U /* Symbol with associated storage */
#define SC_DEFAULT 0x0800U /* Flag: default storage class was used */ #define SC_DEFAULT 0x0800U /* Flag: default storage class was used */
@@ -83,7 +94,7 @@ struct SymEntry {
SymEntry* NextHash; /* Next entry in hash list */ SymEntry* NextHash; /* Next entry in hash list */
SymEntry* PrevSym; /* Previous symbol in dl list */ SymEntry* PrevSym; /* Previous symbol in dl list */
SymEntry* NextSym; /* Next symbol double linked list */ SymEntry* NextSym; /* Next symbol double linked list */
SymEntry* Link; /* General purpose single linked list */ SymEntry* Link; /* General purpose single linked list */
struct SymTable* Owner; /* Symbol table the symbol is in */ struct SymTable* Owner; /* Symbol table the symbol is in */
unsigned Flags; /* Symbol flags */ unsigned Flags; /* Symbol flags */
type* Type; /* Symbol type */ type* Type; /* Symbol type */
@@ -109,18 +120,17 @@ struct SymEntry {
/* Data for functions */ /* Data for functions */
struct { struct {
struct FuncDesc* Func; /* Function descriptor */ struct FuncDesc* Func; /* Function descriptor */
struct CodeSeg* CS; /* Code for function */ struct Segments* Seg; /* Segments for this function */
struct DataSeg* DS; /* Data segment for function */
} F; } F;
} V; } V;
char Name[1]; /* Name, dynamically allocated */ char Name[1]; /* Name, dynamically allocated */
}; };
/*****************************************************************************/ /*****************************************************************************/
/* Code */ /* Code */
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -744,8 +744,7 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
*/ */
if (IsFunc) { if (IsFunc) {
Entry->V.F.Func = GetFuncDesc (Entry->Type); Entry->V.F.Func = GetFuncDesc (Entry->Type);
Entry->V.F.CS = 0; Entry->V.F.Seg = 0;
Entry->V.F.DS = 0;
} }
/* Add the entry to the symbol table */ /* Add the entry to the symbol table */