#include <stdlib.h>
#include <string.h>
+#include <stdarg.h>
/* common */
#include "abend.h"
#include "cpu.h"
#include "debugflag.h"
#include "print.h"
+#include "strbuf.h"
#include "xmalloc.h"
#include "xsprintf.h"
#include "asmlabel.h"
#include "codeent.h"
#include "codeinfo.h"
+#include "codeopt.h"
#include "coptadd.h"
#include "coptc02.h"
#include "coptcmp.h"
#include "copttest.h"
#include "error.h"
#include "global.h"
-#include "codeopt.h"
+#include "output.h"
+static void OpenDebugFile (const CodeSeg* S)
+/* Open the debug file for the given segment if the flag is on */
+{
+ if (DebugOptOutput) {
+ StrBuf Name = AUTO_STRBUF_INITIALIZER;
+ if (S->Func) {
+ SB_CopyStr (&Name, S->Func->Name);
+ } else {
+ SB_CopyStr (&Name, "global");
+ }
+ SB_AppendStr (&Name, ".opt");
+ SB_Terminate (&Name);
+ OpenDebugOutputFile (SB_GetConstBuf (&Name));
+ SB_Done (&Name);
+ }
+}
+
+
+
+static void WriteDebugOutput (CodeSeg* S, const char* Step)
+/* Write a separator line into the debug file if the flag is on */
+{
+ if (DebugOptOutput) {
+ /* Output a separator */
+ WriteOutput ("=========================================================================\n");
+
+ /* Output a header line */
+ if (Step == 0) {
+ /* Initial output */
+ WriteOutput ("Initial code for function `%s':\n",
+ S->Func? S->Func->Name : "<global>");
+ } else {
+ WriteOutput ("Code after applying `%s':\n", Step);
+ }
+
+ /* Output the code segment */
+ CS_Output (S);
+ }
+}
+
+
+
static unsigned RunOptFunc (CodeSeg* S, OptFunc* F, unsigned Max)
/* Run one optimizer function Max times or until there are no more changes */
{
/* Run the function */
C = F->Func (S);
- if (Debug && C > 0) {
- printf ("Applied %s: %u changes\n", F->Name, C);
- }
Changes += C;
/* Do statistics */
F->TotalChanges += C;
F->LastChanges += C;
- /* If we had changes, regenerate register info */
+ /* If we had changes, output stuff and regenerate register info */
if (C) {
+ if (Debug) {
+ printf ("Applied %s: %u changes\n", F->Name, C);
+ }
+ WriteDebugOutput (S, F->Name);
CS_GenRegInfo (S);
}
Print (stdout, 1, "Running optimizer for global code segment\n");
}
+ /* If requested, open an output file */
+ OpenDebugFile (S);
+ WriteDebugOutput (S, 0);
+
/* Generate register info for all instructions */
CS_GenRegInfo (S);
/* Free register info */
CS_FreeRegInfo (S);
+ /* Close output file if necessary */
+ if (DebugOptOutput) {
+ CloseOutputFile ();
+ }
+
/* Write statistics */
if (StatFileName) {
- WriteOptStats (StatFileName);
+ WriteOptStats (StatFileName);
}
}
/* */
/* */
/* */
-/* (C) 1998-2011, Ullrich von Bassewitz */
+/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
unsigned char AddSource = 0; /* Add source lines as comments */
unsigned char DebugInfo = 0; /* Add debug info to the obj */
unsigned char PreprocessOnly = 0; /* Just preprocess the input */
+unsigned char DebugOptOutput = 0; /* Output debug stuff */
unsigned RegisterSpace = 6; /* Space available for register vars */
/* Stackable options */
IntStack Optimize = INTSTACK(0); /* Optimize flag */
IntStack CodeSizeFactor = INTSTACK(100);/* Size factor for generated code */
IntStack DataAlignment = INTSTACK(1); /* Alignment for data */
-
+
/* File names */
StrBuf DepName = STATIC_STRBUF_INITIALIZER; /* Name of dependencies file */
StrBuf FullDepName = STATIC_STRBUF_INITIALIZER; /* Name of full dependencies file */
/* */
/* */
/* */
-/* (C) 1998-2011, Ullrich von Bassewitz */
+/* (C) 1998-2012, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
extern unsigned char AddSource; /* Add source lines as comments */
extern unsigned char DebugInfo; /* Add debug info to the obj */
extern unsigned char PreprocessOnly; /* Just preprocess the input */
+extern unsigned char DebugOptOutput; /* Output debug stuff */
extern unsigned RegisterSpace; /* Space available for register vars */
/* Stackable options */
/* */
/* */
/* */
-/* (C) 2000-2011, Ullrich von Bassewitz */
+/* (C) 2000-2012, Ullrich von Bassewitz */
/* Roemerstrasse 52 */
/* D-70794 Filderstadt */
/* EMail: uz@cc65.org */
+static void OptDebugOptOutput (const char* Opt attribute ((unused)),
+ const char* Arg attribute ((unused)))
+/* Output optimization steps */
+{
+ DebugOptOutput = 1;
+}
+
+
+
static void OptDepTarget (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --dep-target option */
{
{ "--debug", 0, OptDebug },
{ "--debug-info", 0, OptDebugInfo },
{ "--debug-opt", 1, OptDebugOpt },
+ { "--debug-opt-output", 0, OptDebugOptOutput },
{ "--dep-target", 1, OptDepTarget },
{ "--disable-opt", 1, OptDisableOpt },
{ "--enable-opt", 1, OptEnableOpt },
/* */
/* */
/* */
-/* (C) 2009, Ullrich von Bassewitz */
-/* Roemerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2009-2012, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
+void OpenDebugOutputFile (const char* Name)
+/* Open an output file for debugging purposes. Will call Fatal() in case of
+ * failures.
+ */
+{
+ /* Output file must not be open and we must have a name*/
+ PRECONDITION (OutputFile == 0);
+
+ /* Open the file */
+ OutputFile = fopen (Name, "w");
+ if (OutputFile == 0) {
+ Fatal ("Cannot open debug output file `%s': %s", Name, strerror (errno));
+ }
+ Print (stdout, 1, "Opened debug output file `%s'\n", Name);
+}
+
+
+
void CloseOutputFile ()
/* Close the output file. Will call Fatal() in case of failures. */
{
Fatal ("Cannot write to output file (disk full?)");
}
Print (stdout, 1, "Closed output file `%s'\n", OutputFilename);
+
+ OutputFile = 0;
}
/* */
/* */
/* */
-/* (C) 2009, Ullrich von Bassewitz */
-/* Roemerstrasse 52 */
-/* D-70794 Filderstadt */
-/* EMail: uz@cc65.org */
+/* (C) 2009-2012, Ullrich von Bassewitz */
+/* Roemerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
/*****************************************************************************/
-/* Data */
+/* Data */
/*****************************************************************************/
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
void OpenOutputFile ();
/* Open the output file. Will call Fatal() in case of failures. */
+void OpenDebugOutputFile (const char* Name);
+/* Open an output file for debugging purposes. Will call Fatal() in case of
+ * failures.
+ */
+
void CloseOutputFile ();
/* Close the output file. Will call Fatal() in case of failures. */