mirror of
https://github.com/cc65/cc65.git
synced 2025-02-05 20:31:53 +00:00
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
@ -143,32 +143,32 @@ void g_preamble (void)
|
||||
PushSegments (0);
|
||||
|
||||
/* Identify the compiler version */
|
||||
AddDataLine ("; File generated by cc65 v %u.%u.%u",
|
||||
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||
AddTextLine ("; File generated by cc65 v %u.%u.%u",
|
||||
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||
|
||||
/* Insert some object file options */
|
||||
AddDataLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"",
|
||||
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||
AddTextLine (".fopt\t\tcompiler,\"cc65 v %u.%u.%u\"",
|
||||
VER_MAJOR, VER_MINOR, VER_PATCH);
|
||||
|
||||
/* If we're producing code for some other CPU, switch the command set */
|
||||
if (CPU == CPU_65C02) {
|
||||
AddDataLine (".pc02");
|
||||
AddTextLine (".pc02");
|
||||
}
|
||||
|
||||
/* Allow auto import for runtime library routines */
|
||||
AddDataLine (".autoimport\ton");
|
||||
AddTextLine (".autoimport\ton");
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
AddDataLine (".importzp\tsp, sreg, regsave, regbank, tmp1, ptr1");
|
||||
AddTextLine (".importzp\tsp, sreg, regsave, regbank, tmp1, ptr1");
|
||||
|
||||
/* 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 */
|
||||
{
|
||||
if (ZP) {
|
||||
AddDataLine ("\t.exportzp\t_%s", Name);
|
||||
AddTextLine ("\t.exportzp\t_%s", Name);
|
||||
} 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 */
|
||||
{
|
||||
if (ZP) {
|
||||
AddDataLine ("\t.importzp\t_%s", Name);
|
||||
AddTextLine ("\t.importzp\t_%s", Name);
|
||||
} else {
|
||||
AddDataLine ("\t.import\t\t_%s", Name);
|
||||
AddTextLine ("\t.import\t\t_%s", Name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@musoftware.de */
|
||||
/* (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 */
|
||||
@ -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)
|
||||
/* Add a line to the given code segment */
|
||||
{
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@musoftware.de */
|
||||
/* (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 */
|
||||
@ -37,7 +37,7 @@
|
||||
#define CODESEG_H
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@ -81,9 +81,6 @@ struct CodeSeg {
|
||||
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 AddCodeEntry (CodeSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
|
||||
/* Add a line to the given code segment */
|
||||
|
||||
|
@ -6,10 +6,10 @@
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@musoftware.de */
|
||||
/* (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 */
|
||||
@ -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)
|
||||
/* Append the data from Source to Target */
|
||||
{
|
||||
|
@ -1,15 +1,15 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* dataseg.h */
|
||||
/* dataseg.h */
|
||||
/* */
|
||||
/* Data segment structure */
|
||||
/* Data segment structure */
|
||||
/* */
|
||||
/* */
|
||||
/* */
|
||||
/* (C) 2001 Ullrich von Bassewitz */
|
||||
/* Wacholderweg 14 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@musoftware.de */
|
||||
/* (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 */
|
||||
@ -74,9 +74,6 @@ struct DataSeg {
|
||||
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 AppendDataSeg (DataSeg* Target, const DataSeg* Source);
|
||||
/* Append the data from Source to Target. */
|
||||
|
||||
|
@ -62,6 +62,7 @@ OBJS = anonname.o \
|
||||
stmt.o \
|
||||
symentry.o \
|
||||
symtab.o \
|
||||
textseg.o \
|
||||
typecmp.o \
|
||||
util.o
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
/* cc65 */
|
||||
#include "codeseg.h"
|
||||
#include "dataseg.h"
|
||||
#include "textseg.h"
|
||||
#include "segments.h"
|
||||
|
||||
|
||||
@ -125,6 +126,7 @@ static Segments* NewSegments (SymEntry* Func)
|
||||
Segments* S = xmalloc (sizeof (Segments));
|
||||
|
||||
/* Initialize the fields */
|
||||
S->Text = NewTextSeg (Func);
|
||||
S->Code = NewCodeSeg (SegmentNames[SEG_CODE], Func);
|
||||
S->Data = NewDataSeg (SegmentNames[SEG_DATA], 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, ...)
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Output the text segment */
|
||||
OutputTextSeg (S->Text, F);
|
||||
|
||||
/* Output the three data segments */
|
||||
OutputDataSeg (S->Data, F);
|
||||
OutputDataSeg (S->ROData, F);
|
||||
|
@ -53,12 +53,13 @@
|
||||
|
||||
struct CodeSeg;
|
||||
struct DataSeg;
|
||||
struct TextSeg;
|
||||
struct SymEntry;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
@ -75,6 +76,7 @@ typedef enum segment_t {
|
||||
/* A list of all segments used when generating code */
|
||||
typedef struct Segments Segments;
|
||||
struct Segments {
|
||||
struct TextSeg* Text; /* Text segment */
|
||||
struct CodeSeg* Code; /* Code segment */
|
||||
struct DataSeg* Data; /* Data segment */
|
||||
struct DataSeg* ROData; /* Readonly data segment */
|
||||
@ -114,6 +116,9 @@ void UseDataSeg (segment_t DSeg);
|
||||
struct DataSeg* GetDataSeg (void);
|
||||
/* 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)));
|
||||
/* 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 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -33,76 +33,76 @@
|
||||
|
||||
|
||||
|
||||
#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 */
|
||||
#include "chartype.h"
|
||||
#include "check.h"
|
||||
#include "xmalloc.h"
|
||||
#include "xsprintf.h"
|
||||
|
||||
/* cc65 */
|
||||
#include "segname.h"
|
||||
#include "textseg.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Actual names for the segments */
|
||||
char* SegmentNames[SEG_COUNT];
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void InitSegNames (void)
|
||||
/* Initialize the segment names */
|
||||
TextSeg* NewTextSeg (SymEntry* Func)
|
||||
/* Create a new text segment, initialize and return it */
|
||||
{
|
||||
SegmentNames [SEG_BSS] = xstrdup ("BSS");
|
||||
SegmentNames [SEG_CODE] = xstrdup ("CODE");
|
||||
SegmentNames [SEG_DATA] = xstrdup ("DATA");
|
||||
SegmentNames [SEG_RODATA] = xstrdup ("RODATA");
|
||||
/* Allocate memory for the structure */
|
||||
TextSeg* S = xmalloc (sizeof (TextSeg));
|
||||
|
||||
/* Initialize the fields */
|
||||
S->Func = Func;
|
||||
InitCollection (&S->Lines);
|
||||
|
||||
/* Return the new struct */
|
||||
return S;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void NewSegName (segment_t Seg, const char* Name)
|
||||
/* Set a new name for a segment */
|
||||
void AddTextEntry (TextSeg* S, const char* Format, va_list ap)
|
||||
/* Add a line to the given text segment */
|
||||
{
|
||||
/* Check the parameter */
|
||||
CHECK (Seg != SEG_INV);
|
||||
/* Format the line */
|
||||
char Buf [256];
|
||||
xvsprintf (Buf, sizeof (Buf), Format, ap);
|
||||
|
||||
/* Free the old name and set a new one */
|
||||
xfree (SegmentNames [Seg]);
|
||||
SegmentNames [Seg] = xstrdup (Name);
|
||||
/* Add a copy to the data segment */
|
||||
CollAppend (&S->Lines, xstrdup (Buf));
|
||||
}
|
||||
|
||||
|
||||
|
||||
int ValidSegName (const char* Name)
|
||||
/* Return true if the given segment name is valid, return false otherwise */
|
||||
void OutputTextSeg (const TextSeg* S, FILE* F)
|
||||
/* Output the text segment data to a file */
|
||||
{
|
||||
/* Must start with '_' or a letter */
|
||||
if ((*Name != '_' && !IsAlpha(*Name)) || strlen(Name) > 80) {
|
||||
return 0;
|
||||
unsigned I;
|
||||
|
||||
/* 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 */
|
||||
while (*++Name) {
|
||||
if (*Name != '_' && !IsAlNum(*Name)) {
|
||||
return 0;
|
||||
}
|
||||
/* Output all entries */
|
||||
for (I = 0; I < Count; ++I) {
|
||||
fprintf (F, "%s\n", (const char*) CollConstAt (&S->Lines, I));
|
||||
}
|
||||
|
||||
/* Name is ok */
|
||||
return 1;
|
||||
/* Add an additional newline after the segment output */
|
||||
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 */
|
||||
/* D-70597 Stuttgart */
|
||||
/* EMail: uz@cc65.org */
|
||||
@ -33,51 +33,61 @@
|
||||
|
||||
|
||||
|
||||
#ifndef SEGNAME_H
|
||||
#define SEGNAME_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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef TEXTSEG_H
|
||||
#define TEXTSEG_H
|
||||
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* common */
|
||||
#include "attrib.h"
|
||||
#include "coll.h"
|
||||
|
||||
/* cc65 */
|
||||
#include "symentry.h"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Current segment */
|
||||
typedef enum segment_t {
|
||||
SEG_INV = -1, /* Invalid segment */
|
||||
SEG_CODE,
|
||||
SEG_RODATA,
|
||||
SEG_DATA,
|
||||
SEG_BSS,
|
||||
SEG_COUNT
|
||||
} segment_t;
|
||||
|
||||
/* Actual names for the segments */
|
||||
extern char* SegmentNames[SEG_COUNT];
|
||||
typedef struct TextSeg TextSeg;
|
||||
struct TextSeg {
|
||||
SymEntry* Func; /* Owner function */
|
||||
Collection Lines; /* List of text lines */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
void InitSegNames (void);
|
||||
/* Initialize the segment names */
|
||||
TextSeg* NewTextSeg (SymEntry* Func);
|
||||
/* Create a new text segment, initialize and return it */
|
||||
|
||||
void NewSegName (segment_t Seg, const char* Name);
|
||||
/* Set a new name for a segment */
|
||||
void AddTextEntry (TextSeg* S, const char* Format, va_list ap) attribute ((format(printf,2,0)));
|
||||
/* Add a line to the given text segment */
|
||||
|
||||
int ValidSegName (const char* Name);
|
||||
/* Return true if the given segment name is valid, return false otherwise */
|
||||
void OutputTextSeg (const TextSeg* S, FILE* F);
|
||||
/* Output the text segment data to a file */
|
||||
|
||||
|
||||
|
||||
/* End of segname.h */
|
||||
|
||||
/* End of textseg.h */
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user