1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-25 13:29:41 +00:00

Working on the new backend

git-svn-id: svn://svn.cc65.org/cc65/trunk@706 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2001-05-03 17:34:54 +00:00
parent cd956115fa
commit 8eadb8aee0
18 changed files with 256 additions and 79 deletions

View File

@ -38,6 +38,7 @@
#include "dataseg.h"
/* cc65 */
#include "symtab.h"
#include "asmcode.h"
@ -72,12 +73,47 @@ void RemoveCode (CodeMark M)
void WriteOutput (FILE* F)
/* Write the final output to a file */
static void PrintFunctionHeader (FILE* F, SymEntry* Entry)
{
OutputDataSeg (F, DS);
MergeCodeLabels (CS);
OutputCodeSeg (F, CS);
/* Print a comment with the function signature */
fprintf (F,
"; ---------------------------------------------------------------\n"
"; ");
PrintFuncSig (F, Entry->Name, Entry->Type);
fprintf (F,
"\n"
"; ---------------------------------------------------------------\n"
"\n");
}
void WriteOutput (FILE* F)
/* Write the final output to a file */
{
SymTable* SymTab;
SymEntry* Entry;
/* Output the global code and data segments */
MergeCodeLabels (CS);
OutputDataSeg (F, DS);
OutputCodeSeg (F, CS);
/* Output all global or referenced functions */
SymTab = GetGlobalSymTab ();
Entry = SymTab->SymHead;
while (Entry) {
if (IsTypeFunc (Entry->Type) &&
(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);
OutputDataSeg (F, Entry->V.F.DS);
OutputCodeSeg (F, Entry->V.F.CS);
}
Entry = Entry->NextSym;
}
}

View File

@ -9,7 +9,7 @@
/* (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 */
@ -145,9 +145,9 @@ void g_preamble (void)
/* Generate the assembler code preamble */
{
/* Generate the global segments and push them */
PushCodeSeg (NewCodeSeg (""));
PushCodeSeg (NewCodeSeg (SegmentNames[SEG_CODE], ""));
PushDataSeg (NewDataSeg (""));
/* Identify the compiler version */
AddDataSegLine (DS, "; File generated by cc65 v %u.%u.%u",
VER_MAJOR, VER_MINOR, VER_PATCH);
@ -198,6 +198,26 @@ static void UseSeg (int NewSeg)
void g_pushseg (struct CodeSeg** FCS, struct DataSeg** FDS, const char* FuncName)
/* Push the current segments and generate new ones for the given function */
{
PushCodeSeg (NewCodeSeg (SegmentNames[SEG_CODE], FuncName));
*FCS = CS;
PushDataSeg (NewDataSeg (FuncName));
*FDS = DS;
}
void g_popseg (void)
/* Restore the old segments */
{
PopCodeSeg ();
PopDataSeg ();
}
void g_usecode (void)
/* Switch to the code segment */
{
@ -3896,7 +3916,7 @@ void g_defbytes (const void* Bytes, unsigned Count)
} while (Chunk);
/* Output the line */
AddCodeSegLine (CS, Buf);
AddDataSegLine (DS, Buf);
}
}

View File

@ -39,7 +39,18 @@
/*****************************************************************************/
/* data */
/* Forwards */
/*****************************************************************************/
struct CodeSeg;
struct DataSeg;
/*****************************************************************************/
/* Data */
/*****************************************************************************/
@ -99,6 +110,12 @@ 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_usecode (void);
/* Switch to the code segment */

View File

