Working on the new backend
git-svn-id: svn://svn.cc65.org/cc65/trunk@716 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
parent
e6484f85c7
commit
3ff4baeafb
10 changed files with 138 additions and 127 deletions
|
@ -143,32 +143,32 @@ void g_preamble (void)
|
||||||
PushSegments (0);
|
PushSegments (0);
|
||||||
|
|
||||||
/* Identify the compiler version */
|
/* Identify the compiler version */
|
||||||
AddDataLine ("; File generated by cc65 v %u.%u.%u",
|
AddTextLine ("; File generated by cc65 v %u.%u.%u",
|
||||||
VER_MAJOR, VER_MINOR, VER_PATCH);
|
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||||
|
|
||||||
/* Insert some object file options */
|
/* Insert some object file options */
|
||||||
AddDataLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"",
|
AddTextLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"",
|
||||||
VER_MAJOR, VER_MINOR, VER_PATCH);
|
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||||
|
|
||||||
/* If we're producing code for some other CPU, switch the command set */
|
/* If we're producing code for some other CPU, switch the command set */
|
||||||
if (CPU == CPU_65C02) {
|
if (CPU == CPU_65C02) {
|
||||||
AddDataLine (".pc02");
|
AddTextLine (".pc02");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allow auto import for runtime library routines */
|
/* Allow auto import for runtime library routines */
|
||||||
AddDataLine (".autoimport\ton");
|
AddTextLine (".autoimport\ton");
|
||||||
|
|
||||||
/* Switch the assembler into case sensitive mode */
|
/* Switch the assembler into case sensitive mode */
|
||||||
AddDataLine (".case\t\ton");
|
AddTextLine (".case\t\ton");
|
||||||
|
|
||||||
/* Tell the assembler if we want to generate debug info */
|
/* Tell the assembler if we want to generate debug info */
|
||||||
AddDataLine (".debuginfo\t%s", (DebugInfo != 0)? "on" : "off");
|
AddTextLine (".debuginfo\t%s", (DebugInfo != 0)? "on" : "off");
|
||||||
|
|
||||||
/* Import the stack pointer for direct auto variable access */
|
/* Import the stack pointer for direct auto variable access */
|
||||||
AddDataLine (".importzp\tsp, sreg, regsave, regbank, tmp1, ptr1");
|
AddTextLine (".importzp\tsp, sreg, regsave, regbank, tmp1, ptr1");
|
||||||
|
|
||||||
/* Define long branch macros */
|
/* Define long branch macros */
|
||||||
AddDataLine (".macpack\tlongbranch");
|
AddTextLine (".macpack\tlongbranch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -318,9 +318,9 @@ void g_defexport (const char* Name, int ZP)
|
||||||
/* Export the given label */
|
/* Export the given label */
|
||||||
{
|
{
|
||||||
if (ZP) {
|
if (ZP) {
|
||||||
AddDataLine ("\t.exportzp\t_%s", Name);
|
AddTextLine ("\t.exportzp\t_%s", Name);
|
||||||
} else {
|
} else {
|
||||||
AddDataLine ("\t.export\t\t_%s", Name);
|
AddTextLine ("\t.export\t\t_%s", Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,9 +330,9 @@ void g_defimport (const char* Name, int ZP)
|
||||||
/* Import the given label */
|
/* Import the given label */
|
||||||
{
|
{
|
||||||
if (ZP) {
|
if (ZP) {
|
||||||
AddDataLine ("\t.importzp\t_%s", Name);
|
AddTextLine ("\t.importzp\t_%s", Name);
|
||||||
} else {
|
} else {
|
||||||
AddDataLine ("\t.import\t\t_%s", Name);
|
AddTextLine ("\t.import\t\t_%s", Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* (C) 2001 Ullrich von Bassewitz */
|
/* (C) 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 */
|
||||||
|
@ -321,14 +321,6 @@ CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FreeCodeSeg (CodeSeg* S)
|
|
||||||
/* Free a code segment including all code entries */
|
|
||||||
{
|
|
||||||
Internal ("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap)
|
void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap)
|
||||||
/* Add a line to the given code segment */
|
/* Add a line to the given code segment */
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* (C) 2001 Ullrich von Bassewitz */
|
/* (C) 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 */
|
||||||
|
@ -81,9 +81,6 @@ struct CodeSeg {
|
||||||
CodeSeg* NewCodeSeg (const char* SegName, SymEntry* Func);
|
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);
|
|
||||||
/* Free a code segment including all code entries */
|
|
||||||
|
|
||||||
void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
|
void AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
|
||||||
/* Add a line to the given code segment */
|
/* Add a line to the given code segment */
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* (C) 2001 Ullrich von Bassewitz */
|
/* (C) 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 */
|
||||||
|
@ -67,14 +67,6 @@ DataSeg* NewDataSeg (const char* Name, SymEntry* Func)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void FreeDataSeg (DataSeg* S)
|
|
||||||
/* Free a data segment including all line entries */
|
|
||||||
{
|
|
||||||
Internal ("Not implemented");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 */
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
/* (C) 2001 Ullrich von Bassewitz */
|
/* (C) 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 */
|
||||||
|
@ -74,9 +74,6 @@ struct DataSeg {
|
||||||
DataSeg* NewDataSeg (const char* SegName, SymEntry* Func);
|
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);
|
|
||||||
/* Free a data segment including all line entries */
|
|
||||||
|
|
||||||
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. */
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ OBJS = anonname.o \
|
||||||
stmt.o \
|
stmt.o \
|
||||||
symentry.o \
|
symentry.o \
|
||||||
symtab.o \
|
symtab.o \
|
||||||
|
textseg.o \
|
||||||
typecmp.o \
|
typecmp.o \
|
||||||
util.o
|
util.o
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
#include "codeseg.h"
|
#include "codeseg.h"
|
||||||
#include "dataseg.h"
|
#include "dataseg.h"
|
||||||
|
#include "textseg.h"
|
||||||
#include "segments.h"
|
#include "segments.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -125,6 +126,7 @@ static Segments* NewSegments (SymEntry* Func)
|
||||||
Segments* S = xmalloc (sizeof (Segments));
|
Segments* S = xmalloc (sizeof (Segments));
|
||||||
|
|
||||||
/* Initialize the fields */
|
/* Initialize the fields */
|
||||||
|
S->Text = NewTextSeg (Func);
|
||||||
S->Code = NewCodeSeg (SegmentNames[SEG_CODE], Func);
|
S->Code = NewCodeSeg (SegmentNames[SEG_CODE], Func);
|
||||||
S->Data = NewDataSeg (SegmentNames[SEG_DATA], Func);
|
S->Data = NewDataSeg (SegmentNames[SEG_DATA], Func);
|
||||||
S->ROData = NewDataSeg (SegmentNames[SEG_RODATA], Func);
|
S->ROData = NewDataSeg (SegmentNames[SEG_RODATA], Func);
|
||||||
|
@ -190,6 +192,18 @@ struct DataSeg* GetDataSeg (void)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void AddTextLine (const char* Format, ...)
|
||||||
|
/* Add a line of code to the current text segment */
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
va_start (ap, Format);
|
||||||
|
CHECK (CS != 0);
|
||||||
|
AddTextEntry (CS->Text, Format, ap);
|
||||||
|
va_end (ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AddCodeLine (const char* Format, ...)
|
void AddCodeLine (const char* Format, ...)
|
||||||
/* Add a line of code to the current code segment */
|
/* Add a line of code to the current code segment */
|
||||||
{
|
{
|
||||||
|
@ -237,6 +251,9 @@ void OutputSegments (const Segments* S, FILE* F)
|
||||||
PrintFunctionHeader (S->Code->Func, F);
|
PrintFunctionHeader (S->Code->Func, F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Output the text segment */
|
||||||
|
OutputTextSeg (S->Text, F);
|
||||||
|
|
||||||
/* Output the three data segments */
|
/* Output the three data segments */
|
||||||
OutputDataSeg (S->Data, F);
|
OutputDataSeg (S->Data, F);
|
||||||
OutputDataSeg (S->ROData, F);
|
OutputDataSeg (S->ROData, F);
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
struct CodeSeg;
|
struct CodeSeg;
|
||||||
struct DataSeg;
|
struct DataSeg;
|
||||||
|
struct TextSeg;
|
||||||
struct SymEntry;
|
struct SymEntry;
|
||||||
|
|
||||||
|
|
||||||
|
@ -75,6 +76,7 @@ typedef enum segment_t {
|
||||||
/* A list of all segments used when generating code */
|
/* A list of all segments used when generating code */
|
||||||
typedef struct Segments Segments;
|
typedef struct Segments Segments;
|
||||||
struct Segments {
|
struct Segments {
|
||||||
|
struct TextSeg* Text; /* Text segment */
|
||||||
struct CodeSeg* Code; /* Code segment */
|
struct CodeSeg* Code; /* Code segment */
|
||||||
struct DataSeg* Data; /* Data segment */
|
struct DataSeg* Data; /* Data segment */
|
||||||
struct DataSeg* ROData; /* Readonly data segment */
|
struct DataSeg* ROData; /* Readonly data segment */
|
||||||
|
@ -114,6 +116,9 @@ void UseDataSeg (segment_t DSeg);
|
||||||
struct DataSeg* GetDataSeg (void);
|
struct DataSeg* GetDataSeg (void);
|
||||||
/* Return the current data segment */
|
/* Return the current data segment */
|
||||||
|
|
||||||
|
void AddTextLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
|
/* Add a line of code to the current text segment */
|
||||||
|
|
||||||
void AddCodeLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
void AddCodeLine (const char* Format, ...) attribute ((format (printf, 1, 2)));
|
||||||
/* Add a line of code to the current code segment */
|
/* Add a line of code to the current code segment */
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* segname.c */
|
/* textseg.c */
|
||||||
/* */
|
/* */
|
||||||
/* Segment name management */
|
/* Text segment structure */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
/* (C) 2001 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -33,26 +33,18 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
/* Note: This is NOT some sort of code segment, it is used to store lines of
|
||||||
|
* output that are textual (not real code) instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* common */
|
/* common */
|
||||||
#include "chartype.h"
|
|
||||||
#include "check.h"
|
|
||||||
#include "xmalloc.h"
|
#include "xmalloc.h"
|
||||||
|
#include "xsprintf.h"
|
||||||
|
|
||||||
/* cc65 */
|
/* cc65 */
|
||||||
#include "segname.h"
|
#include "textseg.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
/* Data */
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Actual names for the segments */
|
|
||||||
char* SegmentNames[SEG_COUNT];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,47 +54,55 @@ char* SegmentNames[SEG_COUNT];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InitSegNames (void)
|
TextSeg* NewTextSeg (SymEntry* Func)
|
||||||
/* Initialize the segment names */
|
/* Create a new text segment, initialize and return it */
|
||||||
{
|
{
|
||||||
SegmentNames [SEG_BSS] = xstrdup ("BSS");
|
/* Allocate memory for the structure */
|
||||||
SegmentNames [SEG_CODE] = xstrdup ("CODE");
|
TextSeg* S = xmalloc (sizeof (TextSeg));
|
||||||
SegmentNames [SEG_DATA] = xstrdup ("DATA");
|
|
||||||
SegmentNames [SEG_RODATA] = xstrdup ("RODATA");
|
/* Initialize the fields */
|
||||||
|
S->Func = Func;
|
||||||
|
InitCollection (&S->Lines);
|
||||||
|
|
||||||
|
/* Return the new struct */
|
||||||
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NewSegName (segment_t Seg, const char* Name)
|
void AddTextEntry (TextSeg* S, const char* Format, va_list ap)
|
||||||
/* Set a new name for a segment */
|
/* Add a line to the given text segment */
|
||||||
{
|
{
|
||||||
/* Check the parameter */
|
/* Format the line */
|
||||||
CHECK (Seg != SEG_INV);
|
char Buf [256];
|
||||||
|
xvsprintf (Buf, sizeof (Buf), Format, ap);
|
||||||
|
|
||||||
/* Free the old name and set a new one */
|
/* Add a copy to the data segment */
|
||||||
xfree (SegmentNames [Seg]);
|
CollAppend (&S->Lines, xstrdup (Buf));
|
||||||
SegmentNames [Seg] = xstrdup (Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ValidSegName (const char* Name)
|
void OutputTextSeg (const TextSeg* S, FILE* F)
|
||||||
/* Return true if the given segment name is valid, return false otherwise */
|
/* Output the text segment data to a file */
|
||||||
{
|
{
|
||||||
/* Must start with '_' or a letter */
|
unsigned I;
|
||||||
if ((*Name != '_' && !IsAlpha(*Name)) || strlen(Name) > 80) {
|
|
||||||
return 0;
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can have letters, digits or the underline */
|
/* Output all entries */
|
||||||
while (*++Name) {
|
for (I = 0; I < Count; ++I) {
|
||||||
if (*Name != '_' && !IsAlNum(*Name)) {
|
fprintf (F, "%s\n", (const char*) CollConstAt (&S->Lines, I));
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name is ok */
|
/* Add an additional newline after the segment output */
|
||||||
return 1;
|
fprintf (F, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* */
|
/* */
|
||||||
/* segname.h */
|
/* textseg.h */
|
||||||
/* */
|
/* */
|
||||||
/* Segment name management */
|
/* Text segment structure */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
/* (C) 2001 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
|
@ -33,8 +33,26 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef SEGNAME_H
|
/* Note: This is NOT some sort of code segment, it is used to store lines of
|
||||||
#define SEGNAME_H
|
* output that are textual (not real code) instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef TEXTSEG_H
|
||||||
|
#define TEXTSEG_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
/* common */
|
||||||
|
#include "attrib.h"
|
||||||
|
#include "coll.h"
|
||||||
|
|
||||||
|
/* cc65 */
|
||||||
|
#include "symentry.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,18 +62,11 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Current segment */
|
typedef struct TextSeg TextSeg;
|
||||||
typedef enum segment_t {
|
struct TextSeg {
|
||||||
SEG_INV = -1, /* Invalid segment */
|
SymEntry* Func; /* Owner function */
|
||||||
SEG_CODE,
|
Collection Lines; /* List of text lines */
|
||||||
SEG_RODATA,
|
};
|
||||||
SEG_DATA,
|
|
||||||
SEG_BSS,
|
|
||||||
SEG_COUNT
|
|
||||||
} segment_t;
|
|
||||||
|
|
||||||
/* Actual names for the segments */
|
|
||||||
extern char* SegmentNames[SEG_COUNT];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,19 +76,18 @@ extern char* SegmentNames[SEG_COUNT];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InitSegNames (void);
|
TextSeg* NewTextSeg (SymEntry* Func);
|
||||||
/* Initialize the segment names */
|
/* Create a new text segment, initialize and return it */
|
||||||
|
|
||||||
void NewSegName (segment_t Seg, const char* Name);
|
void AddTextEntry (TextSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
|
||||||
/* Set a new name for a segment */
|
/* Add a line to the given text segment */
|
||||||
|
|
||||||
int ValidSegName (const char* Name);
|
void OutputTextSeg (const TextSeg* S, FILE* F);
|
||||||
/* Return true if the given segment name is valid, return false otherwise */
|
/* Output the text segment data to a file */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* End of segname.h */
|
/* End of textseg.h */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue