Remove all references to the GC library, replacing GC_malloc
[fw/sdcc] / src / SDCCglue.c
index 1a3c51584b852c777dcf462cdc5b3a2404a5d3a0..3cd5c434c72075cc38808ca87d78ed912d60a570 100644 (file)
 #include "asm.h"
 #include <time.h>
 
+#if    !defined(__BORLANDC__) && !defined(_MSC_VER)
+#if 0 /* This should no longer be necessary. */
+// This is a bit messy because we define link ourself
+#define link NoLiNk
+#include <unistd.h>
+#undef link
+#else
+
+#include <unistd.h>
+#endif
+#else
+// No unistd.h in Borland C++
+#endif
+
 symbol *interrupts[256];
-/*extern char *aopLiteral (value *, int);*//* drdani Jan 30 2000 */
-void printIval (symbol *, link *, initList *, FILE *);
-extern int noAlloc;
+
+void printIval (symbol *, sym_link *, initList *, FILE *);
 set *publics = NULL;           /* public variables */
 set *externs = NULL;           /* Varibles that are declared as extern */
 
 /* TODO: this should be configurable (DS803C90 uses more than 6) */
 int maxInterrupts = 6;
 int allocInfo = 1;
-extern int maxRegBank ;
 symbol *mainf;
 extern char *VersionString;
-extern FILE *codeOutFile;
 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
 set *tmpfileNameSet = NULL; /* All are unlinked at close. */
+
 /*-----------------------------------------------------------------*/
 /* closeTmpFiles - closes all tmp files created by the compiler    */
 /*                 because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
@@ -109,7 +121,7 @@ char *aopLiteralLong(value *val, int offset, int size)
            /* Hmm.  Too big for now. */
            assert(0);
        }
-        ALLOC_ATOMIC(rs,strlen(buffer)+1);
+        ALLOC(rs,strlen(buffer)+1);
         return strcpy (rs,buffer);
     }
 
@@ -123,7 +135,7 @@ char *aopLiteralLong(value *val, int offset, int size)
 #else
     tsprintf(buffer, "!immedbyte", fl.c[offset]);
 #endif
-    ALLOC_ATOMIC(rs,strlen(buffer)+1);
+    ALLOC(rs,strlen(buffer)+1);
     return strcpy (rs,buffer);
 }
 
@@ -144,8 +156,12 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
     
     if (addPublics) {
        /* PENDING: special case here - should remove */
-       if (!strcmp(map->sname, DATA_NAME))
+       if (!strcmp(map->sname, CODE_NAME))
+           tfprintf(map->oFile, "\t!areacode\n", map->sname);
+       else if (!strcmp(map->sname, DATA_NAME)) 
            tfprintf(map->oFile, "\t!areadata\n", map->sname);
+       else if (!strcmp(map->sname, HOME_NAME)) 
+           tfprintf(map->oFile, "\t!areahome\n", map->sname);
        else
            tfprintf(map->oFile, "\t!area\n", map->sname);
     }
@@ -173,8 +189,10 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
        if ((sym->level == 0 || 
             (sym->_isparm && !IS_REGPARM(sym->etype))) &&
            addPublics &&
-           !IS_STATIC (sym->etype))
+           !IS_STATIC (sym->etype) &&
+           (sym->used || sym->fbody)) {
            addSetHead (&publics, sym);
+       }
        
        /* if extern then do nothing or is a function 
           then do nothing */
@@ -218,7 +236,7 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
            tfprintf(map->oFile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff);
        }
        
-       /* if it has a initial value then do it only if
+       /* if it has an initial value then do it only if
           it is a global variable */
        if (sym->ival && sym->level == 0) {
            ast *ival = NULL;
@@ -226,7 +244,7 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
            if (IS_AGGREGATE (sym->type))
                ival = initAggregates (sym, sym->ival, NULL);
            else
-               ival = newNode ('=', newAst (EX_VALUE, symbolVal (sym)),
+               ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
                                decorateType (resolveSymbols (list2expr (sym->ival))));
            codeOutFile = statsg->oFile;
            allocInfo = 0;
@@ -237,7 +255,6 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
     }
 }
 
-
 /*-----------------------------------------------------------------*/
 /* initPointer - pointer initialization code massaging             */
 /*-----------------------------------------------------------------*/
@@ -343,7 +360,7 @@ void printChar (FILE * ofile, char *s, int plen)
                *p = '\0';
                if (p != buf) 
                    tfprintf(ofile, "\t!ascii\n", buf);
