* src/z80/mappings.i: Added z80asm support.
[fw/sdcc] / src / SDCCglue.c
index 460342a03a62e2f3bf43fb8507f609f4ccd9ca9d..1e66c123fd479d78954dff94ff4e555f446e4fb1 100644 (file)
 #include "newalloc.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];
@@ -48,7 +38,7 @@ 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;
+unsigned maxInterrupts = 6;
 int allocInfo = 1;
 symbol *mainf;
 extern char *VersionString;
@@ -80,7 +70,7 @@ DEFSETFUNC (rmTmpFiles)
   if (name)
     {
       unlink (name);
-      free (name);
+      Safe_free (name);
     }
   return 0;
 }
@@ -109,10 +99,15 @@ aopLiteralLong (value * val, int offset, int size)
        }
        fl;
 
+       if (!val) {
+         // assuming we have been warned before
+         val=constVal("0");
+       }
+
        /* if it is a float then it gets tricky */
        /* otherwise it is fairly simple */
        if (!IS_FLOAT (val->type)) {
-               unsigned long v = floatFromVal (val);
+               unsigned long v = (unsigned long) floatFromVal (val);
 
                v >>= (offset * 8);
                switch (size) {
@@ -159,7 +154,9 @@ aopLiteral (value * val, int offset)
 static void 
 emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 {
-  symbol *sym;
+  symbol *sym, *symIval;
+  ast *ival = NULL;
+  memmap *segment;
 
   if (addPublics)
     {
@@ -173,34 +170,42 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
       else
        tfprintf (map->oFile, "\t!area\n", map->sname);
     }
-
-  /* print the area name */
   for (sym = setFirstItem (map->syms); sym;
        sym = setNextItem (map->syms))
     {
+      symbol *newSym=NULL;
+
 
       /* if extern then add it into the extern list */
       if (IS_EXTERN (sym->etype))
        {
-         addSetHead (&externs, sym);
+          addSetHead (&externs, sym);
          continue;
        }
 
       /* if allocation required check is needed
          then check if the symbol really requires
          allocation only for local variables */
+
       if (arFlag && !IS_AGGREGATE (sym->type) &&
          !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
          !sym->allocreq && sym->level)
        continue;
 
+      /* for bitvar locals and parameters */
+      if (!arFlag && !sym->allocreq && sym->level 
+         && !SPEC_ABSA (sym->etype)) {
+       continue;
+      }
+
       /* if global variable & not static or extern
          and addPublics allowed then add it to the public set */
       if ((sym->level == 0 ||
           (sym->_isparm && !IS_REGPARM (sym->etype))) &&
          addPublics &&
          !IS_STATIC (sym->etype) &&
-         (sym->used || sym->fbody))
+          (IS_FUNC(sym->type) ? (sym->used || IFFUNC_HASBODY(sym->type)) : 1))
        {
          addSetHead (&publics, sym);
        }
@@ -211,62 +216,110 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
        continue;
 
       /* print extra debug info if required */
-      if ((options.debug || sym->level == 0) && !options.nodebug)
-       {
-
-         cdbSymbol (sym, cdbFile, FALSE, FALSE);
-
-         if (!sym->level)      /* global */
-           if (IS_STATIC (sym->etype))
-             fprintf (map->oFile, "F%s$", moduleName);         /* scope is file */
-           else
-             fprintf (map->oFile, "G$");       /* scope is global */
+      if (options.debug) {
+       cdbSymbol (sym, cdbFile, FALSE, FALSE);
+       if (!sym->level) /* global */
+         if (IS_STATIC (sym->etype))
+           fprintf (map->oFile, "F%s$", moduleName); /* scope is file */
          else
-           /* symbol is local */
-           fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
-         fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
+           fprintf (map->oFile, "G$"); /* scope is global */
+       else
+         /* symbol is local */
+         fprintf (map->oFile, "L%s$", (sym->localof ? sym->localof->name : "-null-"));
+       fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
+      }
+      
+      /* if it has an initial value then do it only if
+         it is a global variable */
+      if (sym->ival && sym->level == 0) {
+       if (SPEC_OCLS(sym->etype)==xidata) {
+         // create a new "XINIT (CODE)" symbol, that will be emitted later
+         newSym=copySymbol (sym);
+         SPEC_OCLS(newSym->etype)=xinit;
+         sprintf (newSym->name, "_xinit_%s", sym->name);
+         sprintf (newSym->rname,"_xinit_%s", sym->rname);
+         SPEC_CONST(newSym->etype)=1;
+         //SPEC_STAT(newSym->etype)=1;
+         addSym (SymbolTab, newSym, newSym->name, 0, 0, 1);
+         
+         // add it to the "XINIT (CODE)" segment
+         addSet(&xinit->syms, newSym);
+
+         //fprintf (stderr, "moved %s from xdata to xidata\n", sym->rname);
+         
+       } else {
+         if (IS_AGGREGATE (sym->type)) {
+           ival = initAggregates (sym, sym->ival, NULL);
+         } else {
+           if (getNelements(sym->type, sym->ival)>1) {
+             werror (W_EXCESS_INITIALIZERS, "scalar", 
+                     sym->name, sym->lineDef);
+           }
+           ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
+                           decorateType (resolveSymbols (list2expr (sym->ival))));
+         }
+         codeOutFile = statsg->oFile;
+
+         if (ival) {
+           // set ival's lineno to where the symbol was defined
+           lineno=ival->lineno=sym->lineDef;
+           
+           // check if this is a constant expression
+           if (constExprTree(ival->right)) {
+             allocInfo = 0;
+             eBBlockFromiCode (iCodeFromAst (ival));
+             allocInfo = 1;
+           } else {
+             werror (E_CONST_EXPECTED, "found expression");
+           }
+         }
+       }         
+
+       /* if the ival is a symbol assigned to an aggregate,
+          (bug #458099 -> #462479)
+          we don't need it anymore, so delete it from its segment */
+       if (sym->ival->type == INIT_NODE &&
+           IS_AST_SYM_VALUE(sym->ival->init.node) &&
+           IS_AGGREGATE (sym->type) ) {
+         symIval=AST_SYMBOL(sym->ival->init.node);
+         segment = SPEC_OCLS (symIval->etype);
+         deleteSetItem (&segment->syms, symIval);
        }
+       
+       sym->ival = NULL;
+      }
 
       /* if is has an absolute address then generate
          an equate for this no need to allocate space */
       if (SPEC_ABSA (sym->etype))
        {
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug) {
            fprintf (map->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
+         }
          fprintf (map->oFile, "%s\t=\t0x%04x\n",
                   sym->rname,
                   SPEC_ADDR (sym->etype));
        }
-      else
-       {
-         /* allocate space */
-         if ((options.debug || sym->level == 0) && !options.nodebug)
-           fprintf (map->oFile, "==.\n");
-         if (IS_STATIC (sym->etype))
-           tfprintf (map->oFile, "!slabeldef\n", sym->rname);
-         else
-           tfprintf (map->oFile, "!labeldef\n", sym->rname);
-         tfprintf (map->oFile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
-       }
-
-      /* 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;
-
-         if (IS_AGGREGATE (sym->type))
-           ival = initAggregates (sym, sym->ival, NULL);
-         else
-           ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
-                    decorateType (resolveSymbols (list2expr (sym->ival))));
-         codeOutFile = statsg->oFile;
-         allocInfo = 0;
-         eBBlockFromiCode (iCodeFromAst (ival));
-         allocInfo = 1;
-         sym->ival = NULL;
-       }
+      else {
+         if (newSym) {
+             // this has been moved to another segment
+         } else {
+             int size = getSize (sym->type);
+             if (size==0) {
+                 werror(E_UNKNOWN_SIZE,sym->name);
+             }
+             /* allocate space */
+             if (options.debug) {
+                 fprintf (map->oFile, "==.\n");
+             }
+             if (IS_STATIC (sym->etype))
+                 tfprintf (map->oFile, "!slabeldef\n", sym->rname);
+             else
+                 tfprintf (map->oFile, "!labeldef\n", sym->rname);           
+             tfprintf (map->oFile, "\t!ds\n", 
+                       (unsigned int)  size & 0xffff);
+         }
+      }
     }
 }
 
@@ -373,7 +426,7 @@ initPointer (initList * ilist)
                return val;
        }
  wrong:
-       werror (E_INIT_WRONG);
+       werror (W_INIT_WRONG);
        return NULL;
 
 }
@@ -395,12 +448,12 @@ printChar (FILE * ofile, char *s, int plen)
       i = 60;
       while (i && *s && pplen < plen)
        {
-         if (*s < ' ' || *s == '\"')
+         if (*s < ' ' || *s == '\"' || *s=='\\')
            {
              *p = '\0';
              if (p != buf)
                tfprintf (ofile, "\t!ascii\n", buf);
-             tfprintf (ofile, "\t!db !constbyte\n", *s);
+             tfprintf (ofile, "\t!db !constbyte\n", (unsigned char)*s);
              p = buf;
            }
          else
@@ -431,7 +484,7 @@ printChar (FILE * ofile, char *s, int plen)
 /* return the generic pointer high byte for a given pointer type.  */
 /*-----------------------------------------------------------------*/
 int 
-pointerTypeToGPByte (const int p_type)
+pointerTypeToGPByte (const int p_type, const char *iname, const char *oname)
 {
   switch (p_type)
     {
@@ -442,6 +495,9 @@ pointerTypeToGPByte (const int p_type)
       /* hack - if we get a generic pointer, we just assume
        * it's an FPOINTER (i.e. in XDATA space).
        */
+      werror (E_CANNOT_USE_GENERIC_POINTER, iname, oname);
+      exit (1);
+      // fall through
     case FPOINTER:
       return 1;
     case CPOINTER:
@@ -463,7 +519,8 @@ pointerTypeToGPByte (const int p_type)
 void 
 _printPointerType (FILE * oFile, const char *name)
 {
-  if (TARGET_IS_DS390)
+  /* if (TARGET_IS_DS390) */
+  if (options.model == MODEL_FLAT24)
     {
       fprintf (oFile, "\t.byte %s,(%s >> 8),(%s >> 16)", name, name, name);
     }
@@ -487,18 +544,18 @@ printPointerType (FILE * oFile, const char *name)
 /* printGPointerType - generates ival for generic pointer type     */
 /*-----------------------------------------------------------------*/
 void 
-printGPointerType (FILE * oFile, const char *name,
+printGPointerType (FILE * oFile, const char *iname, const char *oname,
                   const unsigned int type)
 {
-  _printPointerType (oFile, name);
-  fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type));
+  _printPointerType (oFile, iname);
+  fprintf (oFile, ",#0x%02x\n", pointerTypeToGPByte (type, iname, oname));
 }
 
 /*-----------------------------------------------------------------*/
 /* printIvalType - generates ival for int/char                     */
 /*-----------------------------------------------------------------*/
 void 
-printIvalType (sym_link * type, initList * ilist, FILE * oFile)
+printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
 {
        value *val;
 
@@ -506,7 +563,19 @@ printIvalType (sym_link * type, initList * ilist, FILE * oFile)
        if (ilist->type == INIT_DEEP)
                ilist = ilist->init.deep;
 
-       val = list2val (ilist);
+       if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
+         werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
+       }
+
+       if (!(val = list2val (ilist))) {
+         // assuming a warning has been thrown
+         val=constVal("0");
+       }
+
+       if (val->type != type) {
+         val = valCastLiteral(type, floatFromVal(val));
+       }
+       
        switch (getSize (type)) {
        case 1:
                if (!val)
@@ -608,9 +677,12 @@ printIvalStruct (symbol * sym, sym_link * type,
                if (IS_BITFIELD(sflds->type)) {
                        printIvalBitFields(&sflds,&iloop,oFile);
                } else {
-                       printIval (sflds, sflds->type, iloop, oFile);
+                       printIval (sym, sflds->type, iloop, oFile);
                }
        }
+       if (iloop) {
+         werror (W_EXCESS_INITIALIZERS, "struct", sym->name, sym->lineDef);
+       }
        return;
 }
 
@@ -692,8 +764,13 @@ printIvalArray (symbol * sym, sym_link * type, initList * ilist,
 
       /* no of elements given and we    */
       /* have generated for all of them */
-      if (!--lcnt)
+      if (!--lcnt) {
+       /* if initializers left */
+       if (iloop) {
+         werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
+       }
        break;
+      }
     }
 
   /* if we have not been given a size  */
@@ -714,7 +791,7 @@ printIvalFuncPtr (sym_link * type, initList * ilist, FILE * oFile)
 
   val = list2val (ilist);
   /* check the types   */
-  if ((dLvl = checkType (val->type, type->next)) <= 0)
+  if ((dLvl = compareType (val->type, type->next)) <= 0)
     {
       tfprintf (oFile, "\t!dw !constword\n", 0);
       return;
@@ -778,10 +855,17 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
        }
       else if (size == GPTRSIZE)
        {
-         /* PENDING: 0x02 or 0x%02x, CDATA? */
-         printGPointerType (oFile, val->name,
-                            (IS_PTR (val->type) ? DCL_TYPE (val->type) :
-                             PTR_TYPE (SPEC_OCLS (val->etype))));
+         int type;
+         if (IS_PTR (val->type)) {
+           type = DCL_TYPE (val->type);
+         } else {
+           type = PTR_TYPE (SPEC_OCLS (val->etype));
+         }
+         if (val->sym && val->sym->isstrlit) {
+           // this is a literal string
+           type=CPOINTER;
+         }
+         printGPointerType (oFile, val->name, sym->name, type);
        }
       else
        {
@@ -791,7 +875,7 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
     }
   else
     {
-      /* What is this case? Are these pointers? */
+      // these are literals assigned to pointers
       switch (size)
        {
        case 1:
@@ -805,9 +889,25 @@ printIvalCharPtr (symbol * sym, sym_link * type, value * val, FILE * oFile)
                      aopLiteral (val, 0), aopLiteral (val, 1));
          break;
        case 3:
-         /* PENDING: 0x02 or 0x%02x, CDATA? */
-         fprintf (oFile, "\t.byte %s,%s,#0x02\n",
-                  aopLiteral (val, 0), aopLiteral (val, 1));
+         // mcs51 generic pointer
+         if (floatFromVal(val)!=0) {
+           werror (E_LITERAL_GENERIC);
+         }
+         fprintf (oFile, "\t.byte %s,%s,%s\n",
+                  aopLiteral (val, 0), 
+                  aopLiteral (val, 1),
+                  aopLiteral (val, 2));
+         break;
+       case 4:
+         // ds390 generic pointer
+         if (floatFromVal(val)!=0) {
+           werror (E_LITERAL_GENERIC);
+         }
+         fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
+                  aopLiteral (val, 0), 
+                  aopLiteral (val, 1), 
+                  aopLiteral (val, 2),
+                  aopLiteral (val, 3));
          break;
        default:
          assert (0);
@@ -850,8 +950,8 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
       return;
 
   /* check the type      */
-  if (checkType (type, val->type) == 0)
-    werror (E_INIT_WRONG);
+  if (compareType (type, val->type) == 0)
+    werror (W_INIT_WRONG);
 
   /* if val is literal */
   if (IS_LITERAL (val->etype))
@@ -883,11 +983,15 @@ printIvalPtr (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
     }
   else if (size == FPTRSIZE)
     {
-      tfprintf (oFile, "\t!dws\n", val->name);
+      if (port->use_dw_for_init) {
+       tfprintf (oFile, "\t!dws\n", val->name);
+      } else {
+       printPointerType (oFile, val->name);
+      }
     }
   else if (size == GPTRSIZE)
     {
-      printGPointerType (oFile, val->name,
+      printGPointerType (oFile, val->name, sym->name,
                         (IS_PTR (val->type) ? DCL_TYPE (val->type) :
                          PTR_TYPE (SPEC_OCLS (val->etype))));
     }
@@ -927,7 +1031,7 @@ printIval (symbol * sym, sym_link * type, initList * ilist, FILE * oFile)
   /* if type is SPECIFIER */
   if (IS_SPEC (type))
     {
-      printIvalType (type, ilist, oFile);
+      printIvalType (sym, type, ilist, oFile);
       return;
     }
 }
@@ -940,9 +1044,7 @@ emitStaticSeg (memmap * map, FILE * out)
 {
   symbol *sym;
 
-  /*     fprintf(map->oFile,"\t.area\t%s\n",map->sname); */
-  if (!out)
-    out = code->oFile;
+  /* fprintf(out, "\t.area\t%s\n", map->sname); */
 
   /* for all variables in this segment do */
   for (sym = setFirstItem (map->syms); sym;
@@ -956,43 +1058,42 @@ emitStaticSeg (memmap * map, FILE * out)
       /* if it is not static add it to the public
          table */
       if (!IS_STATIC (sym->etype))
-       addSetHead (&publics, sym);
+        {
+          addSetHead (&publics, sym);
+        }
 
       /* print extra debug info if required */
-      if ((options.debug || sym->level == 0) && !options.nodebug)
-       {
-
-         cdbSymbol (sym, cdbFile, FALSE, FALSE);
-
-         if (!sym->level)
-           {                   /* global */
-             if (IS_STATIC (sym->etype))
-               fprintf (out, "F%s$", moduleName);      /* scope is file */
-             else
-               fprintf (out, "G$");    /* scope is global */
-           }
-         else
-           /* symbol is local */
-           fprintf (out, "L%s$",
-                    (sym->localof ? sym->localof->name : "-null-"));
-         fprintf (out, "%s$%d$%d", sym->name, sym->level, sym->block);
-       }
-
+      if (options.debug) {
+       cdbSymbol (sym, cdbFile, FALSE, FALSE);
+       if (!sym->level)
+         {                     /* global */
+           if (IS_STATIC (sym->etype))
+             fprintf (out, "F%s$", moduleName);        /* scope is file */
+           else
+             fprintf (out, "G$");      /* scope is global */
+         }
+       else
+         /* symbol is local */
+         fprintf (out, "L%s$",
+                  (sym->localof ? sym->localof->name : "-null-"));
+       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)
+         if (options.debug)
            fprintf (out, " == 0x%04x\n", SPEC_ADDR (sym->etype));
-
+         
          fprintf (out, "%s\t=\t0x%04x\n",
                   sym->rname,
                   SPEC_ADDR (sym->etype));
        }
       else
        {
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug)
            fprintf (out, " == .\n");
-
+         
          /* if it has an initial value */
          if (sym->ival)
            {
@@ -1002,18 +1103,22 @@ emitStaticSeg (memmap * map, FILE * out)
              printIval (sym, sym->type, sym->ival, out);
              noAlloc--;
            }
-         else
-           {
+         else {
              /* allocate space */
+             int size = getSize (sym->type);
+             
+             if (size==0) {
+                 werror(E_UNKNOWN_SIZE,sym->name);
+             }
              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 (out,
-                          SPEC_CVAL (sym->etype).v_char,
-                          strlen (SPEC_CVAL (sym->etype).v_char) + 1);
+                 printChar (out,
+                            SPEC_CVAL (sym->etype).v_char,
+                            strlen (SPEC_CVAL (sym->etype).v_char) + 1);
              else
-               tfprintf (out, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
+                 tfprintf (out, "\t!ds\n", (unsigned int) size & 0xffff);
            }
        }
     }
@@ -1025,18 +1130,27 @@ emitStaticSeg (memmap * map, FILE * out)
 void 
 emitMaps ()
 {
+  inInitMode++;
   /* no special considerations for the following
      data, idata & bit & xdata */
   emitRegularMap (data, TRUE, TRUE);
   emitRegularMap (idata, TRUE, TRUE);
   emitRegularMap (bit, TRUE, FALSE);
   emitRegularMap (xdata, TRUE, TRUE);
+  if (port->genXINIT) {
+    emitRegularMap (xidata, TRUE, TRUE);
+  }
   emitRegularMap (sfr, FALSE, FALSE);
   emitRegularMap (sfrbit, FALSE, FALSE);
   emitRegularMap (home, TRUE, FALSE);
   emitRegularMap (code, TRUE, FALSE);
 
   emitStaticSeg (statsg, code->oFile);
+  if (port->genXINIT) {
+    fprintf (code->oFile, "\t.area\t%s\n", xinit->sname);
+    emitStaticSeg (xinit, code->oFile);
+  }
+  inInitMode--;
 }
 
 /*-----------------------------------------------------------------*/
@@ -1056,23 +1170,23 @@ flushStatics (void)
 void 
 createInterruptVect (FILE * vFile)
 {
-  int i = 0;
+  unsigned i = 0;
   mainf = newSymbol ("main", 0);
   mainf->block = 0;
 
   /* only if the main function exists */
   if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
     {
-      if (!options.cc_only)
+      if (!options.cc_only && !noAssemble)
        werror (E_NO_MAIN);
       return;
     }
 
   /* if the main is only a prototype ie. no body then do nothing */
-  if (!mainf->fbody)
+  if (!IFFUNC_HASBODY(mainf->type))
     {
       /* if ! compile only then main function should be present */
-      if (!options.cc_only)
+      if (!options.cc_only && !noAssemble)
        werror (E_NO_MAIN);
       return;
     }
@@ -1084,7 +1198,6 @@ createInterruptVect (FILE * vFile)
   if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
     {
       /* "generic" interrupt table header (if port doesn't specify one).
-
        * Look suspiciously like 8051 code to me...
        */
 
@@ -1156,7 +1269,7 @@ printExterns (FILE * afile)
 
   for (sym = setFirstItem (externs); sym;
        sym = setNextItem (externs))
-    tfprintf (afile, "\t!global\n", sym->rname);
+    tfprintf (afile, "\t!extern\n", sym->rname);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1179,11 +1292,15 @@ emitOverlay (FILE * afile)
 
       if (elementsInSet (ovrset))
        {
+#if 0
          /* this dummy area is used to fool the assembler
             otherwise the assembler will append each of these
             declarations into one chunk and will not overlay
             sad but true */
          fprintf (afile, "\t.area _DUMMY\n");
+#else
+         /* not anymore since asmain.c:1.13 */
+#endif
          /* output the area informtion */
          fprintf (afile, "\t.area\t%s\n", port->mem.overlay_name);     /* MOF */
        }
@@ -1208,7 +1325,9 @@ emitOverlay (FILE * afile)
             and addPublics allowed then add it to the public set */
          if ((sym->_isparm && !IS_REGPARM (sym->etype))
              && !IS_STATIC (sym->etype))
-           addSetHead (&publics, sym);
+            {
+              addSetHead (&publics, sym);
+            }
 
          /* if extern then do nothing or is a function
             then do nothing */
@@ -1216,9 +1335,8 @@ emitOverlay (FILE * afile)
            continue;
 
          /* print extra debug info if required */
-         if ((options.debug || sym->level == 0) && !options.nodebug)
+         if (options.debug)
            {
-
              cdbSymbol (sym, cdbFile, FALSE, FALSE);
 
              if (!sym->level)
@@ -1240,23 +1358,27 @@ emitOverlay (FILE * afile)
          if (SPEC_ABSA (sym->etype))
            {
 
-             if ((options.debug || sym->level == 0) && !options.nodebug)
+             if (options.debug)
                fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
 
              fprintf (afile, "%s\t=\t0x%04x\n",
                       sym->rname,
                       SPEC_ADDR (sym->etype));
            }
-         else
-           {
-             if ((options.debug || sym->level == 0) && !options.nodebug)
-               fprintf (afile, "==.\n");
-
+         else {
+             int size = getSize(sym->type);
+
+             if (size==0) {
+                 werror(E_UNKNOWN_SIZE,sym->name);
+             }       
+             if (options.debug)
+                 fprintf (afile, "==.\n");
+             
              /* allocate space */
              tfprintf (afile, "!labeldef\n", sym->rname);
              tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
-           }
-
+         }
+         
        }
     }
 }
@@ -1273,7 +1395,7 @@ glue ()
 
   addSetHead (&tmpfileSet, ovrFile);
   /* print the global struct definitions */
-  if (options.debug && !options.nodebug)
+  if (options.debug)
     cdbStructBlock (0, cdbFile);
 
   vFile = tempfile ();
@@ -1296,17 +1418,17 @@ glue ()
 
   if (!options.c1mode)
     {
-      sprintf (buffer, srcFileName);
-      strcat (buffer, port->assembler.file_ext);
+      sprintf (scratchFileName, srcFileName);
+      strcat (scratchFileName, port->assembler.file_ext);
     }
   else
     {
-      strcpy (buffer, options.out_name);
+      strcpy (scratchFileName, options.out_name);
     }
 
-  if (!(asmFile = fopen (buffer, "w")))
+  if (!(asmFile = fopen (scratchFileName, "w")))
     {
-      werror (E_FILE_OPEN_ERR, buffer);
+      werror (E_FILE_OPEN_ERR, scratchFileName);
       exit (1);
     }
 
@@ -1354,7 +1476,7 @@ glue ()
   copyFile (asmFile, ovrFile);
 
   /* create the stack segment MOF */
-  if (mainf && mainf->fbody)
+  if (mainf && IFFUNC_HASBODY(mainf->type))
     {
       fprintf (asmFile, "%s", iComments2);
       fprintf (asmFile, "; Stack segment in internal ram \n");
@@ -1376,7 +1498,7 @@ glue ()
   copyFile (asmFile, bit->oFile);
 
   /* if external stack then reserve space of it */
-  if (mainf && mainf->fbody && options.useXstack)
+  if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack)
     {
       fprintf (asmFile, "%s", iComments2);
       fprintf (asmFile, "; external stack \n");
@@ -1392,8 +1514,14 @@ glue ()
   fprintf (asmFile, "%s", iComments2);
   copyFile (asmFile, xdata->oFile);
 
+  /* copy xternal initialized ram data */
+  fprintf (asmFile, "%s", iComments2);
+  fprintf (asmFile, "; external initialized ram data\n");
+  fprintf (asmFile, "%s", iComments2);
+  copyFile (asmFile, xidata->oFile);
+
   /* copy the interrupt vector table */
-  if (mainf && mainf->fbody)
+  if (mainf && IFFUNC_HASBODY(mainf->type))
     {
       fprintf (asmFile, "%s", iComments2);
       fprintf (asmFile, "; interrupt vector \n");
@@ -1416,7 +1544,7 @@ glue ()
   tfprintf (asmFile, "\t!area\n", port->mem.post_static_name);
   tfprintf (asmFile, "\t!area\n", port->mem.static_name);
 
-  if (mainf && mainf->fbody)
+  if (mainf && IFFUNC_HASBODY(mainf->type))
     {
       fprintf (asmFile, "__sdcc_gsinit_startup:\n");
       /* if external stack is specified then the
@@ -1434,7 +1562,7 @@ glue ()
       /* initialise the stack pointer */
       /* if the user specified a value then use it */
       if (options.stack_loc)
-       fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc);
+       fprintf (asmFile, "\tmov\tsp,#%d\n", options.stack_loc & 0xff);
       else
        /* no: we have to compute it */
       if (!options.stackOnData && maxRegBank <= 3)
@@ -1448,10 +1576,15 @@ glue ()
       fprintf (asmFile, "\tljmp\t__sdcc_program_startup\n");
       fprintf (asmFile, "__sdcc_init_data:\n");
 
+      // if the port can copy the XINIT segment to XISEG
+      if (port->genXINIT) {
+       port->genXINIT(asmFile);
+      }
+
     }
   copyFile (asmFile, statsg->oFile);
 
-  if (port->general.glue_up_main && mainf && mainf->fbody)
+  if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
     {
       /* This code is generated in the post-static area.
        * This area is guaranteed to follow the static area
@@ -1473,7 +1606,7 @@ glue ()
   fprintf (asmFile, "; code\n");
   fprintf (asmFile, "%s", iComments2);
   tfprintf (asmFile, "\t!areacode\n", CODE_NAME);
-  if (mainf && mainf->fbody)
+  if (mainf && IFFUNC_HASBODY(mainf->type))
     {
 
       /* entry point @ start of CSEG */
@@ -1502,6 +1635,42 @@ glue ()
   applyToSet (tmpfileNameSet, rmTmpFiles);
 }
 
+#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (_MSC_VER)
+void
+rm_tmpfiles (void)
+{
+  applyToSet (tmpfileSet, closeTmpFiles);
+  applyToSet (tmpfileNameSet, rmTmpFiles);
+}
+#endif
+
+/** Creates a temporary file name a'la tmpnam which avoids the bugs
+    in cygwin wrt c:\tmp.
+    Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
+*/
+char *
+tempfilename (void)
+{
+#if !defined(_MSC_VER)
+  const char *tmpdir = NULL;
+  if (getenv ("TMP"))
+    tmpdir = getenv ("TMP");
+  else if (getenv ("TEMP"))
+    tmpdir = getenv ("TEMP");
+  else if (getenv ("TMPDIR"))
+    tmpdir = getenv ("TMPDIR");
+  if (tmpdir)
+    {
+      char *name = tempnam (tmpdir, "sdcc");
+      if (name)
+       {
+          return name;
+        }
+    }
+#endif
+  return tmpnam (NULL);
+}
+
 /** Creates a temporary file a'la tmpfile which avoids the bugs
     in cygwin wrt c:\tmp.
     Scans, in order: TMP, TEMP, TMPDIR, else uses tmpfile().
@@ -1519,7 +1688,7 @@ tempfile (void)
     tmpdir = getenv ("TMPDIR");
   if (tmpdir)
     {
-      char *name = tempnam (tmpdir, "sdcc");
+      char *name = Safe_strdup( tempnam (tmpdir, "sdcc"));
       if (name)
        {
          FILE *fp = fopen (name, "w+b");
@@ -1535,11 +1704,3 @@ tempfile (void)
   return tmpfile ();
 }
 
-char *
-gc_strdup (const char *s)
-{
-  char *ret;
-  ret = Safe_calloc (1, strlen (s) + 1);
-  strcpy (ret, s);
-  return ret;
-}