fixed the pointer value caching problem
[fw/sdcc] / src / SDCCglue.c
index 9412e4ae700713846b98aa6f52867d2a4575330c..475920045cd3897cbd6e65ec7e3e3cc2ae11b26b 100644 (file)
@@ -23,6 +23,7 @@
 -------------------------------------------------------------------------*/
 
 #include "common.h"
+#include "asm.h"
 #include <time.h>
 
 symbol *interrupts[256];
@@ -81,10 +82,7 @@ void copyFile (FILE * dest, FILE * src)
            fputc (ch, dest);
 }
 
-/*-----------------------------------------------------------------*/
-/* aopLiteral - string from a literal value                        */
-/*-----------------------------------------------------------------*/
-char *aopLiteral (value *val, int offset)
+char *aopLiteralLong(value *val, int offset, int size)
 {
     char *rs;
     union {
@@ -98,22 +96,43 @@ char *aopLiteral (value *val, int offset)
         unsigned long v = floatFromVal(val);
 
         v >>= (offset * 8);
-        sprintf(buffer,"#0x%02x",((char) v) & 0xff);
+       switch (size) {
+       case 1:
+           tsprintf(buffer, "!immedbyte", (unsigned int)v & 0xff);
+           break;
+       case 2:
+           tsprintf(buffer, "!immedword", (unsigned int)v & 0xffff);
+           break;
+       default:
+           /* Hmm.  Too big for now. */
+           assert(0);
+       }
         ALLOC_ATOMIC(rs,strlen(buffer)+1);
         return strcpy (rs,buffer);
     }
 
+    /* PENDING: For now size must be 1 */
+    assert(size == 1);
+
     /* it is type float */
     fl.f = (float) floatFromVal(val);
-#ifdef _BIG_ENDIAN    
-    sprintf(buffer,"#0x%02x",fl.c[3-offset]);
+#ifdef _BIG_ENDIAN
+    tsprintf(buffer, "!immedbyte", fl.c[3-offset]);
 #else
-    sprintf(buffer,"#0x%02x",fl.c[offset]);
+    tsprintf(buffer, "!immedbyte", fl.c[offset]);
 #endif
     ALLOC_ATOMIC(rs,strlen(buffer)+1);
     return strcpy (rs,buffer);
 }
 
+/*-----------------------------------------------------------------*/
+/* aopLiteral - string from a literal value                        */
+/*-----------------------------------------------------------------*/
+char *aopLiteral (value *val, int offset)
+{
+    return aopLiteralLong(val, offset, 1);
+}
+
 /*-----------------------------------------------------------------*/
 /* emitRegularMap - emit code for maps with no special cases       */
 /*-----------------------------------------------------------------*/
@@ -121,8 +140,13 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
 {
     symbol *sym;
     
-    if (addPublics)
-       fprintf (map->oFile, "\t.area\t%s\n", map->sname);
+    if (addPublics) {
+       /* PENDING: special case here - should remove */
+       if (!strcmp(map->sname, DATA_NAME))
+           tfprintf(map->oFile, "\t!areadata\n", map->sname);
+       else
+           tfprintf(map->oFile, "\t!area\n", map->sname);
+    }
     
     /* print the area name */
     for (sym = setFirstItem (map->syms); sym;
@@ -183,8 +207,8 @@ static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
            /* allocate space */
            if ((options.debug || sym->level == 0) && !options.nodebug)
                fprintf(map->oFile,"==.\n");
-           fprintf (map->oFile, "%s:\n", sym->rname);
-           fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
+           tfprintf(map->oFile, "!labeldef\n", sym->rname);
+           tfprintf(map->oFile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff);
        }
        
        /* if it has a initial value then do it only if
@@ -286,29 +310,38 @@ void printChar (FILE * ofile, char *s, int plen)
     int i;
     int len = strlen (s);
     int pplen = 0;
-    
-    while (len && pplen < plen) {
+    char buf[100];
+    char *p = buf;
 
-       fprintf (ofile, "\t.ascii /");
+    while (len && pplen < plen) {
        i = 60;
        while (i && *s && pplen < plen) {
-           if (*s < ' ' || *s == '/') {               
-               fprintf (ofile, "/\n\t.byte 0x%02x\n\t.ascii /", *s++);
+           if (*s < ' ' || *s == '\"') {
+               *p = '\0';
+               if (p != buf) 
+                   tfprintf(ofile, "\t!ascii\n", buf);
+               tfprintf(ofile, "\t!db\n", *s);
+               p = buf;
            }
-           else 
-               fprintf (ofile, "%c", *s++);
+           else {
+               *p = *s;
+               p++;
+           }
+           s++;
            pplen++;
            i--;
        }
-       fprintf (ofile, "/\n");
+       if (p != buf) {
+           *p = '\0';
+           tfprintf(ofile, "\t!ascii\n", buf);
+       }
        
        if (len > 60)
            len -= 60;
        else
            len = 0;
     }
-    if (pplen < plen)
-       fprintf(ofile,"\t.byte\t0\n");
+    tfprintf(ofile, "\t!db\n", 0);
 }
 
 /*-----------------------------------------------------------------*/
@@ -326,31 +359,27 @@ void printIvalType (link * type, initList * ilist, FILE * oFile)
     switch (getSize (type)) {
     case 1:
        if (!val)
-           fprintf (oFile, "\t.byte 0\n");
+           tfprintf(oFile, "\t!db\n", 0);
        else
-           fprintf (oFile, "\t.byte %s\n",
+           tfprintf(oFile, "\t!dbs\n",
                     aopLiteral (val, 0));
        break;
 
     case 2:
-       if (!val)
-           fprintf (oFile, "\t.word 0\n");
-       else
-           fprintf (oFile, "\t.byte %s,%s\n",
-                    aopLiteral (val, 0), aopLiteral (val, 1));
+       tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2));
        break;
-
     case 4:
-       if (!val)
-           fprintf (oFile, "\t.word 0,0\n");
-       else
+       if (!val) {
+           tfprintf (oFile, "\t!dw\n", 0);
+           tfprintf (oFile, "\t!dw\n", 0);
+       }
+       else {
            fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
                     aopLiteral (val, 0), aopLiteral (val, 1),
                     aopLiteral (val, 2), aopLiteral (val, 3));
+       }
        break;
     }
-    
-    return;
 }
 
 /*-----------------------------------------------------------------*/
@@ -400,7 +429,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--)
-                   fprintf (oFile, "\t.byte 0\n");
+                   tfprintf (oFile, "\t!db\n", 0);
            
            return 1;
        }
@@ -474,23 +503,19 @@ void printIvalFuncPtr (link * type, initList * ilist, FILE * oFile)
     val = list2val (ilist);
     /* check the types   */
     if ((dLvl = checkType (val->type, type->next)) <= 0) {
-       
-       fprintf (oFile, "\t.word 0\n");
+       tfprintf(oFile, "\t!dw\n", 0);
        return;
     }
     
     /* now generate the name */
     if (!val->sym) {
        if (IS_LITERAL (val->etype))
-           fprintf (oFile, "\t.byte %s,%s\n",
-                    aopLiteral (val, 0), aopLiteral (val, 1));
+           tfprintf(oFile, "\t!dws\n", aopLiteralLong(val, 0, 2));
        else
-           fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
-                    val->name, val->name);
+           tfprintf(oFile, "\t!dws\n", val->name);
     }
     else 
-       fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
-                val->sym->rname, val->sym->rname);
+       tfprintf(oFile, "\t!dws\n", val->sym->rname);
     
     return;
 }