@ -309,7 +309,7 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L)
CodeSeg* NewCodeSeg (const char* Name)
CodeSeg* NewCodeSeg (const char* SegName, const char* FuncName)
/* Create a new code segment, initialize and return it */
{
unsigned I;
@ -318,8 +318,9 @@ CodeSeg* NewCodeSeg (const char* Name)
CodeSeg* S = xmalloc (sizeof (CodeSeg));
/* Initialize the fields */
S->Next = 0;
S->Name = xstrdup (Name);
S->Next = 0;
S->SegName = xstrdup (SegName);
S->FuncName = xstrdup (FuncName);
InitCollection (&S->Entries);
InitCollection (&S->Labels);
for (I = 0; I < sizeof(S->LabelHash) / sizeof(S->LabelHash[0]); ++I) {
@ -337,8 +338,9 @@ void FreeCodeSeg (CodeSeg* S)
{
unsigned I, Count;
/* Free the name */
xfree (S->Name);
/* Free the names */
xfree (S->SegName);
xfree (S->FuncName);
/* Free the entries */
Count = CollCount (&S->Entries);
@ -566,12 +568,22 @@ void OutputCodeSeg (FILE* F, const CodeSeg* S)
unsigned Count = CollCount (&S->Entries);
/* Output the segment directive */
fprintf (F, ".segment\t\"%s\"\n", S->Name);
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);
}
/* Output all entries */
for (I = 0; I < Count; ++I) {
OutputCodeEntry (F, CollConstAt (&S->Entries, I));
}
/* If this is a segment for a function, leave the function */
if (S->FuncName[0] != '\0') {
fprintf (F, "\n.endproc\n\n");
}
}

View File

