mirror of
https://github.com/cc65/cc65.git
synced 2025-08-10 04:25:21 +00:00
Working on the new backend
git-svn-id: svn://svn.cc65.org/cc65/trunk@709 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
/* b6502 */
|
/* b6502 */
|
||||||
|
#include "codeopt.h"
|
||||||
#include "codeseg.h"
|
#include "codeseg.h"
|
||||||
#include "dataseg.h"
|
#include "dataseg.h"
|
||||||
|
|
||||||
@@ -111,6 +112,7 @@ void WriteOutput (FILE* F)
|
|||||||
/* Function which is defined and referenced or extern */
|
/* Function which is defined and referenced or extern */
|
||||||
PrintFunctionHeader (F, Entry);
|
PrintFunctionHeader (F, Entry);
|
||||||
MergeCodeLabels (Entry->V.F.CS);
|
MergeCodeLabels (Entry->V.F.CS);
|
||||||
|
RunOpt (Entry->V.F.CS);
|
||||||
fprintf (F, "; Data segment for function %s:\n", Entry->Name);
|
fprintf (F, "; Data segment for function %s:\n", Entry->Name);
|
||||||
OutputDataSeg (F, Entry->V.F.DS);
|
OutputDataSeg (F, Entry->V.F.DS);
|
||||||
fprintf (F, "; Code segment for function %s:\n", Entry->Name);
|
fprintf (F, "; Code segment for function %s:\n", Entry->Name);
|
||||||
|
@@ -9,7 +9,7 @@
|
|||||||
/* (C) 1998-2001 llrich von Bassewitz */
|
/* (C) 1998-2001 llrich 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 */
|
||||||
|
@@ -82,6 +82,18 @@ void FreeCodeLabel (CodeLabel* L)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
unsigned RemoveLabelRef (CodeLabel* L, const struct CodeEntry* E)
|
||||||
|
/* Remove a reference to this label, return the number of remaining references */
|
||||||
|
{
|
||||||
|
/* Delete the item */
|
||||||
|
CollDeleteItem (&L->JumpFrom, E);
|
||||||
|
|
||||||
|
/* Return the number of remaining references */
|
||||||
|
return CollCount (&L->JumpFrom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void OutputCodeLabel (FILE* F, const CodeLabel* L)
|
void OutputCodeLabel (FILE* F, const CodeLabel* L)
|
||||||
/* Output the code label to a file */
|
/* Output the code label to a file */
|
||||||
{
|
{
|
||||||
|
@@ -45,6 +45,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Forwards */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct CodeEntry;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* struct CodeLabel */
|
/* struct CodeLabel */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -79,6 +89,9 @@ CodeLabel* NewCodeLabel (const char* Name, unsigned Hash);
|
|||||||
void FreeCodeLabel (CodeLabel* L);
|
void FreeCodeLabel (CodeLabel* L);
|
||||||
/* Free the given code label */
|
/* Free the given code label */
|
||||||
|
|
||||||
|
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 (FILE* F, const CodeLabel* L);
|
||||||
/* Output the code label to a file */
|
/* Output the code label to a file */
|
||||||
|
|
||||||
|
147
src/cc65/codeopt.c
Normal file
147
src/cc65/codeopt.c
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* codeopt.c */
|
||||||
|
/* */
|
||||||
|
/* Optimizer subroutines */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (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. */
|
||||||
|
/* */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* b6502 */
|
||||||
|
#include "codeent.h"
|
||||||
|
#include "codeopt.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Counter for the number of changes in one run. The optimizer process is
|
||||||
|
* repeated until there are no more changes.
|
||||||
|
*/
|
||||||
|
static unsigned OptChanges;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Remove dead jumps */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void OptDeadJumps (CodeSeg* S)
|
||||||
|
/* Remove dead jumps (jumps to the next instruction) */
|
||||||
|
{
|
||||||
|
CodeEntry* E;
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
/* Get the number of entries, bail out if we have less than two entries */
|
||||||
|
unsigned Count = CollCount (&S->Entries);
|
||||||
|
if (Count < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Walk over all entries minus the last one */
|
||||||
|
I = 0;
|
||||||
|
while (I < Count-1) {
|
||||||
|
|
||||||
|
/* Get the next entry */
|
||||||
|
E = CollAt (&S->Entries, I);
|
||||||
|
|
||||||
|
/* Check if it's a branch, if it has a local target, and if the target
|
||||||
|
* is the next instruction.
|
||||||
|
*/
|
||||||
|
if (E->AM == AM_BRA) {
|
||||||
|
printf ("BRA on entry %u:\n", I);
|
||||||
|
if (E->JumpTo) {
|
||||||
|
printf (" JumpTo ok\n");
|
||||||
|
if (E->JumpTo->Owner == CollAt (&S->Entries, I+1)) {
|
||||||
|
printf (" Branch to next insn\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (E->AM == AM_BRA && E->JumpTo && E->JumpTo->Owner == CollAt (&S->Entries, I+1)) {
|
||||||
|
|
||||||
|
/* Remember the label */
|
||||||
|
CodeLabel* L = E->JumpTo;
|
||||||
|
|
||||||
|
/* Jump to next instruction, remove it */
|
||||||
|
unsigned Remaining = RemoveLabelRef (L, E);
|
||||||
|
CollDelete (&S->Entries, I);
|
||||||
|
FreeCodeEntry (E);
|
||||||
|
--Count;
|
||||||
|
|
||||||
|
/* If the label has no more references, remove it */
|
||||||
|
if (Remaining == 0) {
|
||||||
|
CollDeleteItem (&L->Owner->Labels, L);
|
||||||
|
FreeCodeLabel (L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remember we had changes */
|
||||||
|
++OptChanges;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
/* Next entry */
|
||||||
|
++I;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void RunOpt (CodeSeg* S)
|
||||||
|
/* Run the optimizer */
|
||||||
|
{
|
||||||
|
printf ("Optimize\n");
|
||||||
|
|
||||||
|
/* Repeat all steps until there are no more changes */
|
||||||
|
do {
|
||||||
|
|
||||||
|
/* Reset the number of changes */
|
||||||
|
OptChanges = 0;
|
||||||
|
|
||||||
|
OptDeadJumps (S);
|
||||||
|
|
||||||
|
} while (OptChanges > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
67
src/cc65/codeopt.h
Normal file
67
src/cc65/codeopt.h
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
/*****************************************************************************/
|
||||||
|
/* */
|
||||||
|
/* codeopt.h */
|
||||||
|
/* */
|
||||||
|
/* Optimizer subroutines */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* */
|
||||||
|
/* (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. */
|
||||||
|
/* */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CODEOPT_H
|
||||||
|
#define CODEOPT_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* b6502 */
|
||||||
|
#include "codeseg.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Data */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Code */
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void RunOpt (CodeSeg* S);
|
||||||
|
/* Run the optimizer */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* End of codeopt.h */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -270,11 +270,10 @@ static CodeEntry* ParseInsn (CodeSeg* S, const char* L)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If the instruction is a branch, check for the label and generate it
|
/* If the instruction is a branch, check for the label and generate it
|
||||||
* if it does not exist. In case of a PC relative branch (*+x) we will
|
* if it does not exist. Ignore anything but local labels here.
|
||||||
* not generate a label, because the target label will not be defined.
|
|
||||||
*/
|
*/
|
||||||
Label = 0;
|
Label = 0;
|
||||||
if ((OPC->Info & CI_MASK_BRA) == CI_BRA && Expr[0] != '*') {
|
if ((OPC->Info & CI_MASK_BRA) == CI_BRA && Expr[0] == 'L') {
|
||||||
|
|
||||||
unsigned Hash;
|
unsigned Hash;
|
||||||
|
|
||||||
@@ -455,6 +454,8 @@ void AddCodeSegLine (CodeSeg* S, const char* Format, ...)
|
|||||||
L->Flags |= LF_DEF;
|
L->Flags |= LF_DEF;
|
||||||
/* Move it to the code entry */
|
/* Move it to the code entry */
|
||||||
CollAppend (&E->Labels, L);
|
CollAppend (&E->Labels, L);
|
||||||
|
/* Tell the label about it's owner */
|
||||||
|
L->Owner = E;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete the transfered labels */
|
/* Delete the transfered labels */
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (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 */
|
||||||
|
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (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 */
|
||||||
|
Reference in New Issue
Block a user