@@ -502,21 +527,49 @@ int printIvalCharPtr (symbol * sym, link * type, value * val, FILE * oFile)
 {
     int size = 0;
     
+    /* PENDING: this is _very_ mcs51 specific, including a magic
+       number... 
+       It's also endin specific.
+    */
     size = getSize (type);
-    
-    if (size == 1)
-       fprintf(oFile,
-            "\t.byte %s", val->name) ;
-    else
-       fprintf (oFile,
-                "\t.byte %s,(%s >> 8)",
-                val->name, val->name);
-   
-    if (size > 2)
-       fprintf (oFile, ",#0x02\n");
-    else
-       fprintf (oFile, "\n");
-    
+
+    if (val->name && strlen(val->name)) {
+       switch (size) {
+       case 1:
+           tfprintf(oFile,
+                   "\t!dbs\n", val->name) ;
+           break;
+       case 2:
+           tfprintf(oFile, "\t!dws\n", val->name);
+           break;
+           /* PENDING: probably just 3 */
+       default:
+           /* PENDING: 0x02 or 0x%02x, CDATA? */
+           fprintf (oFile,
+                    "\t.byte %s,(%s >> 8),#0x02\n",
+                    val->name, val->name);
+       }
+    }
+    else {
+       switch (size) {
+       case 1:
+           tfprintf(oFile, "\t!dbs\n", aopLiteral(val, 0));
+           break;
+       case 2:
+           tfprintf(oFile, "\t!dws\n", 
+                   aopLiteralLong(val, 0, 2));
+           break;
+       case 3:
+           /* PENDING: 0x02 or 0x%02x, CDATA? */
+           fprintf(oFile, "\t.byte %s,%s,0x02\n",
+                   aopLiteral (val, 0), aopLiteral (val, 1));
+           break;
+       default:
+           assert(0);
+       }
+    }
+
+
     if (val->sym && val->sym->isstrlit)
        addSet (&statsg->syms, val->sym);
     
@@ -556,12 +609,10 @@ void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
     if (IS_LITERAL (val->etype)) {
        switch (getSize (type)) {
        case 1:
-           fprintf (oFile, "\t.byte 0x%02x\n", ((char) floatFromVal (val)) & 0xff);
+           tfprintf(oFile, "\t!db\n", (unsigned int)floatFromVal(val) & 0xff);
            break;
        case 2:
-           fprintf (oFile, "\t.byte %s,%s\n",
-                    aopLiteral (val, 0), aopLiteral (val, 1));
-           
+           tfprintf (oFile, "\t!dws\n", aopLiteralLong(val, 0, 2));
            break;
        case 3:
            fprintf (oFile, "\t.byte %s,%s,0x%02x\n",
@@ -573,10 +624,10 @@ void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
     
     switch (getSize (type)) {
     case 1:
-       fprintf (oFile, "\t.byte %s\n", val->name);
+       tfprintf (oFile, "\t!dbs\n", val->name);
        break;
     case 2:
-       fprintf (oFile, "\t.byte %s,(%s >> 8)\n", val->name, val->name);
+       tfprintf (oFile, "\t!dws\n", val->name);
        break;
        
     case 3:
@@ -690,8 +741,8 @@ void emitStaticSeg (memmap * map)
                    printChar (code->oFile,
                               SPEC_CVAL (sym->etype).v_char,
                               strlen(SPEC_CVAL (sym->etype).v_char)+1);
-               else
-                   fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type)& 0xffff);
+               else 
+                   tfprintf(code->oFile, "\t!ds\n", (unsigned int)getSize (sym->type)& 0xffff);
            }
        }
     }
@@ -738,7 +789,7 @@ void createInterruptVect (FILE * vFile)
        return;
     }
     
-    fprintf (vFile, "\t.area\t%s\n", CODE_NAME);
+    tfprintf(vFile, "\t!areacode\n", CODE_NAME);
     fprintf (vFile, "__interrupt_vect:\n");
 
     
@@ -797,7 +848,7 @@ void printPublics (FILE * afile)
     
     for (sym = setFirstItem (publics); sym;
         sym = setNextItem (publics))
