summaryrefslogtreecommitdiff
path: root/cg.c
diff options
context:
space:
mode:
authorJohn van Groningen2003-07-11 13:47:24 +0000
committerJohn van Groningen2003-07-11 13:47:24 +0000
commit2255def3b1d52edce2b87c30ddff0a206abda7cd (patch)
tree406f668067c28094b4a64a59d6549554bcb54f51 /cg.c
parentfix bug in floating point subtract and divide (diff)
add .c and .h files
Diffstat (limited to 'cg.c')
-rw-r--r--cg.c924
1 files changed, 924 insertions, 0 deletions
diff --git a/cg.c b/cg.c
new file mode 100644
index 0000000..9db12d3
--- /dev/null
+++ b/cg.c
@@ -0,0 +1,924 @@
+/*
+ File: cg.c
+ Author: John van Groningen
+ At: University of Nijmegen
+*/
+
+#ifdef THINK_C
+# define USER_INTERFACE
+#endif
+
+#include <string.h>
+
+#include "cgport.h"
+
+#ifdef ALIGN_C_CALLS
+# define CG_PPC_XO
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#if ! (defined (M68000) && defined (SUN))
+# define GENERATE_OBJECT_FILE
+#endif
+
+#ifdef POWER
+# define USE_SYSTEM_ALLOC 1
+/* # include "Memory.h" */
+# include "MacMemory.h"
+#else
+# define USE_SYSTEM_ALLOC 0
+#endif
+
+/* #define PERFORMANCE */
+
+#include "MAIN_CLM.d"
+
+#ifdef PERFORMANCE
+#include <Perf.h>
+TP2PerfGlobals ThePGlobals;
+#endif
+
+#ifdef THINK_C
+# include <console.h>
+# define NO_TOPOLOGY
+#ifdef USER_INTERFACE
+# include "system.h"
+#else
+# include "types.t"
+#endif
+#endif
+
+#include "cgrconst.h"
+#include "cgtypes.h"
+#include "cgcode.h"
+#include "cglin.h"
+#include "cgopt.h"
+#ifdef _WINDOWS_
+# include "cgias.h"
+# include "cgiwas.h"
+#else
+# ifdef SOLARIS
+# include "cgswas.h"
+# else
+# ifdef G_POWER
+# include "cgpas.h"
+# include "cgpwas.h"
+# else
+# include "cgas.h"
+# include "cgwas.h"
+# endif
+# endif
+#endif
+#include "cgstack.h"
+
+#include "cg.h"
+
+#ifdef USER_INTERFACE
+# include "cginterface.t"
+# include "cginterface.h"
+#endif
+
+#include "cginput.h"
+
+#ifdef G_POWER
+# include "cgptoc.h"
+#endif
+
+#include <setjmp.h>
+
+static jmp_buf error_jmp;
+
+static void exit_code_generator (int r)
+{
+ longjmp (error_jmp,r);
+}
+
+int list_flag;
+int check_stack;
+int assembly_flag;
+int mc68000_flag;
+int mc68881_flag;
+int parallel_flag;
+int check_index_flag;
+int module_info_flag=1;
+int profile_table_flag;
+#ifdef G_POWER
+int fmadd_flag=1;
+#endif
+
+#ifdef USER_INTERFACE
+# define print_error(s1) FPrintF (StdError,"%s\n",s1)
+# define exit exit_code_generator
+#else
+# ifdef MAIN_CLM
+# ifdef MAKE_MPW_TOOL
+# define print_error(s1) printf("%s\n",s1)
+# else
+# ifdef CG_PPC_XO
+ static char *return_error_string;
+# else
+ extern char return_error_string[];
+# endif
+# define print_error(s1) strcpy (return_error_string,s1);
+# endif
+# define exit exit_code_generator
+# else
+/* # define print_error(s1) printf("%s\n",s1) */
+# define print_error(s1) fprintf(stderr,"%s\n",s1)
+# endif
+#endif
+
+void warning (char *error_string)
+{
+ print_error (error_string);
+}
+
+void warning_s (char *error_string,char *string)
+{
+ char error[300];
+
+ sprintf (error,error_string,string);
+ print_error (error);
+}
+
+void warning_i (char *error_string,int integer)
+{
+ char error[300];
+
+ sprintf (error,error_string,integer);
+ print_error (error);
+}
+
+void warning_si (char *error_string,char *string,int i)
+{
+ char error[300];
+
+ sprintf (error,error_string,string,i);
+ print_error (error);
+}
+
+void error (char *error_string)
+{
+ warning (error_string);
+#ifdef PERFORMANCE
+ PerfDump (ThePGlobals,"\pPerform.out",0,0);
+ TermPerf (ThePGlobals);
+#endif
+ exit (-1);
+}
+
+void error_i (char *error_string,int integer)
+{
+ warning_i (error_string,integer);
+#ifdef PERFORMANCE
+ PerfDump (ThePGlobals,"\pPerform.out",0,0);
+ TermPerf (ThePGlobals);
+#endif
+ exit (-1);
+}
+
+void error_s (char *error_string,char *string)
+{
+ warning_s (error_string,string);
+#ifdef PERFORMANCE
+ PerfDump (ThePGlobals,"\pPerform.out",0,0);
+ TermPerf (ThePGlobals);
+#endif
+ exit (-1);
+}
+
+void error_si (char *error_string,char *string,int i)
+{
+ warning_si (error_string,string,i);
+#ifdef PERFORMANCE
+ PerfDump (ThePGlobals,"\pPerform.out",0,0);
+ TermPerf (ThePGlobals);
+#endif
+ exit (-1);
+}
+
+void internal_error (char *error_string)
+{
+ error_s ("Internal error: %s",error_string);
+}
+
+void internal_error_in_function (char *function_name)
+{
+ error_s ("Internal error in function: %s",function_name);
+}
+
+void *memory_allocate (int size)
+{
+ void *memory_block;
+
+ memory_block=malloc (size);
+ if (memory_block==NULL)
+ error ("Out of memory");
+ return memory_block;
+}
+
+#if USE_SYSTEM_ALLOC
+#define system_memory_allocate_type(t) ((t*)system_memory_allocate(sizeof (t)))
+
+static void *system_memory_allocate (int size)
+{
+ char *memory_block;
+
+ memory_block=NewPtr (size);
+ if (memory_block==NULL)
+ error ("Out of memory");
+ return memory_block;
+}
+
+#endif
+
+void memory_free (void *memory_block)
+{
+ free (memory_block);
+}
+
+#if USE_SYSTEM_ALLOC
+static void system_memory_free (void *memory_block)
+{
+ DisposePtr ((char*)memory_block);
+}
+#endif
+
+#ifdef THINK_C
+# define MEM_BLOCK_SIZE 16380
+#else
+# if defined (__MWERKS__) || defined (__MRC__)
+# define MEM_BLOCK_SIZE 16384
+# else
+# define MEM_BLOCK_SIZE 4092
+# endif
+#endif
+
+struct memory_block_list
+{
+ char mem_block [MEM_BLOCK_SIZE];
+ struct memory_block_list * mem_next_block;
+};
+
+static struct memory_block_list *heap;
+static int first_mem_block_size;
+
+void *allocate_memory_from_heap (int size)
+{
+#ifdef sparc
+ size = (size+7) & ~7;
+#else
+ size = (size+3) & ~3;
+#endif
+ if (first_mem_block_size+size<=MEM_BLOCK_SIZE){
+ char *mem_block;
+
+ mem_block=&heap->mem_block[first_mem_block_size];
+ first_mem_block_size+=size;
+ return mem_block;
+ } else {
+ struct memory_block_list *new_mem_block_list;
+
+#if USE_SYSTEM_ALLOC
+ new_mem_block_list=system_memory_allocate_type (struct memory_block_list);
+#else
+ new_mem_block_list=memory_allocate (sizeof (struct memory_block_list));
+#endif
+ new_mem_block_list->mem_next_block=heap;
+ heap=new_mem_block_list;
+ first_mem_block_size=size;
+ return new_mem_block_list->mem_block;
+ }
+}
+
+void release_heap (VOID)
+{
+ while (heap->mem_next_block!=NULL){
+ struct memory_block_list *next_mem_block;
+
+ next_mem_block=heap->mem_next_block;
+#if USE_SYSTEM_ALLOC
+ system_memory_free (heap);
+#else
+ memory_free (heap);
+#endif
+ heap=next_mem_block;
+ }
+}
+
+static struct memory_block_list *memory_list;
+static char *fast_mem_block;
+static int fast_mem_block_size;
+
+static void initialize_memory (VOID)
+{
+ memory_list=NULL;
+
+ first_mem_block_size=0;
+#if USE_SYSTEM_ALLOC
+ heap=system_memory_allocate_type (struct memory_block_list);
+#else
+ heap=memory_allocate (sizeof (struct memory_block_list));
+#endif
+ heap->mem_next_block=NULL;
+
+ fast_mem_block_size=0;
+#if USE_SYSTEM_ALLOC
+ memory_list=system_memory_allocate_type (struct memory_block_list);
+#else
+ memory_list=memory_allocate (sizeof (struct memory_block_list));
+#endif
+ memory_list->mem_next_block=NULL;
+ fast_mem_block=memory_list->mem_block;
+}
+
+void *fast_memory_allocate (int size)
+{
+#ifdef sparc
+ size=(size+7) & ~7;
+#else
+ size=(size+3) & ~3;
+#endif
+ if (fast_mem_block_size+size<=MEM_BLOCK_SIZE){
+ char *memory_block;
+
+ memory_block=&fast_mem_block[fast_mem_block_size];
+ fast_mem_block_size+=size;
+ return memory_block;
+ } else {
+ struct memory_block_list *new_memory_block;
+
+#if USE_SYSTEM_ALLOC
+ new_memory_block=system_memory_allocate_type (struct memory_block_list);
+#else
+ new_memory_block=memory_allocate (sizeof (struct memory_block_list));
+#endif
+ new_memory_block->mem_next_block=memory_list;
+ memory_list=new_memory_block;
+
+ fast_mem_block=new_memory_block->mem_block;
+ fast_mem_block_size=size;
+
+ return fast_mem_block;
+ }
+}
+
+static void release_memory (VOID)
+{
+ while (memory_list!=NULL){
+ struct memory_block_list *next_mem_block;
+
+ next_mem_block=memory_list->mem_next_block;
+#if USE_SYSTEM_ALLOC
+ system_memory_free (memory_list);
+#else
+ memory_free (memory_list);
+#endif
+ memory_list=next_mem_block;
+ }
+ release_heap();
+#if USE_SYSTEM_ALLOC
+ system_memory_free (heap);
+#else
+ memory_free (heap);
+#endif
+}
+
+#define IO_BUF_SIZE 8192
+
+char *this_module_name;
+
+#ifdef GNU_C
+# define FOLDER_SEPARATOR '/'
+#else
+# define FOLDER_SEPARATOR ':'
+#endif
+
+#ifdef PROJECT_BUILDER
+static FILE *fopen_with_file_name_conversion (char *file_name,char *mode)
+{
+ static char file_name_s[257];
+ char *p;
+
+ for (p=file_name; *p!='\0' && *p!=':'; ++p)
+ ;
+
+ if (*p==':'){
+ strcpy (file_name_s,"/Volumes/");
+ strcat (file_name_s,file_name);
+
+ for (p=file_name_s; *p!='\0'; ++p)
+ if (*p==':')
+ *p='/';
+
+ file_name=file_name_s;
+ }
+
+ return fopen (file_name,mode);
+}
+
+# define fopen fopen_with_file_name_conversion
+#endif
+
+#ifdef USER_INTERFACE
+
+extern File abc_file;
+
+static File obj_file,assembly_file;
+
+extern int system_file;
+
+int generate_code (char *file_name,target_machine_type target_machine,int flags)
+{
+ int r;
+ char *module_name;
+ int object_file_type;
+
+ /*
+ InitProfile (400,200);
+ freopen ("profile","w",stdout);
+ */
+
+ system_file=0;
+
+ obj_file=NULL;
+ assembly_file=NULL;
+ abc_file=NULL;
+
+ if (!(r=setjmp (error_jmp))){
+ initialize_memory();
+
+ mc68000_flag=0;
+ mc68881_flag=1;
+
+ switch (target_machine){
+ case MAC_II:
+ break;
+ case MAC_I:
+ mc68000_flag=1;
+ mc68881_flag=0;
+ break;
+ case MAC_IISANE:
+ mc68881_flag=0;
+ break;
+ default:
+ error ("Unknown target machine");
+ }
+
+ list_flag=0;
+ check_stack=(flags & STACK_CHECKS)!=0;
+ assembly_flag=(flags & ASSEMBLY)!=0;
+ parallel_flag=(flags & DO_PARALLEL)!=0;
+ check_index_flag=(flags & CHECK_INDICES)!=0;
+ profile_table_flag=0;
+
+#ifndef GENERATE_OBJECT_FILE
+ assembly_flag=1;
+#endif
+
+ initialize_parser();
+ initialize_coding();
+ initialize_linearization();
+ initialize_stacks();
+
+ object_file_type=
+ mc68000_flag ? obj00File : (mc68881_flag ? obj81File : obj20File);
+
+ module_name=file_name+strlen (file_name);
+ while (module_name>file_name && module_name[-1]!=FOLDER_SEPARATOR)
+ --module_name;
+
+ this_module_name=module_name;
+
+ abc_file=FOpen (file_name,abcFile,"r");
+
+ if (abc_file==NULL){
+ fprintf (stderr,"file \"%s.abc\" could not be opened.\n",file_name);
+ exit (-1);
+ }
+
+ setvbuf (abc_file,NULL,_IOFBF,8192);
+
+#if defined (M68000) && !defined (SUN)
+ obj_file=FOpen (file_name,object_file_type,"wb");
+ if (obj_file==NULL)
+ error_s ("Can't create the output file [%s]",this_module_name);
+ setvbuf (obj_file,NULL,_IOFBF,IO_BUF_SIZE);
+#endif
+
+ if (assembly_flag){
+#ifdef MACH_O
+ assembly_file=FOpen (file_name,assFile,"wb");
+#else
+ assembly_file=FOpen (file_name,assFile,"w");
+#endif
+ if (assembly_file==NULL)
+ error_s ("Can't create the assembly file [%s]",this_module_name);
+ setvbuf (assembly_file,NULL,_IOFBF,IO_BUF_SIZE);
+ }
+
+#ifdef GENERATE_OBJECT_FILE
+ initialize_assembler (obj_file);
+#endif
+ if (assembly_flag)
+ initialize_write_assembly (assembly_file);
+
+#ifdef G_POWER
+ initialize_toc();
+#endif
+
+ if (parse_file (abc_file)!=0){
+ if (abc_file!=NULL){
+ FClose (abc_file);
+ abc_file=NULL;
+ }
+
+#ifdef PERFORMANCE
+ PerfDump (ThePGlobals,"\pPerform.out",0,0);
+ TermPerf (ThePGlobals);
+#endif
+ exit (-1);
+ }
+
+ if (abc_file!=NULL){
+ FClose (abc_file);
+ abc_file=NULL;
+ }
+
+ if (profile_table_flag)
+ write_profile_table();
+
+ optimize_jumps();
+
+#if 0
+ if (list_flag){
+ show_code();
+ show_imports_and_exports();
+ }
+#endif
+
+#ifdef GENERATE_OBJECT_FILE
+ assemble_code();
+#endif
+
+ if (assembly_flag)
+ write_assembly();
+
+#if defined (M68000) && !defined (SUN)
+ if (fclose (obj_file)!=0){
+ obj_file=NULL;
+ FDelete (file_name,object_file_type);
+ error_s ("Error while writing object file [%s]",this_module_name);
+ }
+#endif
+
+ if (assembly_flag && fclose (assembly_file)!=0){
+ assembly_file=NULL;
+ FDelete (file_name,assFile);
+ error_s ("Error while writing assembly file [%s]",this_module_name);
+ }
+
+ if (!(flags & KEEP_ABC) && !system_file)
+ FDelete (file_name,abcFile);
+ } else {
+ /* if an error occurrs : */
+ if (obj_file!=NULL){
+ fclose (obj_file);
+ FDelete (file_name,object_file_type);
+ }
+ if (assembly_file!=NULL){
+ fclose (assembly_file);
+ FDelete (file_name,assFile);
+ }
+ if (abc_file!=NULL){
+ FClose (abc_file);
+ abc_file=NULL;
+ }
+ }
+
+ release_memory();
+
+ return r;
+}
+
+#else
+
+static void argument_error (VOID)
+{
+ error ("Usage: cg [options] file [-o object_file] [-s assembly_file]");
+}
+
+#if defined (POWER) && !defined (CG_PPC_XO)
+extern int compiler_id;
+#endif
+
+#ifdef MAIN_CLM
+# if !(defined (__MWERKS__) && defined (__cplusplus))
+# ifdef CG_PPC_XO
+# ifdef MACH_O
+int generate_code_o (int argc,char **argv,char *return_error_string_p,int *compiler_id_p)
+# else
+int generate_code_xo (int argc,char **argv,char *return_error_string_p,int *compiler_id_p)
+# endif
+# else
+int generate_code (int argc,char **argv)
+# endif
+# else
+int generate_code68 (int argc,char **argv)
+# endif
+#else
+int main (int argc,char **argv)
+#endif
+{
+ char *file_name;
+
+ static FILE *abc_file,*obj_file,*assembly_file;
+
+ int arg_n,r,file_name_length;
+ char *abc_file_name=NULL,*object_file_name_s=NULL,*assembly_file_name_s=NULL;
+ char *module_name,*object_file_name,*assembly_file_name;
+
+
+#ifdef CG_PPC_XO
+ return_error_string=return_error_string_p;
+#endif
+
+#if defined (THINK_C)
+ argc = ccommand (&argv);
+#endif
+
+#ifdef PERFORMANCE
+ ThePGlobals=NULL;
+ if (!InitPerf (&ThePGlobals,4,8,1,1,"\pCODE",0,"",0,0,0,0)){
+ printf ("Can't initialize performance measurement\n");
+ exit (-1);
+ }
+ PerfControl (ThePGlobals,1);
+#endif
+
+ obj_file=NULL;
+ assembly_file=NULL;
+ abc_file=NULL;
+
+ if (!(r=setjmp (error_jmp))){
+ initialize_memory();
+
+ list_flag=0;
+ check_stack=0;
+
+ mc68000_flag=0;
+ mc68881_flag=1;
+
+ parallel_flag=0;
+ check_index_flag=0;
+ assembly_flag=0;
+#if defined (G_POWER) && !defined (MACH_O)
+ profile_table_flag=1;
+#else
+ profile_table_flag=0;
+#endif
+
+ for (arg_n=1; arg_n<argc && argv[arg_n][0]=='-'; ++arg_n){
+ char *s;
+
+ s=argv[arg_n]+1;
+ if (!strcmp (s,"l"))
+ list_flag=1;
+ else if (!strcmp (s,"os"))
+ check_stack=1;
+ else if (!strcmp (s,"ci"))
+ check_index_flag=1;
+ else if (!strcmp (s,"p"))
+ parallel_flag=1;
+ else if (!strcmp (s,"a"))
+ assembly_flag=1;
+#ifdef G_POWER
+ else if (!strcmp (s,"pt"))
+ profile_table_flag=1;
+#endif
+ else if (!strcmp (s,"mc68000")){
+ mc68000_flag=1;
+ mc68881_flag=0;
+ } else if (!strcmp (s,"sane"))
+ mc68881_flag=0;
+#ifdef POWER
+ else if (!strcmp (s,"id") && arg_n+1<argc){
+ ++arg_n;
+# ifdef CG_PPC_XO
+ *compiler_id_p=atoi (argv[arg_n]);
+# else
+ compiler_id=atoi (argv[arg_n]);
+# endif
+ }
+#endif
+ else
+ argument_error();
+ }
+
+#ifndef GENERATE_OBJECT_FILE
+ assembly_flag=1;
+#endif
+
+ if (arg_n>=argc)
+ argument_error();
+
+ file_name=argv[arg_n++];
+
+ module_name=file_name+strlen (file_name);
+ while (module_name>file_name && module_name[-1]!=FOLDER_SEPARATOR)
+ --module_name;
+
+ this_module_name=module_name;
+
+ file_name_length=strlen (file_name);
+
+ abc_file_name=(char*)memory_allocate (file_name_length+5);
+ strcpy (abc_file_name,file_name);
+ strcat (abc_file_name,".abc");
+
+ object_file_name_s=(char*)memory_allocate (file_name_length+6);
+ strcpy (object_file_name_s,file_name);
+
+#if defined (G_POWER) || defined (_WINDOWS_) || defined (LINUX) || defined (sparc)
+# if defined (G_POWER) && !defined (MACH_O)
+# ifdef ALIGN_C_CALLS
+ strcat (object_file_name_s,".xo");
+# else
+ strcat (object_file_name_s,".cxo");
+# endif
+# else
+ strcat (object_file_name_s,".o");
+# endif
+#else
+# ifdef I486
+ strcat (object_file_name_s,".obj");
+# else
+ strcat (object_file_name_s,mc68000_flag ? ".obj0" : mc68881_flag ? ".obj2" : ".obj1");
+# endif
+#endif
+ object_file_name=object_file_name_s;
+
+ assembly_file_name_s=(char*)memory_allocate (file_name_length+3);
+ strcpy (assembly_file_name_s,file_name);
+
+#if (defined (M68000) && !defined (SUN)) || (defined (G_POWER) && !defined (LINUX_ELF))
+ strcat (assembly_file_name_s,".a");
+#else
+ strcat (assembly_file_name_s,".s");
+#endif
+ assembly_file_name=assembly_file_name_s;
+
+ while (arg_n<argc){
+ if (arg_n+1==argc)
+ argument_error();
+
+ if (!strcmp (argv[arg_n],"-o"))
+ object_file_name=argv[arg_n+1];
+ else if (!strcmp (argv[arg_n],"-s")){
+ assembly_file_name=argv[arg_n+1];
+ assembly_flag=1;
+ } else
+ argument_error();
+
+ arg_n+=2;
+ }
+ initialize_parser();
+ initialize_coding();
+ initialize_stacks();
+ initialize_linearization();
+
+#if 0
+ abc_file=fopen (abc_file_name,"r");
+#else
+ abc_file=fopen (abc_file_name,"rb");
+#endif
+ if (abc_file==NULL)
+ error_s ("Can't open file %s\n",abc_file_name);
+
+#if defined (I486) && !defined (_WINDOWS_)
+ {
+ char *buffer;
+
+ buffer=malloc (IO_BUF_SIZE);
+ if (buffer==NULL)
+ error ("Out of memory");
+ setvbuf (abc_file,buffer,_IOFBF,IO_BUF_SIZE);
+ }
+#else
+ setvbuf (abc_file,NULL,_IOFBF,IO_BUF_SIZE);
+#endif
+
+# ifdef GENERATE_OBJECT_FILE
+ obj_file=fopen (object_file_name,"wb");
+ if (obj_file==NULL)
+ error ("Can't create the object file");
+ setvbuf (obj_file,NULL,_IOFBF,IO_BUF_SIZE);
+# endif
+
+ if (assembly_flag){
+#ifdef MACH_O
+ assembly_file=fopen (assembly_file_name,"wb");
+#else
+ assembly_file=fopen (assembly_file_name,"w");
+#endif
+ if (assembly_file==NULL)
+ error ("Can't create the assembly file");
+#if defined (I486) && !defined (_WINDOWS_)
+ {
+ char *buffer;
+
+ buffer=malloc (IO_BUF_SIZE);
+ if (buffer==NULL)
+ error ("Out of memory");
+ setvbuf (assembly_file,buffer,_IOFBF,IO_BUF_SIZE);
+ }
+#else
+ setvbuf (assembly_file,NULL,_IOFBF,IO_BUF_SIZE);
+#endif
+ }
+
+#ifdef GENERATE_OBJECT_FILE
+ initialize_assembler (obj_file);
+#endif
+ if (assembly_flag)
+ initialize_write_assembly (assembly_file);
+
+#ifdef G_POWER
+ initialize_toc();
+#endif
+
+ if (parse_file (abc_file)!=0){
+ if (abc_file!=NULL){
+ fclose (abc_file);
+ abc_file=NULL;
+ }
+
+ exit (-1);
+ }
+
+ if (fclose (abc_file)!=0){
+ abc_file=NULL;
+ error_s ("Error while reading file %s\n",abc_file_name);
+ }
+ abc_file=NULL;
+
+ if (profile_table_flag)
+ write_profile_table();
+
+ optimize_jumps();
+
+#if 0
+ if (list_flag){
+ show_code();
+ show_imports_and_exports();
+ }
+#endif
+
+#ifdef GENERATE_OBJECT_FILE
+ assemble_code();
+#endif
+
+ if (assembly_flag)
+ write_assembly();
+
+#ifdef GENERATE_OBJECT_FILE
+ if (fclose (obj_file)!=0){
+ obj_file=NULL;
+ error ("Error while writing object file");
+ }
+ obj_file=NULL;
+#endif
+ if (assembly_flag && fclose (assembly_file)!=0){
+ assembly_file=NULL;
+ error ("Error while writing assembly file");
+ }
+ assembly_file=NULL;
+ } else {
+ if (obj_file!=NULL)
+ fclose (obj_file);
+ if (assembly_file!=NULL)
+ fclose (assembly_file);
+ if (abc_file!=NULL)
+ fclose (abc_file);
+ }
+
+ if (assembly_file_name_s!=NULL)
+ memory_free (assembly_file_name_s);
+ if (object_file_name_s!=NULL)
+ memory_free (object_file_name_s);
+ if (abc_file_name!=NULL)
+ memory_free (abc_file_name);
+
+ release_memory();
+
+#ifdef PERFORMANCE
+ PerfDump (ThePGlobals,"\pPerform.out",0,0);
+ TermPerf (ThePGlobals);
+#endif
+
+ return r;
+}
+
+#endif