-               tfprintf(ofile, "\t!db\n", *s);
+               tfprintf(ofile, "\t!db !constbyte\n", *s);
                p = buf;
            }
            else {
@@ -365,13 +382,76 @@ void printChar (FILE * ofile, char *s, int plen)
        else
            len = 0;
     }
-    tfprintf(ofile, "\t!db\n", 0);
+    tfprintf(ofile, "\t!db !constbyte\n", 0);
+}
+
+/*-----------------------------------------------------------------*/
+/* return the generic pointer high byte for a given pointer type.  */
+/*-----------------------------------------------------------------*/
+int pointerTypeToGPByte(const int p_type)
+{
+    switch (p_type) 
+    {
+           case IPOINTER:
+           case POINTER:
+               return 0;
+           case GPOINTER:
+               /* hack - if we get a generic pointer, we just assume
+                * it's an FPOINTER (i.e. in XDATA space).
+                */
+           case FPOINTER:
+               return 1;
+           case CPOINTER:
+               return 2;
+           case PPOINTER:
+               return 3;
+           default:
+               fprintf(stderr, "*** internal error: unknown pointer type %d in GPByte.\n",
+                       p_type);
+               break;
+    }
+    return -1;
+}
+    
+    
+/*-----------------------------------------------------------------*/
+/* printPointerType - generates ival for pointer type              */
+/*-----------------------------------------------------------------*/
+void _printPointerType(FILE *oFile, const char *name)
+{
+    if (IS_DS390_PORT)
+    {
+       fprintf(oFile, "\t.byte %s,(%s >> 8),(%s >> 16)",name,name,name);
+    }
+    else
+    {
+       fprintf(oFile, "\t.byte %s,(%s >> 8)",name,name);
+    }
+}
+
+/*-----------------------------------------------------------------*/
+/* printPointerType - generates ival for pointer type              */
+/*-----------------------------------------------------------------*/
+void printPointerType(FILE *oFile, const char *name)
+{
+    _printPointerType(oFile, name);
+    fprintf(oFile, "\n");
+}
+
+/*-----------------------------------------------------------------*/
+/* printGPointerType - generates ival for generic pointer type     */
+/*-----------------------------------------------------------------*/
+void printGPointerType(FILE *oFile, const char *name, 
+                     const unsigned int type)
+{
+    _printPointerType(oFile,name);
+    fprintf(oFile, ",#0x%02x\n", pointerTypeToGPByte(type)); 
 }
 
 /*-----------------------------------------------------------------*/
 /* printIvalType - generates ival for int/char                     */
 /*-----------------------------------------------------------------*/
-void printIvalType (link * type, initList * ilist, FILE * oFile)
+void printIvalType (sym_link * type, initList * ilist, FILE * oFile)
 {
     value *val;
     
@@ -383,19 +463,22 @@ void printIvalType (link * type, initList * ilist, FILE * oFile)
     switch (getSize (type)) {
     case 1:
        if (!val)
-           tfprintf(oFile, "\t!db\n", 0);
+           tfprintf(oFile, "\t!db !constbyte\n", 0);
        else
            tfprintf(oFile, "\t!dbs\n",
                     aopLiteral (val, 0));
        break;
 
     case 2:
-       fprintf(oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1));
+       if (port->use_dw_for_init)
+           tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2));
+       else
+           fprintf(oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1));
        break;
     case 4:
        if (!val) {
-           tfprintf (oFile, "\t!dw\n", 0);
-           tfprintf (oFile, "\t!dw\n", 0);
+           tfprintf (oFile, "\t!dw !constword\n", 0);
+           tfprintf (oFile, "\t!dw !constword\n", 0);
        }
        else {
            fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
@@ -409,7 +492,7 @@ void printIvalType (link * type, initList * ilist, FILE * oFile)
 /*-----------------------------------------------------------------*/
 /* printIvalStruct - generates initial value for structures        */
 /*-----------------------------------------------------------------*/
-void printIvalStruct (symbol * sym,link * type,
+void printIvalStruct (symbol * sym,sym_link * type,
                      initList * ilist, FILE * oFile)
 {
     symbol *sflds;
@@ -432,7 +515,7 @@ void printIvalStruct (symbol * sym,link * type,
 /*-----------------------------------------------------------------*/
 /* printIvalChar - generates initital value for character array    */
 /*-----------------------------------------------------------------*/
-int printIvalChar (link * type, initList * ilist, FILE * oFile, char *s)
+int printIvalChar (sym_link * type, initList * ilist, FILE * oFile, char *s)
 {
     value *val;
     int remain;
@@ -453,7 +536,7 @@ int printIvalChar (link * type, initList * ilist, FILE * oFile, char *s)
            
            if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) -1))>0)
                while (remain--)
-                   tfprintf (oFile, "\t!db\n", 0);
+                   tfprintf (oFile, "\t!db !constbyte\n", 0);
            
            return 1;
        }
