* src/z80/mappings.i: Added z80asm support.
[fw/sdcc] / src / SDCCglue.c
index 4895a3e0cb54d2af21c438631120f30ffa01e7db..1e66c123fd479d78954dff94ff4e555f446e4fb1 100644 (file)
@@ -170,16 +170,17 @@ 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;
        }
 
@@ -228,35 +229,25 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
        fprintf (map->oFile, "%s$%d$%d", sym->name, sym->level, sym->block);
       }
       
-      /* 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) {
-           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) {
-           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)
-       {
+      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 {
@@ -265,29 +256,70 @@ emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                      sym->name, sym->lineDef);
            }
            ival = newNode ('=', newAst_VALUE (symbolVal (sym)),
-                    decorateType (resolveSymbols (list2expr (sym->ival))));
+                           decorateType (resolveSymbols (list2expr (sym->ival))));
          }
          codeOutFile = statsg->oFile;
-         allocInfo = 0;
-
-         // set ival's lineno to where the symbol was defined
-         if (ival) ival->lineno=sym->lineDef;
-         eBBlockFromiCode (iCodeFromAst (ival));
-         allocInfo = 1;
-
-         /* 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);
+
+         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;
+      }
 
-         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) {
+           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 {
+         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);
+         }
+      }
     }
 }
 
@@ -535,7 +567,15 @@ printIvalType (symbol *sym, sym_link * type, initList * ilist, FILE * oFile)
          werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
        }
 
-       val = list2val (ilist);
+       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)
@@ -835,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:
@@ -849,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);
@@ -988,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;
@@ -1004,7 +1058,9 @@ 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) {
@@ -1047,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);
            }
        }
     }
@@ -1077,12 +1137,19 @@ emitMaps ()
   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--;
 }
 
@@ -1131,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...
        */
 
@@ -1203,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);
 }
 
 /*-----------------------------------------------------------------*/
@@ -1259,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 */
@@ -1297,16 +1365,20 @@ emitOverlay (FILE * afile)
                       sym->rname,
                       SPEC_ADDR (sym->etype));
            }
-         else
-           {
+         else {
+             int size = getSize(sym->type);
+
+             if (size==0) {
+                 werror(E_UNKNOWN_SIZE,sym->name);
+             }       
              if (options.debug)
-               fprintf (afile, "==.\n");
+                 fprintf (afile, "==.\n");
              
              /* allocate space */
              tfprintf (afile, "!labeldef\n", sym->rname);
              tfprintf (afile, "\t!ds\n", (unsigned int) getSize (sym->type) & 0xffff);
-           }
-
+         }
+         
        }
     }
 }
@@ -1442,6 +1514,12 @@ 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 && IFFUNC_HASBODY(mainf->type))
     {
@@ -1498,6 +1576,11 @@ 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);