1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-26 20:29:34 +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 "codeseg.h"
#include "dataseg.h"
#include "segments.h"
#include "symtab.h"
#include "asmcode.h"
@ -62,7 +63,7 @@ void AddCodeHint (const char* Hint)
CodeMark GetCodePos (void)
/* 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)
/* Remove all code after the given code marker */
{
DelCodeSegAfter (CS, 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");
DelCodeSegAfter (CS->Code, M);
}
@ -96,9 +82,9 @@ void WriteOutput (FILE* F)
SymTable* SymTab;
SymEntry* Entry;
/* Output the data segment (the global code segment should be empty) */
OutputDataSeg (F, DS);
CHECK (GetCodeSegEntries (CS) == 0);
/* Output the global data segment */
CHECK (GetCodeSegEntries (CS->Code) == 0);
OutputSegments (CS, F);
/* Output all global or referenced functions */
SymTab = GetGlobalSymTab ();
@ -108,13 +94,9 @@ void WriteOutput (FILE* F)
(Entry->Flags & SC_DEF) != 0 &&
(Entry->Flags & (SC_REF | SC_EXTERN)) != 0) {
/* Function which is defined and referenced or extern */
PrintFunctionHeader (F, Entry);
MergeCodeLabels (Entry->V.F.CS);
RunOpt (Entry->V.F.CS);
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);
MergeCodeLabels (Entry->V.F.Seg->Code);
RunOpt (Entry->V.F.Seg->Code);
OutputSegments (Entry->V.F.Seg, F);
}
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 */
{
const OPCDesc* D;
@ -129,7 +129,7 @@ void OutputCodeEntry (FILE* F, const CodeEntry* E)
unsigned LabelCount = CollCount (&E->Labels);
unsigned I;
for (I = 0; I < LabelCount; ++I) {
OutputCodeLabel (F, CollConstAt (&E->Labels, I));
OutputCodeLabel (CollConstAt (&E->Labels, I), F);
}
/* Get the opcode description */

View File

@ -91,7 +91,7 @@ void FreeCodeEntry (CodeEntry* E);
int CodeEntryHasLabel (const CodeEntry* E);
/* 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 */

File diff suppressed because it is too large Load Diff

View File

@ -38,14 +38,8 @@
/*****************************************************************************/
/* Forwards */
/*****************************************************************************/
struct CodeSeg;
struct DataSeg;
/* cc65 */
#include "segments.h"
@ -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);
/* Switch to the read only data segment */
@ -124,18 +112,6 @@ void g_usedata (void);
void g_usebss (void);
/* 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 */
#include "xmalloc.h"
/* cc65 */
/* cc65 */
#include "codeent.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 */
{
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);
/* 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 */

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)) {
/* Delete the dead jump */
DelCodeSegLine (S, I);
DelCodeEntry (S, I);
/* Keep the number of entries updated */
--Count;
@ -140,7 +140,7 @@ static void OptDeadCode (CodeSeg* S)
!CodeEntryHasLabel (CollAt (&S->Entries, I+1))) {
/* Delete the next entry */
DelCodeSegLine (S, I+1);
DelCodeEntry (S, I+1);
/* Keep the number of entries updated */
--Count;

View File

@ -52,17 +52,6 @@
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Pointer to current code segment */
CodeSeg* CS = 0;
/*****************************************************************************/
/* 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 */
{
unsigned I;
@ -318,9 +307,8 @@ CodeSeg* NewCodeSeg (const char* SegName, const char* FuncName)
CodeSeg* S = xmalloc (sizeof (CodeSeg));
/* Initialize the fields */
S->Next = 0;
S->SegName = xstrdup (SegName);
S->FuncName = xstrdup (FuncName);
S->Func = Func;
InitCollection (&S->Entries);
InitCollection (&S->Labels);
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)
/* Free a code segment including all code entries */
{
FAIL ("Not implemented");
Internal ("Not implemented");
}
void PushCodeSeg (CodeSeg* S)
/* 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, ...)
void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap)
/* Add a line to the given code segment */
{
const char* L;
@ -376,11 +337,8 @@ void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
char Token[64];
/* Format the line */
va_list ap;
char Buf [256];
va_start (ap, Format);
xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
/* Skip whitespace */
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
* labels, removing references to labels and even removing the referenced labels
* 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 */
{
unsigned I;
@ -600,31 +558,26 @@ void OutputCodeSeg (FILE* F, const CodeSeg* S)
/* Get the number of entries in this segment */
unsigned Count = CollCount (&S->Entries);
fprintf (F, "; Labels: ");
for (I = 0; I < CS_LABEL_HASH_SIZE; ++I) {
const CodeLabel* L = S->LabelHash[I];
while (L) {
fprintf (F, "%s ", L->Name);
L = L->Next;
}
/* If the code segment is empty, bail out here */
if (Count == 0) {
return;
}
fprintf (F, "\n");
/* Output the segment directive */
fprintf (F, ".segment\t\"%s\"\n\n", S->SegName);
/* If this is a segment for a function, enter a function */
if (S->FuncName[0] != '\0') {
fprintf (F, ".proc\t_%s\n\n", S->FuncName);
if (S->Func) {
fprintf (F, ".proc\t_%s\n\n", S->Func->Name);
}
/* Output all entries */
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 (S->FuncName[0] != '\0') {
if (S->Func) {
fprintf (F, "\n.endproc\n\n");
}
}

View File

@ -37,7 +37,8 @@
#define CODESEG_H
#include <stdarg.h>
#include <stdio.h>
/* common */
@ -46,11 +47,12 @@
/* cc65 */
#include "codelab.h"
#include "symentry.h"
/*****************************************************************************/
/* Data */
/* Data */
/*****************************************************************************/
@ -61,41 +63,31 @@
/* Code segment structure */
typedef struct CodeSeg CodeSeg;
struct CodeSeg {
CodeSeg* Next; /* Pointer to next CodeSeg */
char* SegName; /* Segment name */
char* FuncName; /* Name of function */
SymEntry* Func; /* Owner function */
Collection Entries; /* List of code entries */
Collection Labels; /* Labels for next insn */
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 */
void FreeCodeSeg (CodeSeg* S);
/* Free a code segment including all code entries */
void PushCodeSeg (CodeSeg* S);
/* 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)));
void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
/* 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
* labels, removing references to labels and even removing the referenced labels
* if the reference count drops to zero.
@ -113,7 +105,7 @@ void AddCodeSegHint (CodeSeg* S, unsigned Hint);
void DelCodeSegAfter (CodeSeg* S, unsigned Last);
/* 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 */
CodeLabel* FindCodeLabel (CodeSeg* S, const char* Name, unsigned Hash);

View File

@ -39,36 +39,26 @@
#include "xsprintf.h"
/* cc65 */
#include "error.h"
#include "dataseg.h"
/*****************************************************************************/
/* Data */
/*****************************************************************************/
/* Pointer to current data segment */
DataSeg* DS = 0;
/*****************************************************************************/
/* Code */
/*****************************************************************************/
DataSeg* NewDataSeg (const char* Name)
DataSeg* NewDataSeg (const char* Name, SymEntry* Func)
/* Create a new data segment, initialize and return it */
{
/* Allocate memory */
DataSeg* S = xmalloc (sizeof (DataSeg));
DataSeg* S = xmalloc (sizeof (DataSeg));
/* Initialize the fields */
S->Next = 0;
S->Name = xstrdup (Name);
S->SegName = xstrdup (Name);
S->Func = Func;
InitCollection (&S->Lines);
/* Return the new struct */
@ -80,50 +70,7 @@ DataSeg* NewDataSeg (const char* Name)
void FreeDataSeg (DataSeg* S)
/* Free a data segment including all line entries */
{
unsigned I, Count;
/* 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;
Internal ("Not implemented");
}
@ -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 */
{
va_list ap;
char Buf [256];
/* Format the line */
va_start (ap, Format);
char Buf [256];
xvsprintf (Buf, sizeof (Buf), Format, ap);
va_end (ap);
/* Add a copy to the data segment */
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 */
{
unsigned I;
@ -167,10 +110,21 @@ void OutputDataSeg (FILE* F, const DataSeg* S)
/* Get the number of entries in this segment */
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 */
for (I = 0; I < Count; ++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>
/* common */
#include "attrib.h"
#include "coll.h"
/* cc65 */
#include "symentry.h"
/*****************************************************************************/
/* Data */
/* Data */
/*****************************************************************************/
typedef struct DataSeg DataSeg;
struct DataSeg {
DataSeg* Next; /* Pointer to next DataSeg */
char* Name; /* Segment name */
char* SegName; /* Segment name */
SymEntry* Func; /* Owner function */
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 */
void FreeDataSeg (DataSeg* S);
/* 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);
/* 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 */
void OutputDataSeg (FILE* F, const DataSeg* S);
void OutputDataSeg (const DataSeg* S, FILE* F);
/* Output the data segment data to a file */

View File

@ -47,6 +47,7 @@
#include "litpool.h"
#include "locals.h"
#include "scanner.h"
#include "segments.h"
#include "stmt.h"
#include "symtab.h"
#include "function.h"
@ -246,7 +247,7 @@ void NewFunc (SymEntry* Func)
InitRegVars ();
/* 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 (IsFastCallFunc (Func->Type) && D->ParamCount > 0) {
@ -336,7 +337,7 @@ void NewFunc (SymEntry* Func)
LeaveFunctionLevel ();
/* Switch back to the old segments */
g_popseg ();
PopSegments ();
/* Reset the current function pointer */
FreeFunction (CurrentFunc);

View File

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

View File

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

View File

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

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 1998 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (C) 1998-2001 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@cc65.org */
/* */
/* */
/* 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>
/* cc65 */
#include "datatype.h"
/*****************************************************************************/
/* struct SymEntry */
/* Forwards */
/*****************************************************************************/
struct Segments;
/*****************************************************************************/
/* struct SymEntry */
/*****************************************************************************/
/* Storage classes and flags */
#define SC_AUTO 0x0001U
#define SC_AUTO 0x0001U
#define SC_REGISTER 0x0002U /* Register variable, is in static storage */
#define SC_STATIC 0x0004U
#define SC_EXTERN 0x0008U
#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_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_DEFAULT 0x0800U /* Flag: default storage class was used */
@ -83,7 +94,7 @@ struct SymEntry {
SymEntry* NextHash; /* Next entry in hash list */
SymEntry* PrevSym; /* Previous symbol in dl 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 */
unsigned Flags; /* Symbol flags */
type* Type; /* Symbol type */
@ -109,18 +120,17 @@ struct SymEntry {
/* Data for functions */
struct {
struct FuncDesc* Func; /* Function descriptor */
struct CodeSeg* CS; /* Code for function */
struct DataSeg* DS; /* Data segment for function */
struct Segments* Seg; /* Segments for this function */
} F;
} 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) {
Entry->V.F.Func = GetFuncDesc (Entry->Type);
Entry->V.F.CS = 0;
Entry->V.F.DS = 0;
Entry->V.F.Seg = 0;
}
/* Add the entry to the symbol table */