* src/pic16/gen.c (pic16_aopGet): fixed handling of offsets in
[fw/sdcc] / src / pic16 / glue.c
index f7095b038e5d9b01aebdd25be15d9316a89a5496..7e1d1b762de80a2aaa61c0d7d5327a577230146d 100644 (file)
@@ -69,6 +69,8 @@ extern DEFSETFUNC (closeTmpFiles);
 extern DEFSETFUNC (rmTmpFiles);
 
 extern void pic16_AnalyzeBanking (void);
+extern void pic16_OptimizeJumps ();
+extern void pic16_OptimizeBanksel ();
 extern void copyFile (FILE * dest, FILE * src);
 extern void pic16_InlinepCode(void);
 extern void pic16_writeUsedRegs(FILE *);
@@ -174,12 +176,14 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                  
                        checkAddSym(&publics, sym);
                } else
+                        /* new version */
                        if(IS_STATIC(sym->etype)
-                               && !(sym->ival && !sym->level)
-                       ) {
+                               && !sym->ival) /* && !sym->level*/ {
                          regs *reg;
                           sectSym *ssym;
                           int found=0;
+
+//                            debugf("adding symbol %s\n", sym->name);
 #define SET_IMPLICIT   1
 
 #if SET_IMPLICIT
@@ -190,15 +194,17 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                                reg = pic16_allocDirReg( operandFromSymbol( sym ));
                                
                                if(reg) {
-#if 1
                                   for(ssym=setFirstItem(sectSyms); ssym; ssym=setNextItem(sectSyms)) {
                                    if(!strcmp(ssym->name, reg->name))found=1;
                                   }
-#endif
+
                                   if(!found)
                                     checkAddReg(&pic16_rel_udata, reg);
+#if 0
                                   else
-                                   checkAddSym(&publics, sym);
+                                    debugf("Did find %s in pic16_rel_udata already. Check!\n", reg->name);
+//                                 checkAddSym(&publics, sym);
+#endif
 
                                 }
                        }
@@ -213,28 +219,9 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                        continue;
                }
 
-#if 0
-               /* print extra debug info if required */
-               if (options.debug || sym->level == 0) {
-                       cdbWriteSymbol (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 */
-                       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);
-               }
-#endif
-
-
                /* 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)
 //                             fprintf (stderr,"; %s == 0x%04x\t\treqv= %p nRegs= %d\n",
 //                                     sym->name, SPEC_ADDR (sym->etype), sym->reqv, sym->regType);
 
@@ -342,7 +329,9 @@ pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
                /* 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)
+                     || IS_STATIC(sym->etype)) ) {
                  ast *ival = NULL;
 
 #if 0
@@ -565,6 +554,7 @@ void pic16_printGPointerType (const char *iname, const unsigned int itype,
     switch( itype ) {
       case FPOINTER:
       case CPOINTER:
+      case GPOINTER:
       case FUNCTION:
         {
           sprintf(buf, "UPPER(%s)", iname);
@@ -645,10 +635,10 @@ pic16_printIvalType (symbol *sym, sym_link * type, initList * ilist, char ptype,
 /* pic16_printIvalChar - generates initital value for character array */
 /*--------------------------------------------------------------------*/
 static int 
-pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, void *p)
+pic16_printIvalChar (symbol *sym, sym_link * type, initList * ilist, char *s, char ptype, void *p)
 {
   value *val;
-  unsigned int remain;
+  int remain, len, ilen;
 
   if(!p)
     return 0;
@@ -659,19 +649,46 @@ pic16_printIvalChar (sym_link * type, initList * ilist, char *s, char ptype, voi
 
   if(!s) {
     val = list2val (ilist);
+
     /* if the value is a character string  */
     if(IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
+      /* length of initializer string (might contain \0, so do not use strlen) */
+      ilen = DCL_ELEM(val->type);
+
       if(!DCL_ELEM (type))
-        DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
+        DCL_ELEM (type) = ilen;
+
+      /* len is 0 if declartion equals initializer,
+       * >0 if declaration greater than initializer
+       * <0 if declaration less than initializer
+       * Strategy: if >0 emit 0x00 for the rest of the length,
+       * if <0 then emit only the length of declaration elements
+       * and warn user
+       */
+      len = DCL_ELEM (type) - ilen;
+
+//      fprintf(stderr, "%s:%d ilen = %i len = %i DCL_ELEM(type) = %i SPEC_CVAL-len = %i\n", __FILE__, __LINE__,
+//        ilen, len, DCL_ELEM(type), strlen(SPEC_CVAL(val->etype).v_char));
+
+      if(len >= 0) {
+        /* emit initializer */
+        for(remain=0; remain<ilen; remain++)
+          pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
+
+         /* fill array with 0x00 */
+          while(len--) {
+            pic16_emitDB(0x00, ptype, p);
+          }
+      } else {
+        werror (W_EXCESS_INITIALIZERS, "array of chars", sym->name, sym->lineDef);
 
-      for(remain=0; remain<strlen(SPEC_CVAL(val->etype).v_char)+1; remain++)
-        pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
-      
-      if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
-        while(remain--) {
-          pic16_emitDB(0x00, ptype, p);
-        }
+        for(remain=0; remain<DCL_ELEM (type); remain++)
+          pic16_emitDB(SPEC_CVAL(val->etype).v_char[ remain ], ptype, p);
       }
+      
+
+//      if((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0) {
+//      }
       return 1;
     } else return 0;
   } else {
@@ -708,7 +725,7 @@ pic16_printIvalArray (symbol * sym, sym_link * type, initList * ilist,
       return;
     }
 
-    if(pic16_printIvalChar (type,
+    if(pic16_printIvalChar (sym, type,
                       (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
                       SPEC_CVAL (sym->etype).v_char, ptype, p))
       return;
@@ -1413,7 +1430,7 @@ pic16createInterruptVect (FILE * vFile)
                return;
        }
 #endif
-
+#if 0
        if((!pic16_options.omit_ivt) || (pic16_options.omit_ivt && pic16_options.leave_reset)) {
                fprintf (vFile, ";\t.area\t%s\n", CODE_NAME);
                fprintf(vFile, ".intvecs\tcode\t0x%06x\n", pic16_options.ivt_loc);
@@ -1424,6 +1441,7 @@ pic16createInterruptVect (FILE * vFile)
                        port->genIVT(vFile, interrupts, maxInterrupts);
                }
        }
+#endif
        
 }
 
@@ -1459,6 +1477,8 @@ pic16printPublics (FILE *afile)
        fprintf (afile, "%s", iComments2);
 
        for(sym = setFirstItem (publics); sym; sym = setNextItem (publics))
+         /* sanity check */
+         if(!IS_STATIC(sym->etype))
                fprintf(afile, "\tglobal %s\n", sym->rname);
 }
 
@@ -1544,27 +1564,6 @@ pic16emitOverlay (FILE * afile)
          if (IS_FUNC (sym->type))
            continue;
 
-#if 0
-         /* print extra debug info if required */
-         if (options.debug || sym->level == 0)
-           {
-
-             cdbSymbol (sym, cdbFile, FALSE, FALSE);
-
-             if (!sym->level)
-               {               /* global */
-                 if (IS_STATIC (sym->etype))
-                   fprintf (afile, "F%s_", moduleName);        /* scope is file */
-                 else
-                   fprintf (afile, "G_");      /* scope is global */
-               }
-             else
-               /* symbol is local */
-               fprintf (afile, "L%s_",
-                        (sym->localof ? sym->localof->name : "-null-"));
-             fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
-           }
-#endif
 
          /* if is has an absolute address then generate
             an equate for this no need to allocate space */
@@ -1594,15 +1593,18 @@ pic16emitOverlay (FILE * afile)
 
 void emitStatistics(FILE *asmFile)
 {
+  unsigned long isize, udsize;
   statistics.isize = pic16_countInstructions();
+  isize = (statistics.isize >= 0) ? statistics.isize : 0;
+  udsize = (statistics.udsize >= 0) ? statistics.udsize : 0;
        
   fprintf (asmFile, "\n\n; Statistics:\n");
-  fprintf (asmFile, "; code size:\t%ld (0x%lx) bytes\n;\t\t%ld (0x%lx) words\n",
-    statistics.isize, statistics.isize,
-    statistics.isize>>1, statistics.isize>>1);
-  fprintf (asmFile, "; udata size:\t%ld (0x%lx) bytes\n", 
-    statistics.udsize, statistics.udsize);
-  fprintf (asmFile, "; access size:\t%ld (0x%lx) bytes\n",
+  fprintf (asmFile, "; code size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n;           \t%5ld (0x%04lx) words\n",
+    isize, isize, (isize*100.0)/(128 << 10),
+    isize>>1, isize>>1);
+  fprintf (asmFile, "; udata size:\t%5ld (0x%04lx) bytes (%3.2f%%)\n",
+    udsize, udsize, (udsize*100.0) / ((pic16 ? pic16->RAMsize : 0x200) -256));
+  fprintf (asmFile, "; access size:\t%5ld (0x%04lx) bytes\n",
     statistics.intsize, statistics.intsize);
 
   fprintf (asmFile, "\n\n");
@@ -1730,9 +1732,21 @@ pic16glue ()
     /* Put all variables into a cblock */
     pic16_AnalyzeBanking();
 
+#if 0
     if(pic16_options.opt_flags & OF_LR_SUPPORT) {
       pic16_OptimizeLocalRegs();
     }
+#endif
+
+    /* remove redundant BANKSELs -- added by RN 2005-01-17 */
+    if(pic16_options.opt_banksel > 1) {
+      pic16_OptimizeBanksel();
+    }
+           
+    /* turn GOTOs into BRAs -- added by RN 2004-11-16 */
+    if(pic16_options.opt_flags & OF_OPTIMIZE_GOTO) {
+      pic16_OptimizeJumps();
+    }
 
     /* print the extern variables to this module */
     pic16_printExterns(asmFile);