@@ -468,7 +551,7 @@ int printIvalChar (link * type, initList * ilist, FILE * oFile, char *s)
 /*-----------------------------------------------------------------*/
 /* printIvalArray - generates code for array initialization        */
 /*-----------------------------------------------------------------*/
-void printIvalArray (symbol * sym, link * type, initList * ilist,
+void printIvalArray (symbol * sym, sym_link * type, initList * ilist,
                     FILE * oFile)
 {
     initList *iloop;
@@ -519,7 +602,7 @@ void printIvalArray (symbol * sym, link * type, initList * ilist,
 /*-----------------------------------------------------------------*/
 /* printIvalFuncPtr - generate initial value for function pointers */
 /*-----------------------------------------------------------------*/
-void printIvalFuncPtr (link * type, initList * ilist, FILE * oFile)
+void printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
 {
     value *val;
     int dLvl = 0;
@@ -527,22 +610,30 @@ void printIvalFuncPtr (link * type, initList * ilist, FILE * oFile)
     val = list2val (ilist);
     /* check the types   */
     if ((dLvl = checkType (val->type, type->next)) <= 0) {
-       tfprintf(oFile, "\t!dw\n", 0);
+       tfprintf(oFile, "\t!dw !constword\n", 0);
        return;
     }
     
     /* now generate the name */
     if (!val->sym) {
         if (port->use_dw_for_init)
-           tfprintf(oFile, "\t!dw %s\n", val->name);
+       {
+           tfprintf(oFile, "\t!dws\n", val->name);
+       }
        else  
-           fprintf(oFile, "\t.byte %s,(%s >> 8)\n", val->name,val->name);
+       {
+           printPointerType(oFile, val->name);
+       }
     }
     else
        if (port->use_dw_for_init)
+       {
            tfprintf(oFile, "\t!dws\n", val->sym->rname);
-       else 
-           fprintf(oFile, "\t.byte %s,(%s >> 8)\n", val->sym->rname,val->sym->rname);
+       }
+       else
+       {
+           printPointerType(oFile, val->sym->rname);
+       }
     
     return;
 }
@@ -550,7 +641,7 @@ void printIvalFuncPtr (link * type, initList * ilist, FILE * oFile)
 /*-----------------------------------------------------------------*/
 /* printIvalCharPtr - generates initial values for character pointers */
 /*-----------------------------------------------------------------*/
-int printIvalCharPtr (symbol * sym, link * type, value * val, FILE * oFile)
+int printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
 {
     int size = 0;
     
@@ -561,34 +652,47 @@ int printIvalCharPtr (symbol * sym, link * type, value * val, FILE * oFile)
     size = getSize (type);
 
     if (val->name && strlen(val->name)) {
-       switch (size) {
-       case 1:
+       if (size == 1) /* This appears to be Z80 specific?? */
+       {
            tfprintf(oFile,
-                   "\t!dbs\n", val->name) ;
-           break;
-       case 2:
+                   "\t!dbs\n", val->name);
+       }
+       else if (size == FPTRSIZE)
+       {
            if (port->use_dw_for_init)
+           {
                tfprintf(oFile, "\t!dws\n", val->name);
+           }
            else
-               fprintf(oFile, "\t.byte %s,(%s >> 8)\n", val->name, val->name);
-           break;
-           /* PENDING: probably just 3 */
-       default:
+           {
+               printPointerType(oFile, val->name);
+           }
+       }
+       else  if (size == GPTRSIZE)
+       {
            /* PENDING: 0x02 or 0x%02x, CDATA? */
-           fprintf (oFile,
-                    "\t.byte %s,(%s >> 8),#0x%02x\n",
-                    val->name, val->name, (IS_PTR(val->type) ? DCL_TYPE(val->type) :
-                                           PTR_TYPE(SPEC_OCLS(val->etype))));
+           printGPointerType(oFile, val->name, 
+                             (IS_PTR(val->type) ? DCL_TYPE(val->type) :
+                             PTR_TYPE(SPEC_OCLS(val->etype))));
+       }
+       else
+       {
+           fprintf(stderr, "*** internal error: unknown size in "
+                           "printIvalCharPtr.\n");
        }
     }
     else {
+       /* What is this case? Are these pointers? */
        switch (size) {
        case 1:
            tfprintf(oFile, "\t!dbs\n", aopLiteral(val, 0));
            break;
        case 2:
-           tfprintf(oFile, "\t.byte %s,%s\n", 
-                   aopLiteral(val, 0),aopLiteral(val, 1));
+           if (port->use_dw_for_init)
+               tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, size));
+           else 
+               tfprintf(oFile, "\t.byte %s,%s\n", 
+                        aopLiteral(val, 0),aopLiteral(val, 1));
            break;
        case 3:
            /* PENDING: 0x02 or 0x%02x, CDATA? */
@@ -610,9 +714,10 @@ int printIvalCharPtr (symbol * sym, link * type, value * val, FILE * oFile)
 /*-----------------------------------------------------------------*/
 /* printIvalPtr - generates initial value for pointers             */
 /*-----------------------------------------------------------------*/
-void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
+void printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
 {
     value *val;
+    int size;
     
     /* if deep then   */
     if (ilist->type == INIT_DEEP)
@@ -640,10 +745,13 @@ void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
     if (IS_LITERAL (val->etype)) {
        switch (getSize (type)) {
        case 1:
-           tfprintf(oFile, "\t!db\n", (unsigned int)floatFromVal(val) & 0xff);
+           tfprintf(oFile, "\t!db !constbyte\n", (unsigned int)floatFromVal(val) & 0xff);
            break;
        case 2:
-           tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1));
+           if (port->use_dw_for_init)
+               tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2));
+           else
+               tfprintf (oFile, "\t.byte %s,%s\n", aopLiteral(val, 0),aopLiteral(val, 1));
            break;
        case 3:
            fprintf (oFile, "\t.byte %s,%s,#0x02\n",
@@ -653,18 +761,21 @@ void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
     }
     
     
-    switch (getSize (type)) {
-    case 1:
+    size = getSize (type);
+    
+    if (size == 1)  /* Z80 specific?? */
+    {
        tfprintf (oFile, "\t!dbs\n", val->name);
-       break;
-    case 2:
+    }
+    else if (size == FPTRSIZE)
+    {
        tfprintf (oFile, "\t!dws\n", val->name);
-       break;
-       
-    case 3:
-       fprintf (oFile, "\t.byte %s,(%s >> 8),#0x%02x\n",
-                val->name, val->name,(IS_PTR(val->type) ? DCL_TYPE(val->type) :
-                                           PTR_TYPE(SPEC_OCLS(val->etype))));
+    }
+    else if (size == GPTRSIZE)
+    {
+       printGPointerType(oFile, val->name, 
+                     (IS_PTR(val->type) ? DCL_TYPE(val->type) :
+                     PTR_TYPE(SPEC_OCLS(val->etype))));
     }
     return;
 }
@@ -672,7 +783,7 @@ void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
 /*-----------------------------------------------------------------*/
 /* printIval - generates code for initial value                    */
 /*-----------------------------------------------------------------*/
-void printIval (symbol * sym, link * type, initList * ilist, FILE * oFile)
+void printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
 {
     if (!ilist)
        return;    
@@ -705,13 +816,14 @@ void printIval (symbol * sym, link * type, initList * ilist, FILE * oFile)
 /*-----------------------------------------------------------------*/
 /* emitStaticSeg - emitcode for the static segment                 */
 /*-----------------------------------------------------------------*/
-void emitStaticSeg (memmap * map)
+void emitStaticSeg(memmap * map, FILE *out)
 {
     symbol *sym;
     
     /*     fprintf(map->oFile,"\t.area\t%s\n",map->sname); */
-    
-    
+    if (!out)
+       out = code->oFile;
+
     /* for all variables in this segment do */
     for (sym = setFirstItem (map->syms); sym;
         sym = setNextItem (map->syms)) {
@@ -732,49 +844,49 @@ void emitStaticSeg (memmap * map)
 
            if (!sym->level) { /* global */
                if (IS_STATIC(sym->etype))
-                   fprintf(code->oFile,"F%s$",moduleName); /* scope is file */
+                   fprintf(out,"F%s$",moduleName); /* scope is file */
                else
-                   fprintf(code->oFile,"G$"); /* scope is global */
+                   fprintf(out,"G$"); /* scope is global */
            }
            else
                /* symbol is local */
-               fprintf(code->oFile,"L%s$",
+               fprintf(out,"L%s$",
                        (sym->localof ? sym->localof->name : "-null-"));
-           fprintf(code->oFile,"%s$%d$%d",sym->name,sym->level,sym->block);
+           fprintf(out,"%s$%d$%d",sym->name,sym->level,sym->block);
        }
        
        /* if it has an absolute address */
        if (SPEC_ABSA (sym->etype)) {
            if ((options.debug || sym->level == 0) && !options.nodebug)
-               fprintf(code->oFile," == 0x%04x\n", SPEC_ADDR (sym->etype));
+               fprintf(out," == 0x%04x\n", SPEC_ADDR (sym->etype));
 
-           fprintf (code->oFile, "%s\t=\t0x%04x\n",
+           fprintf (out, "%s\t=\t0x%04x\n",
                     sym->rname,
                     SPEC_ADDR (sym->etype));
        }
        else {
            if ((options.debug || sym->level == 0) && !options.nodebug)
-               fprintf(code->oFile," == .\n"); 
+               fprintf(out," == .\n"); 
 
            /* if it has an initial value */
            if (sym->ival) {
-               fprintf (code->oFile, "%s:\n", sym->rname);
+               fprintf (out, "%s:\n", sym->rname);
                noAlloc++;
                resolveIvalSym (sym->ival);
-               printIval (sym, sym->type, sym->ival, code->oFile);
+               printIval (sym, sym->type, sym->ival, out);
                noAlloc--;
            }
            else {
                /* allocate space */
-               fprintf (code->oFile, "%s:\n", sym->rname);
+               fprintf (out, "%s:\n", sym->rname);
                /* special case for character strings */
                if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
                    SPEC_CVAL (sym->etype).v_char)
-                   printChar (code->oFile,
+                   printChar (out,
                               SPEC_CVAL (sym->etype).v_char,
                               strlen(SPEC_CVAL (sym->etype).v_char)+1);
                else 
-                   tfprintf(code->oFile, "\t!ds\n", (unsigned int)getSize (sym->type)& 0xffff);
+                   tfprintf(out, "\t!ds\n", (unsigned int)getSize (sym->type)& 0xffff);
            }
        }
     }
@@ -793,8 +905,20 @@ void emitMaps ()
     emitRegularMap (xdata, TRUE,TRUE);
     emitRegularMap (sfr, FALSE,FALSE);
     emitRegularMap (sfrbit, FALSE,FALSE);
+    emitRegularMap (home, TRUE,FALSE);
     emitRegularMap (code, TRUE,FALSE);
-    emitStaticSeg (statsg);
+
+    emitStaticSeg (statsg, code->oFile);
+}
+
+/*-----------------------------------------------------------------*/
+/* flushStatics - flush all currently defined statics out to file  */
+/*  and delete.  Temporary function                                */
+/*-----------------------------------------------------------------*/
+void flushStatics(void)
+{
+    emitStaticSeg(statsg, codeOutFile);
+    statsg->syms = NULL;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1004,7 +1128,7 @@ void glue ()
     
     addSetHead(&tmpfileSet,ovrFile);
     /* print the global struct definitions */
-    if (options.debug)
+    if (options.debug && !options.nodebug)
        cdbStructBlock (0,cdbFile);
 
     vFile = tempfile();
@@ -1182,7 +1306,14 @@ void glue ()
        tfprintf(asmFile, "\t!area\n", port->mem.post_static_name);
        fprintf (asmFile,"\tljmp\t__sdcc_program_startup\n");
     }
-       
+
+    fprintf (asmFile,
+            "%s"
+            "; Home\n"
+            "%s", iComments2, iComments2);
+    tfprintf(asmFile, "\t!areahome\n", HOME_NAME);
+    copyFile (asmFile, home->oFile);
+
     /* copy over code */
     fprintf (asmFile, "%s", iComments2);
     fprintf (asmFile, "; code\n");
@@ -1231,7 +1362,9 @@ FILE *tempfile(void)
        if (name) {
            FILE *fp = fopen(name, "w+b");
            if (fp)
+           {
                addSetHead(&tmpfileNameSet, name);
+           }
            return fp;
        }
        return NULL;
@@ -1242,7 +1375,7 @@ FILE *tempfile(void)
 char *gc_strdup(const char *s)
 {
     char *ret;
-    ALLOC_ATOMIC(ret, strlen(s)+1);
+    ALLOC(ret, strlen(s)+1);
     strcpy(ret, s);
     return ret;
 }