@ -62,7 +62,8 @@
typedef struct CodeSeg CodeSeg;
struct CodeSeg {
CodeSeg* Next; /* Pointer to next CodeSeg */
char* Name; /* Segment name */
char* SegName; /* Segment name */
char* FuncName; /* Name of function */
Collection Entries; /* List of code entries */
Collection Labels; /* Labels for next insn */
CodeLabel* LabelHash [CS_LABEL_HASH_SIZE]; /* Label hash table */
@ -79,7 +80,7 @@ extern CodeSeg* CS;
CodeSeg* NewCodeSeg (const char* Name);
CodeSeg* NewCodeSeg (const char* SegName, const char* FuncName);
/* Create a new code segment, initialize and return it */
void FreeCodeSeg (CodeSeg* S);

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (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 */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (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 */

View File

@ -239,42 +239,44 @@ void PrintType (FILE* F, const type* Type)
T = PrintTypeComp (F, T, T_QUAL_CONST, "const");
T = PrintTypeComp (F, T, T_QUAL_VOLATILE, "volatile");
/* Signedness */
T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed");
/* Signedness. Omit the signedness specifier for long and int */
if ((T & T_MASK_TYPE) != T_TYPE_INT && (T & T_MASK_TYPE) != T_TYPE_LONG) {
T = PrintTypeComp (F, T, T_SIGN_SIGNED, "signed");
}
T = PrintTypeComp (F, T, T_SIGN_UNSIGNED, "unsigned");
/* Now check the real type */
switch (T & T_MASK_TYPE) {
case T_TYPE_CHAR:
fprintf (F, "char\n");
fprintf (F, "char");
break;
case T_TYPE_SHORT:
fprintf (F, "short\n");
fprintf (F, "short");
break;
case T_TYPE_INT:
fprintf (F, "int\n");
fprintf (F, "int");
break;
case T_TYPE_LONG:
fprintf (F, "long\n");
fprintf (F, "long");
break;
case T_TYPE_LONGLONG:
fprintf (F, "long long\n");
fprintf (F, "long long");
break;
case T_TYPE_FLOAT:
fprintf (F, "float\n");
fprintf (F, "float");
break;
case T_TYPE_DOUBLE:
fprintf (F, "double\n");
fprintf (F, "double");
break;
case T_TYPE_VOID:
fprintf (F, "void\n");
fprintf (F, "void");
break;
case T_TYPE_STRUCT:
fprintf (F, "struct %s\n", ((SymEntry*) DecodePtr (Type))->Name);
fprintf (F, "struct %s", ((SymEntry*) DecodePtr (Type))->Name);
Type += DECODE_SIZE;
break;
case T_TYPE_UNION:
fprintf (F, "union %s\n", ((SymEntry*) DecodePtr (Type))->Name);
fprintf (F, "union %s", ((SymEntry*) DecodePtr (Type))->Name);
Type += DECODE_SIZE;
break;
case T_TYPE_ARRAY:
@ -289,7 +291,7 @@ void PrintType (FILE* F, const type* Type)
Type += DECODE_SIZE;
break;
default:
fprintf (F, "unknown type: %04X\n", T);
fprintf (F, "unknown type: %04X", T);
}
}
@ -297,6 +299,40 @@ void PrintType (FILE* F, const type* Type)
void PrintFuncSig (FILE* F, const char* Name, type* Type)
/* Print a function signature. */
{
/* Get the function descriptor */
const FuncDesc* D = GetFuncDesc (Type);
/* Print a comment with the function signature */
PrintType (F, GetFuncReturn (Type));
if (D->Flags & FD_FASTCALL) {
fprintf (F, " __fastcall__");
}
fprintf (F, " %s (", Name);
/* Parameters */
if (D->Flags & FD_VOID_PARAM) {
fprintf (F, "void");
} else {
unsigned I;
SymEntry* E = D->SymTab->SymHead;
for (I = 0; I < D->ParamCount; ++I) {
if (I > 0) {
fprintf (F, ", ");
}
PrintType (F, E->Type);
E = E->NextSym;
}
}
/* End of parameter list */
fprintf (F, ")");
}
void PrintRawType (FILE* F, const type* Type)
/* Print a type string in raw format (for debugging) */
{
@ -734,4 +770,21 @@ FuncDesc* GetFuncDesc (const type* T)
type* GetFuncReturn (type* T)
/* Return a pointer to the return type of a function or pointer-to-function type */
{
if (T[0] == T_PTR) {
/* Pointer to function */
++T;
}
/* Be sure it's a function type */
CHECK (T[0] == T_FUNC);
/* Return a pointer to the return type */
return T + 1 + DECODE_SIZE;
}

View File

@ -200,6 +200,9 @@ void PrintType (FILE* F, const type* Type);
void PrintRawType (FILE* F, const type* Type);
/* Print a type string in raw format (for debugging) */
void PrintFuncSig (FILE* F, const char* Name, type* Type);
/* Print a function signature. */
void Encode (type* Type, unsigned long Val);
/* Encode an unsigned long into a type array */
@ -310,6 +313,9 @@ type GetQualifier (const type* T) attribute ((const));
FuncDesc* GetFuncDesc (const type* T) attribute ((const));
/* Get the FuncDesc pointer from a function or pointer-to-function type */
type* GetFuncReturn (type* T) attribute ((const));
/* Return a pointer to the return type of a function or pointer-to-function type */
/* End of datatype.h */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (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 */
@ -62,7 +62,7 @@
/* Structure that holds all data needed for function activation */
struct Function {
struct SymEntry* FuncEntry; /* Symbol table entry */
type* ReturnType; /* Function return type */
type* ReturnType; /* Function return type */
struct FuncDesc* Desc; /* Function descriptor */
int Reserved; /* Reserved local space */
unsigned RetLab; /* Return code label */
@ -88,7 +88,7 @@ static Function* NewFunction (struct SymEntry* Sym)
/* Initialize the fields */
F->FuncEntry = Sym;
F->ReturnType = Sym->Type + 1 + DECODE_SIZE;
F->ReturnType = GetFuncReturn (Sym->Type);
F->Desc = (FuncDesc*) DecodePtr (Sym->Type + 1);
F->Reserved = 0;
F->RetLab = GetLocalLabel ();
@ -220,7 +220,7 @@ void NewFunc (SymEntry* Func)
unsigned Flags;
/* Get the function descriptor from the function entry */
FuncDesc* D = (FuncDesc*) DecodePtr (Func->Type+1);
FuncDesc* D = Func->V.F.Func;
/* Allocate the function activation record for the function */
CurrentFunc = NewFunction (Func);
@ -248,9 +248,8 @@ void NewFunc (SymEntry* Func)
/* Setup register variables */
InitRegVars ();
/* Switch to the code segment and define the function name label */
g_usecode ();
g_defgloblabel (Func->Name);
/* Allocate code and data segments for this function */
g_pushseg (&Func->V.F.CS, &Func->V.F.DS, Func->Name);
/* If this is a fastcall function, push the last parameter onto the stack */
if (IsFastCallFunc (Func->Type) && D->ParamCount > 0) {
@ -339,6 +338,9 @@ void NewFunc (SymEntry* Func)
/* Leave the lexical level */
LeaveFunctionLevel ();
/* Switch back to the old segments */
g_popseg ();
/* Reset the current function pointer */
FreeFunction (CurrentFunc);
CurrentFunc = 0;
@ -346,4 +348,3 @@ void NewFunc (SymEntry* Func)

View File

@ -9,7 +9,7 @@
/* (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 */

View File

@ -9,7 +9,7 @@
/* (C) 2000-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 */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (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 */

View File

@ -58,7 +58,6 @@
#include "incpath.h"
#include "input.h"
#include "macrotab.h"
/* #include "optimize.h" */
#include "scanner.h"
#include "segname.h"
@ -567,7 +566,7 @@ int main (int argc, char* argv[])
Optimize = 1;
P = Arg + 2;
while (*P) {
switch (*P++) {
switch (*P++) {
#if 0
case 'f':
sscanf (P, "%lx", (long*) &OptDisable);

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (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 */
@ -134,8 +134,9 @@ void DumpSymEntry (FILE* F, const SymEntry* E)
if (E->Type) {
PrintType (F, E->Type);
} else {
fprintf (F, "(none)\n");
fprintf (F, "(none)");
}
fprintf (F, "\n");
}

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (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 */
@ -107,7 +107,11 @@ struct SymEntry {
} S;
/* Data for functions */
struct FuncDesc* Func; /* Function descriptor */
struct {
struct FuncDesc* Func; /* Function descriptor */
struct CodeSeg* CS; /* Code for function */
struct DataSeg* DS; /* Data segment for function */
} F;
} V;
char Name[1]; /* Name, dynamically allocated */

View File

@ -6,10 +6,10 @@
/* */
/* */
/* */
/* (C) 2000 Ullrich von Bassewitz */
/* Wacholderweg 14 */
/* D-70597 Stuttgart */
/* EMail: uz@musoftware.de */
/* (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 */
@ -224,13 +224,13 @@ void LeaveGlobalLevel (void)
/* Dump the tables if requested */
if (Debug) {
PrintSymTable (SymTab0, stdout, "Global symbol table");
PrintSymTable (TagTab0, stdout, "Global tag table");
PrintSymTable (SymTab0, stdout, "Global symbol table");
PrintSymTable (TagTab0, stdout, "Global tag table");
}
/* Don't delete the symbol and struct tables! */
SymTab0 = SymTab = 0;
TagTab0 = TagTab = 0;
SymTab = 0;
TagTab = 0;
}
@ -664,8 +664,11 @@ SymEntry* AddLocalSym (const char* Name, const type* Type, unsigned Flags, int O
SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
/* Add an external or global symbol to the symbol table and return the entry */
{
/* There is some special handling for functions, so check if it is one */
int IsFunc = IsTypeFunc (Type);
/* Functions must be inserted in the global symbol table */
SymTable* Tab = IsTypeFunc (Type)? SymTab0 : SymTab;
SymTable* Tab = IsFunc? SymTab0 : SymTab;
/* Do we have an entry with this name already? */
SymEntry* Entry = FindSymInTable (Tab, Name, HashStr (Name));
@ -716,8 +719,12 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
* contains pointers to the new symbol tables that are needed if
* an actual function definition follows.
*/
if (IsTypeFunc (Type)) {
CopyEncode (Type+1, EType+1);
if (IsFunc) {
/* Get the function descriptor from the new type */
FuncDesc* F = GetFuncDesc (Type);
/* Use this new function descriptor */
Entry->V.F.Func = F;
EncodePtr (EType+1, F);
}
}
@ -732,6 +739,15 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags)
/* Set the symbol attributes */
Entry->Type = TypeDup (Type);
/* If this is a function, set the function descriptor and clear
* additional fields.
*/
if (IsFunc) {
Entry->V.F.Func = GetFuncDesc (Entry->Type);
Entry->V.F.CS = 0;
Entry->V.F.DS = 0;
}
/* Add the entry to the symbol table */
AddSymEntry (Tab, Entry);
}
@ -756,6 +772,14 @@ SymTable* GetSymTab (void)
SymTable* GetGlobalSymTab (void)
/* Return the global symbol table */
{
return SymTab0;
}
int SymIsLocal (SymEntry* Sym)
/* Return true if the symbol is defined in the highest lexical level */
{

View File

@ -160,6 +160,9 @@ SymEntry* AddGlobalSym (const char* Name, const type* Type, unsigned Flags);
SymTable* GetSymTab (void);
/* Return the current symbol table */
SymTable* GetGlobalSymTab (void);
/* Return the global symbol table */
int SymIsLocal (SymEntry* Sym);
/* Return true if the symbol is defined in the highest lexical level */