-       fprintf (afile, "\t.globl %s\n", sym->rname);
+       tfprintf(afile, "\t!global\n", sym->rname);
 }
 
 /*-----------------------------------------------------------------*/
@@ -808,7 +859,7 @@ static void emitOverlay(FILE *afile)
     set *ovrset;
     
     if (!elementsInSet(ovrSetSets))
-       fprintf(afile,"\t.area\t%s\n", port->mem.overlay_name);
+       tfprintf(afile,"\t!area\n", port->mem.overlay_name);
 
     /* for each of the sets in the overlay segment do */
     for (ovrset = setFirstItem(ovrSetSets); ovrset;
@@ -886,8 +937,8 @@ static void emitOverlay(FILE *afile)
                    fprintf(afile,"==.\n");
        
                /* allocate space */
-               fprintf (afile, "%s:\n", sym->rname);
-               fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
+               tfprintf(afile, "!labeldef\n", sym->rname);
+               tfprintf(afile, "\t!ds\n", (unsigned int)getSize (sym->type) & 0xffff);
            }
            
        }
@@ -942,8 +993,9 @@ void glue ()
     initialComments (asmFile);
     
     /* print module name */
-    fprintf (asmFile, "\t.module %s\n", moduleName);
-    
+    tfprintf(asmFile, "\t!module\n", moduleName);
+    tfprintf(asmFile, "\t!fileprelude\n");
+
     /* Let the port generate any global directives, etc. */
     if (port->genAssemblerPreamble)
     {
@@ -982,7 +1034,7 @@ void glue ()
     if (mainf && mainf->fbody) {
        fprintf (asmFile, "%s", iComments2);
        fprintf (asmFile, "; Stack segment in internal ram \n");
-       fprintf (asmFile, "%s", iComments2);    
+       fprintf (asmFile, "%s", iComments2);
        fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
                 "__start__stack:\n\t.ds\t1\n\n");
     }
@@ -1034,9 +1086,9 @@ void glue ()
      * the post_static_name area will immediately follow the static_name
      * area.
      */
-    fprintf (asmFile, "\t.area %s\n", port->mem.static_name); /* MOF */
-    fprintf (asmFile, "\t.area %s\n", port->mem.post_static_name);
-    fprintf (asmFile, "\t.area %s\n", port->mem.static_name);
+    tfprintf(asmFile, "\t!area\n", port->mem.static_name); /* MOF */
+    tfprintf(asmFile, "\t!area\n", port->mem.post_static_name);
+    tfprintf(asmFile, "\t!area\n", port->mem.static_name);
     
     if (mainf && mainf->fbody) {
        fprintf (asmFile,"__sdcc_gsinit_startup:\n");
@@ -1077,7 +1129,7 @@ void glue ()
          * This area is guaranteed to follow the static area
          * by the ugly shucking and jiving about 20 lines ago.
          */
-       fprintf(asmFile, "\t.area %s\n", port->mem.post_static_name);
+       tfprintf(asmFile, "\t!area\n", port->mem.post_static_name);
        fprintf (asmFile,"\tljmp\t__sdcc_program_startup\n");
     }
        
@@ -1085,7 +1137,7 @@ void glue ()
     fprintf (asmFile, "%s", iComments2);
     fprintf (asmFile, "; code\n");
     fprintf (asmFile, "%s", iComments2);
-    fprintf (asmFile, "\t.area %s\n", port->mem.code_name);
+    tfprintf(asmFile, "\t!areacode\n", CODE_NAME);
     if (mainf && mainf->fbody) {
        
        /* entry point @ start of CSEG */
@@ -1136,3 +1188,11 @@ FILE *tempfile(void)
     }
     return tmpfile();
 }
+
+char *gc_strdup(const char *s)
+{
+    char *ret;
+    ALLOC_ATOMIC(ret, strlen(s)+1);
+    strcpy(ret, s);
+    return ret;
+}